diff --git a/.github/ISSUE_TEMPLATE/bug-report-or-usage-issue.md b/.github/ISSUE_TEMPLATE/bug-report-or-usage-issue.md index 3a70ed71e..e012393d9 100644 --- a/.github/ISSUE_TEMPLATE/bug-report-or-usage-issue.md +++ b/.github/ISSUE_TEMPLATE/bug-report-or-usage-issue.md @@ -22,10 +22,6 @@ Steps to reproduce the behavior: 3. Scroll down to '....' 4. See error -**Geoserver log** - -Attach geoserver log located in **data_dir\logs\geoserver.log** - **Expected behavior** A clear and concise description of what you expected to happen. diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 93267404a..60c0e0335 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,13 +1,21 @@ name: CI -on: [ push, pull_request, workflow_dispatch ] +on: + push: + branches: [main] + pull_request: + workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: - build: + build_linux: runs-on: ubuntu-latest services: postgres: - image: postgis/postgis:16-3.4 + image: imresamu/postgis:17-3.5 env: # must specify password for PG Docker container image, see: https://registry.hub.docker.com/_/postgres?tab=description&page=1&name=10 POSTGRES_USER: noisemodelling @@ -18,6 +26,12 @@ jobs: # needed because the postgres container does not provide a healthcheck options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: + - name: Cache + uses: actions/cache@v4 + with: + path: | + $HOME/.m2/ + key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} # Checkout the source code of the project - name: Checkout uses: actions/checkout@v4 @@ -33,57 +47,68 @@ jobs: gpg-private-key: ${{ secrets.GPG_SECRET_KEY }} gpg-passphrase: MAVEN_GPG_PASSPHRASE - name: Building - run: mvn test install javadoc:test-javadoc javadoc:jar -B - - name: Setup Gradle - uses: gradle/actions/setup-gradle@v4 - - name: Build and test WPS with Gradle - run: ./gradlew build --info --stacktrace - working-directory: ./wps_scripts - - name: Maven Deploy - env: - MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} - MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} - MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - if: ${{ (env.MAVEN_USERNAME != null) && (github.ref == 'refs/heads/main') }} - run: mvn clean deploy -B - - name: Clean gradle cache - run: rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - name: Restore gradle.properties + run: mvn test install javadoc:jar package -B env: - MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} - MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} - MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - if: ${{ (env.MAVEN_USERNAME != null) && (github.ref == 'refs/heads/main') }} - shell: bash + POSTGRES_HOST: localhost + POSTGRES_PORT: 5432 + POSTGRES_DB: noisemodelling_db + POSTGRES_USER: noisemodelling + POSTGRES_PASSWORD: noisemodelling + - name: Unzip production artifacts + run: | + # 1. Unzip into a temporary directory + unzip -q noisemodelling-scripts/target/*.zip -d tmp_extract + + # 2. Create target directory + mkdir NoiseModelling + + # 3. Move contents from the subfolder to the target + # The asterisk-slash-asterisk moves everything inside the first subfolder + mv tmp_extract/*/* NoiseModelling/ + + # 4. Cleanup + rm -rf tmp_extract + - name: Integration test, use ScriptRunner with H2GIS run: | - mkdir -p ~/.gradle/ - echo "GRADLE_USER_HOME=${HOME}/.gradle" >> $GITHUB_ENV - echo "ossrhUsername=${MAVEN_USERNAME}" >> ~/.gradle/gradle.properties - echo "ossrhPassword=${MAVEN_PASSWORD}" >> ~/.gradle/gradle.properties - echo "signing.gnupg.passphrase=${MAVEN_GPG_PASSPHRASE}" >> ~/.gradle/gradle.properties - - name: Deploy WPS + bin/ScriptRunner -w /tmp/h2gis_ws -s get_started_tutorial_complex.groovy + working-directory: NoiseModelling + - name: Integration test, use ScriptRunner with PostGIS + run: | + bin/ScriptRunner -w /tmp/postgis_ws -s get_started_tutorial_complex.groovy --host localhost --user noisemodelling --password noisemodelling --port 5432 --database noisemodelling_db + working-directory: NoiseModelling + - name: Maven Deploy snapshot env: MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} if: ${{ (env.MAVEN_USERNAME != null) && (github.ref == 'refs/heads/main') }} - run: ./gradlew publish -d - working-directory: ./wps_scripts - - name: Cache - uses: actions/cache@v4 - with: - path: | - $HOME/.m2/ - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ - key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} - - #Production of the archive - - name: Unzip production artifacts - run: ./gradlew assembleDist && unzip build/distributions/*.zip -d NoiseModelling_without_gui - working-directory: ./wps_scripts - - name: Archive production artifacts + run: mvn clean -DskipTests deploy -B + - name: Generate Sanitized Artifact Name + id: sanitize + run: | + # Determine the raw value (Ref name if not default branch, otherwise SHA) + if [ "${{ github.ref_name }}" != "${{ github.event.repository.default_branch }}" ]; then + RAW_VAL="${{ github.ref_name }}" + else + RAW_VAL="${{ github.sha }}" + fi + + # Use sed to perform replacements: + # 1. / and \ become _ + # 2. : is removed + # 3. * becomes x + CLEAN_VAL=$(echo "$RAW_VAL" | sed 's/[\/\\]/_/g; s/://g; s/\*/x/g') + + # Set it as an environment variable for the next step + echo "ARTIFACT_NAME=NoiseModelling-$CLEAN_VAL" >> $GITHUB_ENV + - name: Upload distribution file uses: actions/upload-artifact@v4 with: - name: NoiseModelling_without_gui - path: wps_scripts/NoiseModelling_without_gui/ + name: ${{ env.ARTIFACT_NAME }} + path: NoiseModelling/ + build_windows: + uses: ./.github/workflows/build_windows.yml + with: + git_ref: ${{ github.ref }} + + diff --git a/.github/workflows/CI_Release.yml b/.github/workflows/CI_Release.yml index b53ef3c47..52382135a 100644 --- a/.github/workflows/CI_Release.yml +++ b/.github/workflows/CI_Release.yml @@ -3,16 +3,22 @@ name: CI release on: workflow_dispatch: inputs: - nextVersion: - required: false - description: "Next version (optional)" + releaseVersion: + description: 'Release version (e.g., 2.0.0)' + required: true + developmentVersion: + description: 'Next development version (e.g., 2.1.0-SNAPSHOT)' + required: true jobs: - build: + prepare_release: + outputs: + tag_name: v${{ github.event.inputs.release_version }} name: Release and next iteration runs-on: ubuntu-latest permissions: contents: write + pull-requests: write steps: # Checkout the source code of the project - name: Checkout @@ -28,71 +34,110 @@ jobs: server-password: MAVEN_PASSWORD gpg-private-key: ${{ secrets.GPG_SECRET_KEY }} gpg-passphrase: MAVEN_GPG_PASSPHRASE - + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.11' # Configure git user in order to sign release with OrbisGIS user. - name: Configure Git User run: | git config user.email "contact@noise-planet.org" git config user.name Noise-Planet - - # Test build - - name: Build test - run: mvn -ntp clean validate package test javadoc:test-javadoc javadoc:jar - - - name: Install xmlstarlet (if needed) - run: sudo apt-get update && sudo apt-get install -y libxml-xpath-perl - - name: Update version in build.gradle + - name: Configure Git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + - name: Create Release Branch run: | - bash update_gradle_version.sh - git commit -am "Update groovy wps version" - working-directory: wps_scripts - # Create the release : - # - move from Snapshot version to Release - # - commit and tag release - # - move to next Snapshot - # - upload release to maven repo - - name: Release + git checkout -b release/v${{ github.event.inputs.releaseVersion }} + - name: Prepare and perform Release + # -DpushChanges=false ensures Maven doesn't try to push to main automatically run: | - VERSION=${{ github.event.inputs.nextVersion }} - mvn \ - -ntp \ - --batch-mode \ - -Dmaven.test.skip=true \ - release:prepare release:perform \ - -Dusername=$GITHUB_ACTOR -Dpassword=$GITHUB_TOKEN ${VERSION:+"-DdevelopmentVersion="$VERSION"-SNAPSHOT"} + mvn -B release:prepare \ + -DreleaseVersion=${{ github.event.inputs.releaseVersion }} \ + -DdevelopmentVersion=${{ github.event.inputs.developmentVersion }} \ + -DpushChanges=false \ + -P-use-snapshots \ + -Darguments="-P-use-snapshots" + + # 2. Temporarily switch to the tag to deploy the Release version + git checkout v${{ github.event.inputs.releaseVersion }} + + # 3. Deploy the Release version (the code currently checked out) + # We use -DskipTests because prepare already ran them. + mvn clean javadoc:jar deploy -P-use-snapshots -DskipTests -B + + # 4. Switch back to the release branch to continue the workflow + git checkout release/v${{ github.event.inputs.releaseVersion }} env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + - name: Push Branch and Tag + run: | + # Push the commits (Release and Next Snapshot) to the temporary branch + git push origin release/v${{ github.event.inputs.releaseVersion }} + # Push the tag (Maven creates this locally) + git push origin v${{ github.event.inputs.releaseVersion }} + - name: Create Pull Request to Main + run: | + gh pr create \ + --title "Release v${{ github.event.inputs.releaseVersion }}" \ + --body "This PR updates the version to ${{ github.event.inputs.releaseVersion }} and prepares the next development cycle ${{ github.event.inputs.developmentVersion }}." \ + --base main \ + --head release/v${{ github.event.inputs.releaseVersion }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Export the last git tag into env. - - name: Export env values - run: echo "GIT_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_ENV - # Make the Github release from the last created tag. Write in its body the content of the changelog file. - - name: Make Github release - uses: ncipollo/release-action@v1 + build_windows_exe: + needs: prepare_release + uses: ./.github/workflows/build_windows.yml + with: + git_ref: v${{ github.event.inputs.releaseVersion }} + use_snapshots: false + run_unit_tests: false + build_macos_dmg: + needs: prepare_release + uses: ./.github/workflows/build_macos.yml + with: + git_ref: v${{ github.event.inputs.releaseVersion }} + use_snapshots: false + upload_release: + needs: [prepare_release, build_windows_exe, build_macos_dmg] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 with: - tag: ${{ env.GIT_TAG }} - release: ${{ env.GIT_TAG }} - bodyFile: "README.md" - draft: false - prerelease: false - artifacts: "wps_scripts/build/distributions/scriptrunner.zip" - - # If the version change is a major or minor, create a branch from the previous tag for future revisions. - - name: Branch fork + fetch-depth: 0 # Necessary to see tags and branches + - name: Build Zip Artifact + # Since we are already on the release-ready state locally, + # we can just package the webserver run: | - GIT_TAG="${GIT_TAG:1}" - CUR_TAG="$( mvn help:evaluate -Dexpression=project.version | sed -n -e '/^\[.*\]/ !{ /^[0-9]/ { p; q } }' | cut -d- -f1)" - SPLIT0=(${GIT_TAG//./ }) - SPLIT1=(${CUR_TAG//./ }) - if [ "${SPLIT0[0]}" = "${SPLIT1[0]}" ] && [ "${SPLIT0[1]}" = "${SPLIT1[1]}" ]; then - echo "Revision change" - else - echo "Minor or Major change" - BRANCH="${SPLIT0[0]}.${SPLIT0[1]}.X" - git checkout -b "$BRANCH" "v${GIT_TAG}" - mvn versions:set -DnewVersion="${SPLIT0[0]}.${SPLIT0[1]}.$((${SPLIT0[2]}+1))-SNAPSHOT" - git commit -a -m "Set next version." - git push -u origin "$BRANCH" - fi + # Checkout the release tag to be sure we build the exact release code + git checkout v${{ github.event.inputs.releaseVersion }} + mvn clean package -DskipTests -P-use-snapshots + - name: Download windows Artifact + uses: actions/download-artifact@v4 + with: + name: windows-installer + path: release-artifacts + - name: Download macOS Artifact + uses: actions/download-artifact@v4 + with: + name: ${{ needs.build_macos_dmg.outputs.installer_name }} + path: release-artifacts + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ github.event.inputs.releaseVersion }} + name: Release ${{ github.event.inputs.releaseVersion }} + files: | + noisemodelling-scripts/target/NoiseModelling_${{ github.event.inputs.releaseVersion }}.zip + release-artifacts/${{ needs.build_windows_exe.outputs.installer_name }} + release-artifacts/${{ needs.build_macos_dmg.outputs.installer_name }} + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.github/workflows/build_macos.yml b/.github/workflows/build_macos.yml new file mode 100644 index 000000000..4196f67bc --- /dev/null +++ b/.github/workflows/build_macos.yml @@ -0,0 +1,78 @@ +name: Reusable macOS Build + +on: + workflow_dispatch: + inputs: + git_ref: + description: 'The git ref to checkout' + required: true + type: string + use_snapshots: + description: 'Enable the Maven profile use-snapshots (set false to disable - used for releases)' + required: false + type: boolean + default: true + workflow_call: + inputs: + git_ref: + description: 'The git ref to checkout' + required: true + type: string + use_snapshots: + description: 'Enable the Maven profile use-snapshots (set false to disable - used for releases)' + required: false + type: boolean + default: true + outputs: + # Tier 3: Map Workflow Output -> Job Output + installer_name: + description: "The filename of the generated DMG file" + value: ${{ jobs.build.outputs.dmg_name }} # MUST reference jobs, not steps + +jobs: + build: + runs-on: macos-latest + outputs: + dmg_name: ${{ steps.get_name.outputs.FILENAME }} + steps: + # Checkout the source code of the project + - name: Checkout Code + uses: actions/checkout@v4 + with: + ref: ${{ inputs.git_ref }} + - name: Cache + uses: actions/cache@v4 + with: + path: | + $HOME/.m2/ + key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} + # Setup the jdk + - name: Setup java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '21' + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.11' + - name: Building + env: + MAVEN_PROFILE: ${{ inputs.use_snapshots && '-Puse-snapshots' || '' }} + run: | + mvn package -B -DskipTests $MAVEN_PROFILE + - name: Extract DMG Filename + id: get_name + run: | + # Find the dmg file and get just the filename + FULL_PATH=$(ls noisemodelling-scripts/target/*.dmg | head -n 1) + FILENAME=$(basename "$FULL_PATH") + echo "FILENAME=$FILENAME" >> $GITHUB_OUTPUT + echo "Detected DMG: $FILENAME" + + - name: Upload Installer Artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.get_name.outputs.FILENAME }} + path: noisemodelling-scripts/target/*.dmg + if-no-files-found: error diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml new file mode 100644 index 000000000..981c3d27a --- /dev/null +++ b/.github/workflows/build_windows.yml @@ -0,0 +1,154 @@ +name: Reusable Windows Build + +on: + workflow_dispatch: + inputs: + git_ref: + description: 'The git ref to checkout' + required: true + type: string + use_snapshots: + description: 'Enable the Maven profile use-snapshots (set false to disable - used for releases)' + required: false + type: boolean + default: true + run_unit_tests: + description: 'Run Maven unit tests' + required: false + type: boolean + default: true + workflow_call: + inputs: + git_ref: + description: 'The git ref to checkout' + required: true + type: string + use_snapshots: + description: 'Enable the Maven profile use-snapshots (set false to disable - used for releases)' + required: false + type: boolean + default: true + run_unit_tests: + description: 'Run Maven unit tests' + required: false + type: boolean + default: true + outputs: + # Tier 3: Map Workflow Output -> Job Output + installer_name: + description: "The filename of the generated EXE" + value: ${{ jobs.build.outputs.exe_name }} # MUST reference jobs, not steps + +jobs: + build: + runs-on: windows-latest + outputs: + exe_name: ${{ steps.version_step.outputs.EXE_NAME }} + steps: + # Checkout the source code of the project + - name: Checkout Code + uses: actions/checkout@v4 + with: + ref: ${{ inputs.git_ref }} + - name: Cache + uses: actions/cache@v4 + with: + path: | + $HOME/.m2/ + key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} + # Setup the jdk using version 11 of Adoptium Temurin + - name: Setup java 11 using Adoptium Temurin + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '11' + server-id: central + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + gpg-private-key: ${{ secrets.GPG_SECRET_KEY }} + gpg-passphrase: MAVEN_GPG_PASSPHRASE + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.11' + - name: Building + shell: pwsh + env: + MAVEN_PROFILE: ${{ inputs.use_snapshots && '-Puse-snapshots' || '' }} + # If run_unit_tests is false, add the skip flag + SKIP_TESTS: ${{ inputs.run_unit_tests == false && '-DskipTests' || '' }} + run: | + # Note: 'install' automatically runs tests unless -DskipTests is provided + mvn install javadoc:test-javadoc javadoc:jar package -B $env:MAVEN_PROFILE $env:SKIP_TESTS + - name: Extract packaged zip with windows + run: | + unzip -o noisemodelling-scripts/target/*.zip -d NoiseModelling + - name: Find extracted folder (PowerShell) + id: folder + shell: pwsh + run: | + $subdir = Get-ChildItem -Path NoiseModelling -Directory | Select-Object -First 1 + echo "folder=$($subdir.FullName)" >> $env:GITHUB_OUTPUT + - name: Integration test, use ScriptRunner to import a shapefile into the database + run: | + bin\ScriptRunner -w ./ -s scripts/Import_and_Export/Import_File.groovy --pathFile resources/ground_type.shp + working-directory: ${{ steps.folder.outputs.folder }} + - name: Fetch versions for NSIS executable metadata + id: version_step + run: | + $mavenVersion = (Select-String -Path "pom.xml" -Pattern "([^<]+)" | Select-Object -First 1).Matches.Groups[1].Value + echo "MAVEN_VERSION=$mavenVersion" >> $env:GITHUB_ENV + echo "EXE_NAME=NoiseModelling-$mavenVersion-Setup.exe" >> $env:GITHUB_OUTPUT + # Derive 4-part numeric version for Windows EXE metadata (e.g. 5.0.2-SNAPSHOT -> 5.0.2.0) + $numericVersion = $mavenVersion -replace '-.*', '' + $parts = $numericVersion.Split('.') + while ($parts.Count -lt 4) { $parts += '0' } + $winVersion = ($parts[0..3]) -join '.' + echo "APP_VERSION=$winVersion" >> $env:GITHUB_ENV + echo "APP_VERSION_TXT=$mavenVersion" >> $env:GITHUB_ENV + - name: Extract NoiseModelling packaged ZIP to NSIS installer folder + run: | + $zip = Get-ChildItem noisemodelling-scripts\target\*.zip | Select-Object -First 1 + Expand-Archive -Path $zip.FullName -DestinationPath extracted_raw -Force + $innerDir = (Get-ChildItem extracted_raw | Where-Object PSIsContainer | Select-Object -First 1).FullName + New-Item -ItemType Directory -Force -Path installer\app + Copy-Item -Recurse "$innerDir\*" installer\app + - name: Debug unzipped contents + run: | + dir installer + dir installer\app\bin + - name: Download Windows JRE (Adoptium) + run: | + $jreUrl = "https://api.adoptium.net/v3/binary/latest/21/ga/windows/x64/jre/hotspot/normal/eclipse" + Invoke-WebRequest -Uri $jreUrl -OutFile jre.zip + Expand-Archive -Path jre.zip -DestinationPath jre_raw -Force + $innerDir = (Get-ChildItem jre_raw | Where-Object PSIsContainer | Select-Object -First 1).FullName + Move-Item "$innerDir" installer\jre + + - name: Install Launch4j + run: choco install launch4j --yes --no-progress + + - name: Build EXE config + run: | + (Get-Content installer\launch4j-config.xml) ` + -replace 'APP_VERSION_PLACEHOLDER', $env:APP_VERSION ` + -replace 'APP_VERSION_TXT_PLACEHOLDER', $env:APP_VERSION_TXT ` + | Set-Content installer\launch4j-config-final.xml + + + - name: Create EXE + run: | + java -jar "C:\Program Files (x86)\Launch4j\launch4j.jar" installer\launch4j-config-final.xml + + - name: Install NSIS + run: choco install nsis --yes --no-progress + + - name: Build installer + run: | + & "C:\Program Files (x86)\NSIS\makensis.exe" /DAPP_VERSION=$env:APP_VERSION /DMAVEN_VERSION=$env:MAVEN_VERSION installer\installer.nsi + + - name: Upload Installer Artifact + uses: actions/upload-artifact@v4 + with: + name: windows-installer + path: installer\NoiseModelling-${{ env.MAVEN_VERSION }}-Setup.exe diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 000000000..30c1a5830 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,123 @@ +name: Build and Publish Docker Image + +on: + push: + branches: ["main"] + tags: ["v*.*.*"] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + REGISTRY: ghcr.io + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + os: ubuntu-latest + - arch: arm64 + os: ubuntu-24.04-arm + + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # THIS STEP FIXES THE UPPERCASE ERROR + - name: Downcase Repo Name + run: | + echo "IMAGE_NAME=${GITHUB_REPOSITORY,,}" >> ${GITHUB_ENV} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push by digest + id: build + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/${{ matrix.arch }} + # Uses the lowercased IMAGE_NAME from GITHUB_ENV + outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ matrix.arch }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + needs: build + permissions: + packages: write + steps: + - name: Downcase Repo Name + run: | + echo "IMAGE_NAME=${GITHUB_REPOSITORY,,}" >> ${GITHUB_ENV} + + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=sha,format=long + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) + diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 89cb5c58b..05b476f65 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -35,35 +35,25 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Set up JDK 11 + - name: Set up JDK 21 uses: actions/setup-java@v1 with: - java-version: 11 - - name: Generate Javadoc - run: mvn javadoc:aggregate -Ddoclint=none - - name: Build NoiseModelling - run: mvn install -DskipTests - - name: Generate Cnossos report - working-directory: noisemodelling-tutorial-01 - run: mvn exec:java -Dmain.class=org.noise_planet.nmtutorial01.GenerateReferenceDeviation -Dexec.args="../Docs" - - shell: bash - run: | - mkdir -p Docs/build/html/javadoc - mv target/reports/apidocs/* Docs/build/html/javadoc/ - - uses: actions/setup-python@v5 - - name: Install dependencies - run: | - pip install -r Docs/requirements.txt - - name: Sphinx build + java-version: 21 + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.11' + - name: Generate documentation of NoiseModelling in package phase run: | - sphinx-build -M html Docs/ Docs/build + mvn install javadoc:aggregate -Ddoclint=none -DskipTests + mkdir -p noisemodelling-scripts/target/sphinx/html/javadoc + mv target/reports/apidocs/* noisemodelling-scripts/target/sphinx/html/javadoc/ - name: Setup Pages uses: actions/configure-pages@v4 - - name: Upload artifact + - name: Upload static site pages with javadoc uses: actions/upload-pages-artifact@v3 with: - # Upload static site pages - path: 'Docs/build/html' + path: 'noisemodelling-scripts/target/sphinx/html' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 0f788d236..a3b9e65f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ target/ *.iml .idea/ -nbactions.xml *.versionsBackup .attach* Docs/build @@ -10,4 +9,4 @@ Docs/venv profile_*.csv venv/ .DS_Store - +*.trace.db diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..011455796 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,62 @@ +# Contributing to NoiseModelling + +First off, thanks for taking the time to contribute! + +The following is a set of guidelines for contributing to NoiseModelling. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. + +## Code of Conduct + +This project and everyone participating in it is governed by the [NoiseModelling Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. + +## How Can I Contribute? + +### Reporting Bugs + +This section guides you through submitting a bug report for NoiseModelling. Following these guidelines helps maintainers and the community understand your report, reproduce the behavior, and find related reports. + +* **Check the [issues](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/issues)** to see if the problem has already been reported. +* **Open a new issue**. Explain the problem and include additional details to help maintainers reproduce the problem: + * Use a clear and descriptive title for the issue to identify the problem. + * Describe the exact steps to reproduce the problem in as many details as possible. + * Describe the behavior you observed after following the steps and point out what exactly is the problem with that behavior. + * Explain which behavior you expected to see instead and why. + * Include screenshots and animated GIFs which show you following the reproduction steps. + +### Suggesting Enhancements + +This section guides you through submitting an enhancement suggestion for NoiseModelling, including completely new features and minor improvements to existing functionality. + +* **Check the [issues](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/issues) and [discussions](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/discussions)** to see if the enhancement has already been suggested. +* **Open a new issue** or start a **new discussion**. Describe the enhancement and provide as much detail as possible. + +### Your First Code Contribution + +Unsure where to begin contributing to NoiseModelling? You can start by looking through these `good first issue` and `help wanted` issues: + +* [Good first issues](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/labels/good%20first%20issue) - issues which should only require a few lines of code, and a test or two. +* [Help wanted issues](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/labels/help%20wanted) - issues which should be a bit more involved than `good first issue`. + +### Pull Requests + +* **Fork the repository** and clone it locally. +* Create a branch for your edits. +* Make sure your code lints and tests pass. +* **Submit a pull request** to the `main` branch. +* If you're adding a new feature, add tests for it. + +## Styleguides + +### Java Styleguide + +* Please follow the existing coding style in the project. +* Ensure that your code is well-documented with Javadoc where appropriate. + +### Documentation Styleguide + +* Documentation is written in reStructuredText (.rst) and Markdown (.md). +* Correct spelling and grammar are appreciated. + +## Additional Resources + +* [Get Started Dev Documentation](https://noisemodelling.readthedocs.io/en/latest/Get_Started_Dev.html) +* [NoiseModelling Website](http://noise-planet.org/noisemodelling.html) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..c784f0245 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,49 @@ +# Use a Maven image that already includes JDK 21 +FROM maven:3.9.9-eclipse-temurin-21 AS builder + +# Set working directory +WORKDIR /build + +# Install bsdtar (found in libarchive-tools on Debian/Ubuntu-based images) +RUN apt-get update && apt-get install -y libarchive-tools && rm -rf /var/lib/apt/lists/* + +# Copy your project files +COPY . /build/ + +# Run your commands +RUN mvn package && \ + mkdir noisemodelling && \ + bsdtar -xvf noisemodelling-scripts/target/*.zip --strip-components=1 -C noisemodelling + +FROM eclipse-temurin:latest + +LABEL org.opencontainers.image.authors="Nicolas Fortin, UMRAE Univ Eiffel, contact@noise-planet.org" + +LABEL org.opencontainers.image.description="NoiseModelling server mode distribution. See https://github.com/Universite-Gustave-Eiffel/NoiseModelling/blob/main/README.md for more information" + +ENV NOISEMODELLING_GID=8978 +ENV NOISEMODELLING_UID=8978 +ENV APP_DIR=/srv/noisemodelling/ +ENV APP_FILE=$APP_DIR/bin/WebServer + +RUN <`_. It is the best way to safely host NoiseModelling on a public server. Be aware that a registered user may be able to run a privilege escalation attack through the usage of scripts/SQL, so you should add only trusted users. .. _Docker : https://www.docker.com/ -.. _v4.0.1 image : https://hub.docker.com/r/xenotech/noisemodelling -.. _Xenotech81 : https://github.com/Xenotech81 -.. _v3.4.4 image : https://github.com/tomasanda/docker-noisemodelling -.. _tomasanda : https://github.com/tomasanda \ No newline at end of file + +On the root of this repository you can find an example docker compose. + +You can edit the following environment variables: + +- PROXY_BASE_URL : If you have a domain name you can use the your domain name instead of localhost +- ROOT_URL : By default the service is accessible from the path /noisemodelling but you can change it by using the environment variable ROOT_URL (empty to use the base url) +- UNSECURE_MODE : By default the registration is enabled (with TOTP). If you use this docker image locally, you can disable the registration by setting the environment variable UNSECURE_MODE in the docker-compose.yml file to true. + +Dependencies +============ + +Install Docker or Podman on your system + +Running +======= + +Download the file `docker-compose.yml `_ and run this command in the same folder: + +:: + + docker compose up -d + +or + +:: + + podman compose up -d + +Follow the instructions of the logs in order to register the administrator account (if not in unsecure mode). + +:: + + docker compose logs noisemodelling + +or + +:: + + podman compose logs noisemodelling diff --git a/Docs/Cnossos_Report.rst b/Docs/Cnossos_Report.rst index adcfc07ca..986624ec6 100644 --- a/Docs/Cnossos_Report.rst +++ b/Docs/Cnossos_Report.rst @@ -3,28 +3,24 @@ Conformity to ISO 17534-1:2015 .. DO NOT UPDATE THIS FILE!! .. This document has been automatically generated with noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/GenerateReferenceDeviation.java +Clarifications on the ISO Standard +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Clarifications on the ISO Standard and Identified Issues -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -It is important to note that the ISO standard provides recommendations rather than regulatory obligations. While it serves as a reference framework, its application is not mandatory from a legal standpoint. - -During our analysis, we identified several issues within the standard that hinder a complete and reliable comparison. Notably, we observed inconsistencies between 2D and 3D visualizations, preventing us from achieving a coherent assessment. Additionally, discrepancies exist between the geometric description of the scene and the corresponding acoustic response, raising concerns about the accuracy and reliability of the standard’s methodology. - -Furthermore, with respect to favorable rays, our findings indicate a different implementation of CNOSSOS compared to the approach suggested by the standard. This divergence may have implications for the interpretation and reproducibility of results, necessitating further clarification and alignment. - +It is important to note that the ISO standard provides recommendations +rather than regulatory obligations. While it serves as a reference framework, +its application is not mandatory from a legal standpoint. Conformity table ^^^^^^^^^^^^^^^^ | Conform * Do not the deviate more than ±0,1 dB -* Percentage of conformity : 86% (24/28) +* Percentage of conformity : 100% (28/28) | NLD Conform * Do not the deviate more than ±0,1 dB neglecting lateral diffraction -* Percentage of conformity : 90% (25/28) +* Percentage of conformity : 100% (28/28) .. list-table:: :widths: 10 20 20 25 30 @@ -87,7 +83,7 @@ Conformity table * - TC11 - ☑ - ☑ - - 0.02 dB @ 125 Hz + - 0.01 dB @ 125 Hz - `TC11`_ * - TC12 - ☑ @@ -107,7 +103,7 @@ Conformity table * - TC15 - ☑ - ☑ - - 0.06 dB @ 250 Hz + - 0.03 dB @ 125 Hz - `TC15`_ * - TC16 - ☑ @@ -125,9 +121,9 @@ Conformity table - 0.02 dB @ 500 Hz - `TC18`_ * - TC19 - - □ - ☑ - - 0.77 dB @ 250 Hz + - ☑ + - 0.02 dB @ 63 Hz - `TC19`_ * - TC20 - ☑ @@ -150,9 +146,9 @@ Conformity table - 0.02 dB @ 63 Hz - `TC23`_ * - TC24 - - □ - - □ - - 1.04 dB @ 2000 Hz + - ☑ + - ☑ + - 0.01 dB @ 250 Hz - `TC24`_ * - TC25 - ☑ @@ -160,14 +156,14 @@ Conformity table - 0.01 dB @ 2000 Hz - `TC25`_ * - TC26 - - □ - - □ - - 0.47 dB @ 63 Hz + - ☑ + - ☑ + - 0.02 dB @ 4000 Hz - `TC26`_ * - TC27 - - □ - - □ - - 1.76 dB @ 500 Hz + - ☑ + - ☑ + - 0.02 dB @ 1000 Hz - `TC27`_ * - TC28 - ☑ @@ -526,11 +522,11 @@ Right Lateral - Maximum Difference - Frequency * - Lʜ - - 0.05 dB - - 250 + - 0.03 dB + - 500 * - Lꜰ - - 0.05 dB - - 250 + - 0.03 dB + - 500 Left Lateral @@ -544,11 +540,11 @@ Left Lateral - Maximum Difference - Frequency * - Lʜ - - 0.05 dB - - 250 + - 0.03 dB + - 500 * - Lꜰ - - 0.05 dB - - 250 + - 0.03 dB + - 500 TC12 ^^^^ @@ -754,11 +750,11 @@ Right Lateral - Maximum Difference - Frequency * - Lʜ - - 0.24 dB - - 500 + - 0.03 dB + - 63 * - Lꜰ - - 0.40 dB - - 250 + - 0.03 dB + - 63 Left Lateral @@ -946,10 +942,10 @@ Left Lateral - Maximum Difference - Frequency * - Lʜ - - 6.46 dB - - 8000 + - 0.04 dB + - 500 * - Lꜰ - - 6.46 dB + - 0.01 dB - 8000 TC20 @@ -1144,8 +1140,8 @@ Reflection - 0.02 dB - 63 * - Lꜰ - - 3.53 dB - - 4000 + - 0.02 dB + - 63 TC25 ^^^^ @@ -1276,8 +1272,26 @@ Vertical Plane - 0.02 dB - 2000 * - Lꜰ - - 0.18 dB + - 0.03 dB + - 1000 + + +Reflection + +================ + +.. list-table:: + :widths: 25 25 25 + + * - Parameters + - Maximum Difference + - Frequency + * - Lʜ + - 0.03 dB - 125 + * - Lꜰ + - 0.08 dB + - 4000 TC28 ^^^^ @@ -1330,8 +1344,8 @@ Left Lateral - Maximum Difference - Frequency * - Lʜ - - 1.11 dB - - 1000 + - 0.08 dB + - 2000 * - Lꜰ - 0.01 dB - 1000 diff --git a/Docs/Community.rst b/Docs/Community.rst index b963c004a..aaf2b4c7d 100644 --- a/Docs/Community.rst +++ b/Docs/Community.rst @@ -51,12 +51,13 @@ Academic labs 🧪 Private company 🏭 ------------------- -* `Archimethod SA`_ (🇨🇭) +* `UrbanMetrix`_ (previously `Archimethod SA`_) (🇨🇭) * `OrbiWise`_ (🇨🇭) * `Neovya`_ (🇫🇷) * `Quiet Places Ltd`_ (🇬🇧) * `MobiLysis`_ (🇨🇭) +.. _UrbanMetrix: https://urbanmetrix.com/ .. _Archimethod SA: https://archi-method.ch/ .. _OrbiWise: https://orbiwise.com/ .. _Neovya: https://www.neovya.com/ @@ -81,11 +82,11 @@ Other ------------------ * `Direction générale de la prévention des risques (DGPR)`_ - (🇫🇷) -* `Centre National d’Incendie et de Secours`_ - CNIS (🇱🇺) +* `Corps grand-ducal d’incendie et de secours`_ - CGDIS (G.D. Luxembourg 🇱🇺) * `Ministerio para la Transición Ecológica y el Reto Demográfico`_ (🇪🇸) .. _Direction générale de la prévention des risques (DGPR): https://www.ecologie.gouv.fr/direction-generale-prevention-risques-dgpr -.. _Centre National d’Incendie et de Secours: https://112.public.lu/fr/organisation/cnis0.html +.. _Corps grand-ducal d’incendie et de secours: https://112.public.lu/fr.html .. _Ministerio para la Transición Ecológica y el Reto Demográfico: https://www.miteco.gob.es diff --git a/Docs/Functions.rst b/Docs/Functions.rst new file mode 100644 index 000000000..1eb535e59 --- /dev/null +++ b/Docs/Functions.rst @@ -0,0 +1,148 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +List of functions +^^^^^^^^^^^^^^^^^ + +Below is a list of all the functions that can be run in NoiseModelling. +These functions, written as ``.groovy`` scripts, are available in the ``/scripts/`` folder. + +Acoustic Tools +~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + functions/Acoustic_Tools/Add_Laeq_Leq_columns + functions/Acoustic_Tools/Create_Isolines + functions/Acoustic_Tools/Create_Isosurface + functions/Acoustic_Tools/DynamicIndicators + +Data Assimilation +~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + functions/Data_Assimilation/All_Possible_Configuration + functions/Data_Assimilation/Create_Assimilated_Maps + functions/Data_Assimilation/Data_Simulation + functions/Data_Assimilation/Extract_Best_Configuration + functions/Data_Assimilation/Merged_Sensors_Receivers + functions/Data_Assimilation/NMs_4_BestConfigs + functions/Data_Assimilation/Prepare_Sensors + +Database Manager +~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + functions/Database_Manager/Add_Primary_Key + functions/Database_Manager/Clean_Database + functions/Database_Manager/Display_Database + functions/Database_Manager/Drop_a_Table + functions/Database_Manager/Table_Visualization_Data + functions/Database_Manager/Table_Visualization_Map + +Deprecated +~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + functions/Deprecated/Noise_level_from_traffic + +Dynamic +~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + functions/Dynamic/Flow_2_Noisy_Vehicles + functions/Dynamic/Ind_Vehicles_2_Noisy_Vehicles + functions/Dynamic/Noise_From_Attenuation_Matrix + functions/Dynamic/Point_Source_From_Network + functions/Dynamic/Split_Sources_Period + +Experimental +~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + functions/Experimental/Noise_Map_Difference + functions/Experimental/Road_Emission_From_AADF + functions/Experimental/Road_Emission_From_TMJA + +Experimental Matsim +~~~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + functions/Experimental_Matsim/Agent_Exposure + functions/Experimental_Matsim/Import_Activities + functions/Experimental_Matsim/Plot_Exposition_Distribution + functions/Experimental_Matsim/Receivers_From_Activities_Closest + functions/Experimental_Matsim/Receivers_From_Activities_Random + functions/Experimental_Matsim/Traffic_From_Events + +Geometric Tools +~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + functions/Geometric_Tools/Change_SRID + functions/Geometric_Tools/Clean_Buildings_Table + functions/Geometric_Tools/Enrich_DEM + functions/Geometric_Tools/Enrich_DEM_with_lines + functions/Geometric_Tools/Enrich_DEM_with_rail + functions/Geometric_Tools/Enrich_DEM_with_road + functions/Geometric_Tools/Enrich_Landcover_with_rail + functions/Geometric_Tools/Point_Source_0dB_From_Network + functions/Geometric_Tools/Screen_to_building + functions/Geometric_Tools/Set_Height + functions/Geometric_Tools/Simplify_Geometries + +Import and Export +~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + functions/Import_and_Export/Export_Table + functions/Import_and_Export/Import_Asc_File + functions/Import_and_Export/Import_Asc_Folder + functions/Import_and_Export/Import_File + functions/Import_and_Export/Import_Folder + functions/Import_and_Export/Import_OSM + functions/Import_and_Export/Import_OSM_Pedestrian + functions/Import_and_Export/Import_Symuvia + functions/Import_and_Export/Linked_Table + +NoiseModelling +~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + functions/NoiseModelling/Atmospheric_Template + functions/NoiseModelling/Noise_level_from_source + functions/NoiseModelling/PlotDirectivity + functions/NoiseModelling/Railway_Emission_from_Traffic + functions/NoiseModelling/Road_Emission_from_Traffic + +Receivers +~~~~~~~~~ + +.. toctree:: + :maxdepth: 1 + + functions/Receivers/Building_Grid + functions/Receivers/Building_Grid3D + functions/Receivers/Delaunay_Grid + functions/Receivers/Random_Grid + functions/Receivers/Regular_Grid + diff --git a/Docs/Get_Started_Dev.rst b/Docs/Get_Started_Dev.rst index ca7f02282..a3e641221 100644 --- a/Docs/Get_Started_Dev.rst +++ b/Docs/Get_Started_Dev.rst @@ -5,12 +5,13 @@ Get Started #. Go to the official NoiseModelling repository: https://github.com/Universite-Gustave-Eiffel/NoiseModelling -#. There are 4 main librairies: +#. There are 5 main libraries: * ``noisemodelling-emission`` : to determine the noise emission * ``noisemodelling-jdbc`` : to connect NoiseModelling to a database * ``noisemodelling-pathfinder`` : to determine the noise path * ``noisemodelling-propagation`` : to calculate the noise propagation + * ``noisemodelling-scripts`` : Host the web server, the groovy scripts and the final packaging instructions #. Enjoy & feel free to contact us! diff --git a/Docs/Get_Started_GUI.rst b/Docs/Get_Started_GUI.rst deleted file mode 100644 index e82647d71..000000000 --- a/Docs/Get_Started_GUI.rst +++ /dev/null @@ -1,193 +0,0 @@ -Get Started - GUI -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Below we present a simple application case, allowing you to discover NoiseModelling through its Graphical User Interface . - -Step 1: Download NoiseModelling -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Download the latest realease of NoiseModelling on `Github`_. - -* Windows: you can directly download and execute the ``NoiseModelling_5.x.x_install.exe`` installer file *(or you can also follow Linux / Mac instructions below)* -* Linux or Mac: download the ``NoiseModelling_5.x.x.zip`` file and unzip it into a chosen directory - -.. warning:: - The chosen directory can be anywhere, but be sure that you have write access. If you are using the computer of your company, the Program Files folder is probably not a good idea. - -.. warning:: - For **Linux** and **Mac** users, please make sure your Java environment is well setted. For more information, please read the page :doc:`Requirements`. **Windows** users who are using the ``.exe`` file are not concerned since the Java Runtime Environment is **already embeded**. - -.. note:: - Only from version 3.3, NoiseModelling releases include the user interface described in this tutorial. - -.. _Github : https://github.com/Ifsttar/NoiseModelling/releases - - - -Step 2: Start NoiseModelling GUI -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -As seen in the page ":doc:`Architecture`", NoiseModelling can be used through a Graphic User Interface (GUI), thanks to Geoserver and WPS Builder bricks. - -In this tutorial, we will use the default and already configured H2GIS database. - -Those tools (Geoserver, WPS Builder and H2GIS) are already included in the archive. So you don't have to install them before. - -To launch NoiseModelling with GUI, please execute : - -* Windows: ``NoiseModelling.exe`` or ``NoiseModelling_xxx\bin\startup_windows.bat`` -* Linux or Mac: ``NoiseModelling_xxx/bin/startup_linux_mac.sh`` *(check authorize file execution in property of this file before)* - -and wait until ``INFO:oejs.Server:main:Started`` is written in your command prompt. - - -.. warning:: - Depending on your computer configuration, the NoiseModelling launch can take some time. Be patient. - -NoiseModelling with GUI is now started. - -.. tip:: - NoiseModelling will be open as long as the command window is open. If you close it, NoiseModelling will automatically be closed and you will not be able to continue with the tutorial. - - -.. _GeoServer : http://geoserver.org/ -.. _H2GIS : http://www.h2gis.org/ - -Step 3: Open NoiseModelling GUI -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The NoiseModelling GUI is built thanks to the :doc:`WPS_Builder` brick. To open it, just go to http://localhost:9580 using your preferred web browser. - -.. figure:: images/tutorial/Tutorial1_nm_open.png - :align: center - :width: 80% - -.. warning:: - On former versions of NoiseModelling, the url was: http://localhost:8080/geoserver/web/ - -You are now ready to discover the power of NoiseModelling! - -Step 4: Load input files -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To compute your first noise map, you will need to load input geographic files into the NoiseModelling database. - -In this tutorial, we have 5 layers, zoomed in the city center of `Lorient`_ (France): Buildings, Roads, Ground type, Topography (DEM) and Receivers. - -.. _Lorient : https://www.openstreetmap.org/relation/30305 - -In the ``noisemodelling/data_dir/data/wpsdata/`` folder, you will find the 5 files (4 shapefiles and 1 geojson) corresponding to these layers. - -You can import these layers in your database using the ``Import File`` or ``Import Folder`` blocks. - -- Drag ``Import File`` block into the Builder window -- Select ``Path of the input File`` box and write ``data_dir/data/wpsdata/buildings.shp`` in the field ``PathFile`` *(on the right-side column)* -- Then click on ``Run Process`` after selecting one of the sub-boxes of your process - -.. figure:: images/tutorial/Tutorial1_Image1bis.gif - :align: center - -Repeat this operation for the 4 other files: - -- ``data_dir/data/wpsdata/ground_type.shp`` -- ``data_dir/data/wpsdata/receivers.shp`` -- ``data_dir/data/wpsdata/ROADS2.shp`` -- ``data_dir/data/wpsdata/dem.geojson`` - -Files are uploaded to database when the Console window displays ``The table x has been uploaded to database``. - - -.. note:: - - If you have the message ``Error opening database``, please refer to the note in Step 1. - - The process is supposed to be quick (<5 sec.). In case of out of time, try to restart NoiseModelling (see Step 2). - - Orange blocks are mandatory - - Beige blocks are optional - - If all input blocks are optional, you must modify at least one of these blocks to be able to run the process - - Blocks get solid border when they are ready to run - - Read the :doc:`WPS_Builder` page for more information - -Once done, you can check if the tables have been well imported in the database. To do so, drag/drop and execute the ``Display_Database`` WPS script (in the "Database_Manager" part). You should see on the right panel the tables list (and their columns if you checked the the option in the ``Display columns of the tables`` block). - -.. figure:: images/tutorial/Tutorial1_display_db.png - :align: center - :width: 100% - - -Step 5: Run Calculation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To run Calculation you have to drag the block ``Noise_level_from_traffic`` into WPS Builder window. - -Then, select the orange blocks and indicate the name of the corresponding table in your database: - -- Building table name : ``BUILDINGS`` -- Sources table name : ``ROADS2`` This table contain geometry of roads with traffic for day, evening and night -- Receivers table name : ``RECEIVERS`` Location where to evaluate noise level -- DEM table name : ``DEM`` Digital elevation model -- Ground absorption table : ``GROUND_TYPE`` Nature of the ground -- Diffraction on horizontal edges : Check it (Sound propagation go over buildings) -- Maximum source-receiver distance: Set ``2000`` meters (do not look for sound sources further than 2km) -- Order of reflexion: Set ``0`` to disable it (faster but less accurate) - -The beige blocks correspond to optional parameters (e.g ``DEM table name``, ``Ground absorption table name``, ``Diffraction on vertical edges``, ...). - -When ready, you can press ``Run Process``. - -.. figure:: images/tutorial/Tutorial1_Image2bis.png - :align: center - -As a result, the table ``RECEIVERS_LEVEL`` will be created in your database. This table correspond to the noise levels, based on receiver points, the column PERIOD correspond to the 4 different period of the day (D E N and DEN). - - -Step 6: Export (& see) the results -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can now export the output tables *(one by one)* in your favorite export format using ``Export_Table`` block, giving the path of the file you want to create. - -.. warning:: - Dont' forget to add the file extension (*e.g* ``c:/home/receivers_level.geojson`` or ``c:/home/receivers_level.shp``) (Read more info about file extensions here: :doc:`Tutorials_FAQ`) - -.. figure:: images/tutorial/Tutorial1_Image3.PNG - :align: center - -For example, you can choose to export the tables in ``.shp`` format. This format can be read with most of GIS tools such as the free and open-source `QGIS`_ and `SAGA`_ softwares. - -.. _QGIS : https://www.qgis.org/fr/site/ -.. _SAGA : http://www.saga-gis.org/en/index.html - -.. note:: - For those who are new to GIS and want to get started with QGIS, we advise you to follow `this tutorial`_ as a start. - -.. _this tutorial : https://docs.qgis.org/3.22/en/docs/training_manual/basic_map/index.html - -To obtain the following image, filter use the styling vector options in your GIS and assign a color gradient to ``LAEQ`` column of your exported ``RECEIVERS_LEVEL`` table. - -.. figure:: images/tutorial/Tutorial1_Image4.PNG - :align: center - -To display the result for a period you have to filter the rendering by the field PERIOD in QGIS. - -.. figure:: images/tutorial/Tutorial1_FilterMenu.png - :align: center - - Popup menu - -.. figure:: images/tutorial/Tutorial1_FilterWindow.png - :align: center - - Filter window - -.. tip:: - Now that you have made your first noise map (congratulations!), you can try again, adding / changing optional parameters to see the differeneces. - - -Step 7: Know the possibilities -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Now that you have finished this introduction tutorial, take the time to read the description of each of the WPS blocks present in your NoiseModelling version. - -By clicking on each of the inputs or outputs, you will find a lot of information. - -.. figure:: images/tutorial/Tutorial1_ImageLast.gif - :align: center - diff --git a/Docs/Get_Started_Script.rst b/Docs/Get_Started_Script.rst deleted file mode 100644 index 05ab28129..000000000 --- a/Docs/Get_Started_Script.rst +++ /dev/null @@ -1,73 +0,0 @@ -Pilot NoiseModelling with scripts -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -In this tutorial, we describe the different ways to pilot NoiseModelling thanks to scripts. To do so, we will use a dedicated packaging of NoiseModelling, called ``NoiseModelling_5.0.0_without_gui``, in which the GUI has been removed (no more Geoserver and :doc:`WPS_Builder`). - -#. Go to the NoiseModelling latest `release page`_ -#. Download and unzip the `NoiseModelling_5.0.0_without_gui`_ file - -.. _release page : https://github.com/Ifsttar/NoiseModelling/releases/latest -.. _NoiseModelling_5.0.0_without_gui : https://github.com/Ifsttar/NoiseModelling/releases/download/v5.0.0/NoiseModelling_5.0.0_without_gui.zip - -From that point, NoiseModelling can be executed in 3 different manners: - -#. with simple command lines -#. with Bash script -#. with Groovy script - -To illustrate, users are invited to reproduce the tutorial ":doc:`Get_Started_GUI`" in command lines. - -.. note:: - This tutorial is mainly dedicated to advanced users. - -.. warning:: - The URL is here adapted to Linux or Mac users. Windows user may adapt the address by replacing ``/`` by ``\`` and the drive name. - -Requirements -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. warning:: - For all users (**Linux** , **Mac** and **Windows**), please make sure your Java environment is well setted. For more information, please read the page :doc:`Requirements`. - - -1. Simple command line -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Using the terminal of your operating system (Java 11 must be in the system path) - -Below is an example of a bash instruction, executing the ``Noise_level_from_traffic.groovy`` WPS Script (located in the directory ``/noisemodelling/wps/``). This block has 5 arguments corresponding to the input table names (for buildings, roads, receivers, dem and ground type). - -.. literalinclude:: scripts/nm_terminal.bash - :language: bash - :linenos: - - -``./bin/wps_scripts`` instruction allows to launch the ``wps_scripts.sh`` or ``wps_scripts.bat`` *(depending on if you are on Linux / Mac or Windows)* file, which is located in the ``bin/`` directory. - - -.. warning :: - Adapt ``/home/user/`` address with your own situation - - -2. Bash script -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Below is an example of a sequence of simple .groovy scripts, using bash instructions and launching the steps described in the ":doc:`Get_Started_GUI`". - -.. literalinclude:: scripts/get_started_tutorial_simple.bash - :language: bash - :linenos: - - -3. Groovy script -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Below is an example of a complex .groovy script, launching the differents steps described in the ":doc:`Get_Started_GUI`". - -.. literalinclude:: scripts/get_started_tutorial_complex.groovy - :language: java - :linenos: - -You can find this script online `here`_ - -.. _here : https://github.com/Ifsttar/NoiseModelling/blob/master/wps_scripts/src/main/groovy/get_started_tutorial.groovy diff --git a/Docs/Input_acoustics.rst b/Docs/Input_acoustics.rst index 09e3ad9a0..bb15eed1b 100644 --- a/Docs/Input_acoustics.rst +++ b/Docs/Input_acoustics.rst @@ -10,7 +10,7 @@ Below we list the most important ones, indicating, where necessary, the default -The following parameters may be found in the scripts dealing with noise emission or propagation (*e.g* ``Noise_level_from_traffic``, ``Noise_level_from_source```, ...) +The following parameters may be found in the scripts dealing with noise emission or propagation (*e.g* :doc:`functions/NoiseModelling/Noise_level_from_source`, ...) Probability of occurrences @@ -94,6 +94,15 @@ Maximum source-reflexion distance .. figure:: images/Input_tables/acoustics_parameters_confMaxReflDist.png :align: center +Ignore reflections close to the receiver wall +---------------------------------------------- + +* Parameter name: ``confMinWallReflDist`` +* Description: Optional maximum receiver-to-wall distance (meters) below which reflection cut profiles are ignored. When a receiver is located very close to a reflective wall, the reflected path may be physically unreliable or negligible. Setting this parameter filters out such reflection paths. Use ``0`` to keep all reflections (filter disabled). +* Type: Double +* Default value: ``0`` (disabled) +* Recommended value: Set the distance you wish; classically below ``2`` m. This parameter is typically used when assessing noise impact on people inside buildings, in order to avoid the last-reflection effect (approximately +3 dB). + Wall absorption coefficient -------------------------------- diff --git a/Docs/Input_directivity.rst b/Docs/Input_directivity.rst index 14a1e992b..f67fd94d1 100644 --- a/Docs/Input_directivity.rst +++ b/Docs/Input_directivity.rst @@ -11,7 +11,7 @@ The other tables are accessible via the left menu in the ``Input tables`` sectio :align: center .. note:: - If you want to see how to use this table, have a look to the tutorial ":doc:`Noise_Map_From_Point_Source`" , in the section ``Step 5 (bonus): Change the directivity`` + If you want to see how to use this table, have a look to the tutorial ":doc:`Tutorial_Noise_Map_From_Point_Source`" , in the section ``Step 5 (bonus): Change the directivity`` Table definition --------------------- diff --git a/Docs/Input_railways.rst b/Docs/Input_railways.rst index acc9261bf..2c47fd46d 100644 --- a/Docs/Input_railways.rst +++ b/Docs/Input_railways.rst @@ -36,20 +36,20 @@ Table definition * Description: Maximum speed on the section *(in km/h)* * Type: Double * ``TRANSFER`` - * Description: Track transfer function identifier - * ``1`` = Mono-bloc sleeper on soft rail pad - * ``2`` = Mono-bloc sleeper on medium rail pad - * ``3`` = Mono-bloc sleeper on stiff rail pad - * ``4`` = Bi-bloc sleeper on soft rail pad - * ``5`` = Bi-bloc sleeper on medium rail pad - * ``6`` = Bi-bloc sleeper on stiff rail pad - * ``7`` = Wooden sleeper (Traverse en bois) - * Type: Integer + * Description: Track transfer function identifier, listed in the `RailwayEmissionCnossos.json`_ file + * ``SNCF1`` = Mono-bloc sleeper on soft rail pad + * ``SNCF2`` = Mono-bloc sleeper on medium rail pad + * ``SNCF3`` = Mono-bloc sleeper on stiff rail pad + * ``SNCF4`` = Bi-bloc sleeper on soft rail pad + * ``SNCF5`` = Bi-bloc sleeper on medium rail pad + * ``SNCF6`` = Bi-bloc sleeper on stiff rail pad + * ``SNCF7`` = Wooden sleeper (Traverse en bois) + * Type: Varchar * ``ROUGHNESS`` - * Description: Rail roughness identifier - * ``1`` = Classic lines - * ``2`` = TGV (for France) lines - * Type: Integer + * Description: Rail roughness identifier, listed in the `RailwayEmissionCnossos.json`_ file + * ``SNCF1`` = Classic lines + * ``SNCF2`` = TGV (for France) lines + * Type: Varchar * ``IMPACT`` * Description: Impact noise coefficient identifier * ``0`` = No impact @@ -98,7 +98,7 @@ Table definition * Description: A section identifier, refering to ``RAIL_SECTIONS`` table * Type: Integer * ``TRAINTYPE`` * - * Description: Type of vehicle, listed in the `Rail_Train_SNCF_2021.json`_ file *(mainly for french SNCF)* + * Description: Type of vehicle, listed in the `RailwayTrainsets.json`_ file *(mainly for french SNCF)* * Type: Varchar * ``TRAINSPD`` * * Description: Maximum train speed *(in km/h)* @@ -114,5 +114,6 @@ Table definition * Type: Integer -.. _Rail_Train_SNCF_2021.json : https://github.com/Universite-Gustave-Eiffel/NoiseModelling/blob/4.X/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/Rail_Train_SNCF_2021.json +.. _RailwayEmissionCnossos.json : https://github.com/Universite-Gustave-Eiffel/NoiseModelling/tree/main/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayEmissionCnossos.json +.. _RailwayTrainsets.json : https://github.com/Universite-Gustave-Eiffel/NoiseModelling/tree/main/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayTrainsets.json diff --git a/Docs/Input_roads.rst b/Docs/Input_roads.rst index bda6ca60b..5f0cd2d4f 100644 --- a/Docs/Input_roads.rst +++ b/Docs/Input_roads.rst @@ -15,7 +15,7 @@ Table SOURCES_GEOM definition .. warning:: * In the list below, the columns noted with ``*`` are mandatory - * This description is only valid for ``Noise_level_from_traffic`` and ``Road_Emission_from_Traffic`` WPS scripts. For the other WPS scripts, it is necessary to refer to the description of their input data + * This description is only valid for :doc:`functions/NoiseModelling/Noise_level_from_source` block. For the other blocks, it is necessary to refer to the description of their input data .. note:: diff --git a/Docs/NoiseModellingOnPostGIS.rst b/Docs/NoiseModellingOnPostGIS.rst index 7da8bb2e5..0d7bbe753 100644 --- a/Docs/NoiseModellingOnPostGIS.rst +++ b/Docs/NoiseModellingOnPostGIS.rst @@ -4,52 +4,79 @@ Use NoiseModelling with a PostGIS database Introduction ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NoiseModelling is distributed with `GeoServer`_. This application has been preconfigured to use `H2GIS`_ as the default database. +NoiseModelling is designed to use `H2GIS`_ as the default database. H2GIS does not need to be configured or installed on the system and is therefore perfectly suitable as a default database. -However, you may want to connect NoiseModelling to a `PostgreSQL`_/`PostGIS`_ database (this option may be interesting especially if you are using huge datasets (*e.g* on large area)). +However, you may want to connect NoiseModelling to a `PostgreSQL`_/`PostGIS`_ database (this option may be interesting especially if you want to use `QGIS`_ while using NoiseModelling). -That is why NoiseModelling has been written with the idea of maintaining the H2GIS/PostGIS compatibility. +.. note:: Using PostGIS may result in slower performance than H2GIS due to network overhead, as data is transferred over a connection rather than written directly to local storage. + +NoiseModelling core functions has been written with the idea of maintaining the H2GIS/PostGIS compatibility. + +.. warning:: NoiseModelling Groovy scripts may use incompatible syntax with PostGIS. We are currently working on checking the compatibility with the PostGIS database. This tutorial will not cover the steps for installing and configuring a PostGIS database. -.. _Geoserver: http://geoserver.org/ -.. _H2GIS : http://h2gis.org/ +.. _QGIS : https://qgis.org +.. _H2GIS : https://h2gis.org/ .. _PostgreSQL: https://www.postgresql.org/ .. _PostGIS: https://postgis.net/ +Using ScriptRunner with PostGIS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Connect with Java -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You can run Groovy scripts using a PostGIS connection instead of the default H2GIS embedded database by using the `ScriptRunner` program. + +This is particularly useful for large-scale simulations where a dedicated database server is preferred. + +Command Line Example +-------------------- + +To import a Shapefile into a PostGIS database, you can use the following command: + +.. code-block:: bash + + ./bin/ScriptRunner \ + -w /path/to/working/dir \ + -s src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_File.groovy \ + -d noisemodelling_db \ + -u noisemodelling \ + -p noisemodelling \ + --host localhost \ + --port 5432 \ + --pathFile /path/to/your/buildings.shp \ + --tableName BUILDINGS + +Parameters Description +---------------------- -First you have to add some libraries. We will use PostgreSQL/PostGIS wrapper available in the H2GIS library: +* **-w, --working-dir**: Path where the application logs and temporary files will be stored. +* **-s, --script**: Path to the Groovy script you want to execute. +* **-d, --database-name**: Name of the PostGIS database. +* **-u, --username**: Database username. +* **-p, --password**: Database password. If not provided and a host is specified, it will try to fetch it from the `.pgpass` file. +* **--host**: PostGIS database host name. Specifying this parameter tells NoiseModelling to connect to PostGIS instead of using H2GIS. +* **--port**: PostGIS database port (default: 5432). +Additional Script Parameters +---------------------------- -.. literalinclude:: scripts/postgis_deps.xml - :language: xml - :linenos: +Any parameter specific to the Groovy script (defined in its `inputs` map) can be passed as a double-dash argument. In the example above: -The new dependency here is ``postgis-jts-osgi``. It contains some code to convert PostGIS geometries objects into/from `JTS`_ objects. +* **--pathFile**: The path to the file to import (required by `Import_File.groovy`). +* **--tableName**: The name of the table to create in the database. -.. _JTS: https://github.com/locationtech/jts +Using .pgpass for Credentials +----------------------------- -In your code you have to import the PostGIS wrapper class and some utility class: +If you don't want to provide the password in the command line, you can use a `.pgpass` file as specified in the `PostgreSQL documentation `_. -.. literalinclude:: scripts/postgis_nm.java - :language: java - :lines: 6-7,19-26 - :linenos: +The file should contain lines in the following format: -Then use it to connect to you local or remote PostGIS database and obtain a valid JDBC connection object: +.. code-block:: text -.. literalinclude:: scripts/postgis_nm.java - :language: java - :lines: 36-45 - :linenos: + hostname:port:database:username:password -Finally you can use the NoiseModelling functions as usual: +NoiseModelling will automatically fetch the password if the host is specified and the password parameter is omitted. -.. literalinclude:: scripts/postgis_nm.java - :language: java - :linenos: \ No newline at end of file diff --git a/Docs/NoiseModelling_db.rst b/Docs/NoiseModelling_db.rst index 4fdcd5f59..5ac5306a1 100644 --- a/Docs/NoiseModelling_db.rst +++ b/Docs/NoiseModelling_db.rst @@ -22,7 +22,7 @@ To visualize and manage NoiseModelling data (*e.g* roads, buildings or landcover 1. Use WPS blocks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once NoiseModelling UI is launched (open `http://localhost:9580/ `_ in your web browser), you can manage your data thanks to the ``Database_Manager`` WPS blocks folder *(on the left side)*. In particular, you can do these actions: +Once NoiseModelling UI is launched (open `http://localhost:8000/ `_ in your web browser), you can manage your data thanks to the ``Database_Manager`` WPS blocks folder *(on the left side)*. In particular, you can do these actions: - ``Add_Primary_Key``: allows to add a primary key on a column of a specific layer (table) - ``Clean_Database``: remove all the layers (tables) from NoiseModelling *(can be useful when starting a new project)* @@ -61,17 +61,17 @@ To do so, follow these steps: In the connexion panel, you have to specify the following informations: - ``Driver Class``: the driver that allows to connect to a specific database. Here we want to connect to a H2 db, so let the default value ``org.h2.Driver`` -- ``JDBC URL``: the JDBC address of the NoiseModelling database. By default, this database is placed in here ``/.../data_dir/h2gisdb.mv.db``. So, fill this text area with ``jdbc:h2:/.../data_dir/h2gisdb.mv.db``. -- ``User name``: the db user name. By default, keep the empty value -- ``Password``: the db password. By default, keep the empty value +- ``JDBC URL``: the JDBC address of the NoiseModelling database. By default, this database is placed in here ``~/.noisemodelling/user_001.mv.db``. So, fill this text area with ``jdbc:h2:/~/.noisemodelling/user_001.mv.db``. +- ``User name``: the db user name. By default, sa +- ``Password``: the db password. By default, sa .. warning:: If you want to open the database while NoiseModelling is running, you have to add ``;AUTO_SERVER=TRUE`` after the ``JDBC URL``. If not, you will only be able to open the database once NoiseModelling is closed. -Below is an example, with a database located on the computer here: ``/home/nm_user/NoiseModelling/NoiseModelling_4.0/data_dir/h2gisdb.mv.db``. We want to open the db while NoiseModelling is running. +Below is an example, with a database located on the computer here: ``/home/nm_user/.noisemodelling/user_001.mv.db``. We want to open the db while NoiseModelling is running. -- ``JDBC URL``: ``jdbc:h2:/home/nm_user/NoiseModelling/NoiseModelling_4.0/data_dir/h2gisdb.mv.db;AUTO_SERVER=TRUE`` +- ``JDBC URL``: ``jdbc:h2:/home/nm_user/.noisemodelling/user_001;AUTO_SERVER=TRUE`` - ``User name``: *empty* - ``Password``: *empty* @@ -90,8 +90,6 @@ In the new interface, you discover a full database manager, with the list of tab :align: center :width: 100% - -.. _Geoserver: http://geoserver.org/ .. _H2 : https://www.h2database.com .. _H2GIS : http://h2gis.org/ .. _PostgreSQL: https://www.postgresql.org/ @@ -117,9 +115,10 @@ Connect DBeaver to your database #. Run DBeaver #. Add a new connection #. If you use a H2GIS type databse, please select ``H2GIS embedded`` *(use the search engine to filter)* -#. Point the database path by clicking on ``Browse ...``. By default the database is placed in the ``NoiseModelling/data_dir`` directory and is named ``h2gisdb.mv.db``. +#. Point the database path by clicking on ``Browse ...``. By default the database is placed in the ``~/.noisemodelling`` directory and is named ``user_001.mv.db``. #. In the ``Path`` text area, remove ``.mv.db`` at the end of the address -#. If you want to open the database while NoiseModelling is running, add ``;AUTO_SERVER=TRUE`` at the end of the path (you should have something like this ``/home/nm_user/NoiseModelling/NoiseModelling_4.0/data_dir/h2gisdb;AUTO_SERVER=TRUE``) +#. The default user is ``sa`` and password ``sa`` +#. If you want to open the database while NoiseModelling is running, add ``;AUTO_SERVER=TRUE`` at the end of the path (you should have something like this ``/home/nm_user/.noisemodelling/user_001;AUTO_SERVER=TRUE``) #. Click on ``Terminate`` to open your dabatase! .. figure:: images/NoiseModelling_db/dbeaver_new_connection.png @@ -128,7 +127,7 @@ Connect DBeaver to your database .. warning :: - If you are using a version of DBeaver prior to 22.0.4, the interface may ask you to ``Save`` instead of ``Opening`` the existing db. Once you click on ``Save``, a panel will warns you that ``h2gisdb.mv.db`` already exists and will ask you if you want to ``Cancel`` or ``Replace`` : click on ``Replace``. + If you are using a version of DBeaver prior to 22.0.4, the interface may ask you to ``Save`` instead of ``Opening`` the existing db. Once you click on ``Save``, a panel will warns you that ``user_001.mv.db`` already exists and will ask you if you want to ``Cancel`` or ``Replace`` : click on ``Replace``. Now you can use the full potential of DBeaver and the H2GIS database. You can explore, display and manage your database. diff --git a/Docs/Noise_Map_Color_Scheme.rst b/Docs/Noise_Map_Color_Scheme.rst index 533d1fe87..5759309e7 100644 --- a/Docs/Noise_Map_Color_Scheme.rst +++ b/Docs/Noise_Map_Color_Scheme.rst @@ -45,7 +45,7 @@ This ``.sld`` file can be loaded in many GIS applications, such as `QGIS`_. The .. note:: For those who are new to GIS and want to get started with QGIS, we advise you to follow `this tutorial`_ as a start. - To know how to load an ``.sld`` file, you can also consult the NoiseModelling tutorial :doc:`Noise_Map_From_Point_Source` in the section "``Step 3 - Apply a color palette adapted to acoustics``" + To know how to load an ``.sld`` file, you can also consult the NoiseModelling tutorial :doc:`Tutorial_Noise_Map_From_Point_Source` in the section "``Step 3 - Apply a color palette adapted to acoustics``" .. _this tutorial : https://docs.qgis.org/3.22/en/docs/training_manual/basic_map/index.html diff --git a/Docs/Own_Wps.rst b/Docs/Own_Wps.rst index d98508a9f..d4860bd62 100644 --- a/Docs/Own_Wps.rst +++ b/Docs/Own_Wps.rst @@ -8,9 +8,7 @@ The OGC Web Processing Service (`WPS`_) Standard provides rules for standardizin .. _WPS : https://www.ogc.org/standards/wps -WPS scripts for NoiseModelling are written in Groovy language. They are located in the ``NoiseModelling/data_dir/scripts/wps`` directory. - -To help you build your WPS script, you will find a template in the ``NoiseModelling/data_dir/scripts/template`` directory +WPS scripts for NoiseModelling are written in Groovy language. They are located in the ``NoiseModelling/scripts/`` directory. .. note:: Don't be shy, if you think your script can be useful to the community, you can redistribute it using github or by sending it directly to us. @@ -24,59 +22,62 @@ General Structure 1. Import used libraries ------------------------- -:: +.. code-block:: groovy - import geoserver.GeoServer - import geoserver.catalog.Store + import groovy.sql.Sql + import java.sql.Connection + import org.h2gis.api.ProgressVisitor 2. WPS Script meta data ------------------------- -:: - - title = '....' - description = '.....' - -3. WPS Script input & output ------------------------------------ - -:: +.. code-block:: groovy + title = 'My script title' + description = 'My script description, I support html !' inputs = [ - inputparameter1: [name: '...', description : '...', title: '...', type: String.class], - inputparameter2: [name: '...', description : '...', title: '...', type: String.class] + my_optional_parameter: [name: 'option1', title: 'option1', description : 'Description, you can use html here. This parameter is optional because you have provided a default value', type: String.class, default: 'MY_RESULT_TABLE'], + my_integer_parameter: [name: 'my_integer_parameter', title: 'my_integer_parameter', description : 'Restrict to an int, you can use html here', type: Integer.class], + my_double_parameter: [name: 'my_double_parameter', title: 'my_double_parameter', description : 'Restrict to an floating point value, you can use html here', type: Double.class], + my_boolean_parameter: [name: 'my_boolean_parameter', title: 'my_boolean_parameter', description : 'A checkbox parameter', type: Boolean.class], + my_choice_parameter: [name: 'my_choice_parameter', title: 'my_choice_parameter', description : 'A list box with limited choices', type: String.class, allowedValues : ["Choice 1", "Choice 2", "Choice 3"], default : "Choice 2"], ] + // Optional (default 60 seconds) + // For synchronous WPS, it will wait this time (in seconds) before returning a message, but it will still run the execution in the background + executionTimeout = 120 + + outputs = [ - ouputparameter: [name: '...', title: '...', type: String.class] + result: [name: 'result', title: 'result', description : 'Result output, generally the result output table name. You can use this output as an input for another processing', type: String.class] ] -4. Set connection method ------------------------------------ -:: +.. note:: + You may want to add an optional parameter but without a default value (the input will not be in the input map) to do so instead of defining a default value ``default: 'MY_RESULT_TABLE'`` use the entry ``min : 0`` - def static Connection openPostgreSQLDataStoreConnection() { - Store store = new GeoServer().catalog.getStore("h2gisdb") - JDBCDataStore jdbcDataStore = (JDBCDataStore)store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() - } -5. Set main method to execute +4. Set main method to execute ----------------------------------- -:: - - def run(input) { - - // Open connection and close it at the end - openPostgreSQLDataStoreConnection(dbName).withCloseable { Connection connection -> - // Execute code here - // for example, run SQL command lines - Sql sql = new Sql(connection) - sql.execute("drop table if exists TABLETODROP") - } - - // print to Console windows - return [result : 'Ok ! '] +.. code-block:: groovy + + /** + * Main method + * @param connection SQL Connection + * @param input Map of inputs, should provide the same keys as described in the input metadata + * @param progress Can be used to display the progression of the computation, and to check if the user canceled the execution + * @return A map as described in the result metadata + * @throws SQLException if something went wrong + */ + def exec(Connection connection, Map inputs, ProgressVisitor progress) { + Sql sql = new Sql(connection) + // Get the parameter value. For optional parameters, do not forget to provide a default value in the metadata. + def myTableName = inputs.my_optional_parameter + sql.execute("CREATE TABLE IF NOT EXISTS $myTableName(PK SERIAL PRIMARY KEY, DATA INTEGER)".toString()) + return [result : '$myTableName'] } + +5. Make your method available + +You have to save the script into the folder ``NoiseModelling/scripts/``. You have to refresh the web page WPS Builder in order to see your new script. diff --git a/Docs/Requirements.rst b/Docs/Requirements.rst deleted file mode 100644 index 3bd84875b..000000000 --- a/Docs/Requirements.rst +++ /dev/null @@ -1,57 +0,0 @@ -Requirements -^^^^^^^^^^^^^^^^^ - -Java environment -~~~~~~~~~~~~~~~~~~~~ - -Since NoiseModelling is developped with the `Java langage`_, you will need to install the Java Runtime Environment (JRE) on your computer to use the application. - -.. warning:: - **Only version 11.x of Java is compatible with NoiseModelling 4.x**. Unfortunatelay, former or newer versions are not compatible with NoiseModelling 4.x. - -.. _Java langage : https://en.wikipedia.org/wiki/Java_(programming_language) - - - - -Windows ----------- - -If you are launching NoiseModelling thanks to the ``NoiseModelling_xxx_install.exe`` file, the JRE is already inside, so **you don't have anything to do**. - -If you are not using the ``.exe`` file, you have to launch NoiseModelling thanks to the ```...\bin\startup_windows.bat`` file (in the ``NoiseModelling_xxx.zip`` release file). In this case, Java v11.x has to be installed before. - - -#. Download and install Java: choose between `OpenJDK`_ or `Oracle`_ versions. - -#. You can check if ``JAVA_HOME`` environnement variable is well settled to your last installed Java folder using ``echo %JAVA_HOME%`` in your command prompt. You should have a result similar to ``C:\\Program Files (x86)\\Java\\jre1.8.x_x\\``. - -#. If you don't have this result, it is probably because your ``JAVA_HOME`` environnement variable is not well settled. To set you ``JAVA_HOME`` environnement variable you can adapt (with ``x`` the JAVA version number) you installed and use the following command line : ``setx JAVA_HOME "C:\\Program Files (x86)\\Java\\jre.1.8.x_x"`` in your command prompt. You can also refer to `this document`_ for example. - -#. You may have to reboot your command prompt after using the precedent command line before printing again ``echo %JAVA_HOME%``. - -.. warning:: - The command promprt should print ``C:\\Program Files (x86)\\Java\\jre1.11.x_x\\`` whithout the bin directory. If ``JAVA_HOME`` is settled as ``C:\\Program Files (x86)\\Java\\jre1.11.x_x\\bin``, it will not work. It should also point to a JRE (Java Runtime Environment) Java environnement and not JDK. - -.. _this document : https://confluence.atlassian.com/doc/setting-the-java_home-variable-in-windows-8895.html - - -Linux or Mac -------------- - -If not already done, you have to install the Java version v11.x. - - -#. Download and install Java: choose between `OpenJDK`_ or `Oracle`_ versions. - -#. You can check if ``JAVA_HOME`` environnement variable is well settled to your installed v11.x Java folder using ``echo $JAVA_HOME`` in your command prompt. You should have a result similar to ``/usr/lib/jvm/java-11-openjdk-amd64/``. - -#. If you don't have this result, it is probably because your ``JAVA_HOME`` environnement variable is not well settled. In this case, you are invited to follow the steps `proposed here`_. - -#. Once done, you may have to reboot your command prompt (or maybe disconnect/reconnect your session) after using the precedent command line before printing again ``echo $JAVA_HOME``. - -.. _proposed here: https://stackoverflow.com/questions/24641536/how-to-set-java-home-in-linux-for-all-users - - -.. _OpenJDK : https://jdk.java.net/archive/ -.. _Oracle : https://www.oracle.com/fr/java/technologies/javase/jdk11-archive-downloads.html \ No newline at end of file diff --git a/Docs/Data_Assimilation_Tutorial.rst b/Docs/Tutorial_Data_Assimilation.rst similarity index 90% rename from Docs/Data_Assimilation_Tutorial.rst rename to Docs/Tutorial_Data_Assimilation.rst index b113a4e47..01bded78b 100644 --- a/Docs/Data_Assimilation_Tutorial.rst +++ b/Docs/Tutorial_Data_Assimilation.rst @@ -1,11 +1,11 @@ Data Assimilation ^^^^^^^^^^^^^^^^^^^^ -.. image:: ./images/Data_Assimilation/data_assimilation_banner.png +.. image:: ./images/tutorial/Data_Assimilation/data_assimilation_banner.png :alt: Data assimilation Introduction -~~~~~~~~~~~~~~~ +~~~~~~~~~~~~ Data assimilation is a technique that combines observations with a numerical model to improve the accuracy of forecasts or analyses. Applied to acoustics and noise maps, data assimilation makes it possible to integrate real noise measurements (*e.g* coming from sensors) into noise propagation models to produce more accurate and reliable noise maps. @@ -15,13 +15,13 @@ The main objective is to **combine measurements from sensors** located in Geneva .. _Geneva: https://www.openstreetmap.org/relation/1685488 Requirements -~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~ To play with this tutorial, you will need: -* a working installation of NoiseModelling (NM) with at least version 5.0.1. If needed, get the last release on the official `GitHub repository`_, -* the tutorial's datasets, stored in the folder ``.../NoiseModelling_5.0.1/data_dir/data/wpsdata/dataAssimilation/``, -* the dedicated WPS ``.groovy`` scripts, stored in the folder ``.../NoiseModelling_5.0.1/data_dir/scripts/wps/DataAssimilation/``. +* a working installation of NoiseModelling (NM) with at least version 5. If needed, get the last release on the official `GitHub repository`_, +* the tutorial's datasets, stored in the folder ``.../NoiseModelling/resources/dataAssimilation/``, +* the dedicated WPS ``.groovy`` scripts, stored in the folder ``.../NoiseModelling/scripts/DataAssimilation/``. .. _GitHub repository: https://github.com/Universite-Gustave-Eiffel/NoiseModelling/releases @@ -74,7 +74,7 @@ The ``device_mapping_sf.geojson`` columns are: Below is a map, showing the seven sensors (red points), with their identifier ``deveui``. -.. image:: ./images/Data_Assimilation/geneva_sensors.png +.. image:: ./images/tutorial/Data_Assimilation/geneva_sensors.png :alt: Sensors in Geneva @@ -84,10 +84,10 @@ To compute the data assimilation, you will have to execute several WPS ``.groovy * with the NoiseModelling's GUI (Graphic User Interface). In this case, the WPS blocks are listed in the ``Data_Assimilation`` tab *(see screenshot below)*, -* in command line (see how to :doc:`Get_Started_Script`). In this case, just note that they are stored in the folder ``.../NoiseModelling_5.0.1/data_dir/scripts/wps/DataAssimilation/``, +* in command line (see how to :doc:`Tutorial_Get_Started_Script`). In this case, just note that they are stored in the folder ``.../NoiseModelling_x.x.x/scripts/DataAssimilation/``, * in a .groovy script, calling one or various WPS .groovy scripts. -.. image:: ./images/Data_Assimilation/NM_GUI_wps_list.png +.. image:: ./images/tutorial/Data_Assimilation/NM_GUI_wps_list.png :alt: List of WPS blocks Data Simulation @@ -117,7 +117,7 @@ Execute ``All_Possible_Configuration`` WPS block With the **NoiseModelling GUI** -.. image:: ./images/Data_Assimilation/all_possible_configuration_all.png +.. image:: ./images/tutorial/Data_Assimilation/all_possible_configuration_all.png :alt: All possible configuration With **command lines** @@ -180,11 +180,11 @@ Step 2 : Import sensor positions Using the ``Import_File`` WPS script*, import the location of the sensors into the NoiseModelling's database from the .geojson file ``device_mapping_sf.geojson``. This file will be stored in a table called ``SENSORS_LOCATION``. -\* in the ``data_dir/scripts/wps/Ìmport_and_Export/`` folder +\* in the ``scripts/Ìmport_and_Export/`` folder 🌍 Since we are in the Geneva area, we are using the ``CH1903+`` metric coordinate system (identified as `EPSG:2056`_). -* ``pathFile`` : ``.../device_mapping_sf.geojson`` +* ``pathFile`` : ``./resources/dataAssimilation/device_mapping_sf.geojson`` * ``inputSRID`` : ``2056`` * ``tableName`` : ``SENSORS_LOCATION`` @@ -206,7 +206,7 @@ Result Once done, you have the table ``SENSORS_LOCATION``, presented below. -.. csv-table:: +.. csv-table:: :file: ./data/SENSORS_LOCATION.csv :widths: 80, 20 :header-rows: 1 @@ -215,12 +215,12 @@ Once done, you have the table ``SENSORS_LOCATION``, presented below. Step 3 : Prepare sensor data --------------------------------------- -Now we can extract and prepare the sensors, for a given period. To do so, we are using the ``Prepare_Sensors`` WPS .groovy script stored in the folder ``.../data_dir/scripts/wps/DataAssimilation/``. +Now we can extract and prepare the sensors, for a given period. To do so, we are using the ``Prepare_Sensors`` WPS .groovy script stored in the folder ``.../scripts/DataAssimilation/``. -This script has the following parameters: +This script has the following parameters: -* ``startDate`` : the start timestamp to extract the dataset (in format ``YYYY-MM-DD HH:MM:SS``) -* ``endDate`` : the start timestamp to extract the dataset (in format ``YYYY-MM-DD HH:MM:SS``) +* ``startDate`` : the start timestamp for the dataset extraction (in format ``YYYY-MM-DD HH:MM:SS``) +* ``endDate`` : the final timestamp for the dataset extraction (in format ``YYYY-MM-DD HH:MM:SS``) * ``trainingRatio`` : define the percentage of data to be used for training (e.g a value of 0.7 means that 70% of the data will be used for training. The remaining 30% will be used for validation) (Double) * ``workingFolder`` : folder containing the file ``device_mapping_sf.csv``, the OSM file and the ``devices_data`` folder. * ``targetSRID``: Target projection identifier (also called SRID) of your project (Integer) @@ -230,11 +230,11 @@ Execution For this tutorial, you can fill with these informations: -* ``startDate`` : ``2024-08-25 06:30:00`` -* ``endDate`` : ``2024-08-25 07:30:00`` -* ``trainingRatio`` : ``0.8`` -* ``workingFolder`` : ``.../data_dir/data/wpsdata/dataAssimilation/`` (enter the full URL e.g ``/home/myUserName/Documents/NoiseModelling_5.0.0/NoiseModelling_5.0.0/data_dir/data/wpsdata/dataAssimilation/``) -* ``targetSRID`` : ``2056`` +* Start time stamp (``startDate``) : ``2024-08-25 06:30:00`` +* End time stamp (``endDate``) : ``2024-08-25 07:30:00`` +* Training data percentage(``trainingRatio``) : ``0.8`` +* Working directory path with input files (``workingFolder``) : ``./resources/dataAssimilation/`` (enter the full URL e.g ``/home/myUserName/Documents/NoiseModelling/resources/dataAssimilation/``) +* Target projection identifier (``targetSRID``) : ``2056`` If you are using the Groovy script @@ -244,7 +244,7 @@ If you are using the Groovy script "startDate":"2024-08-25 06:30:00", "endDate": "2024-08-25 07:30:00", "trainingRatio": 0.8, - "workingFolder": ".../data_dir/data/wpsdata/dataAssimilation/", + "workingFolder": "./resources/dataAssimilation/", "targetSRID": 2056 ]) @@ -272,7 +272,7 @@ Now, using the ``Ìmport_OSM`` block, you can import buildings and road network Execution ********** -* Path of the OSM file (``pathFile``): ``.../data_dir/data/wpsdata/dataAssimilation/geneva.osm.pbf`` +* Path of the OSM file (``pathFile``): ``./resources/dataAssimilation/geneva.osm.pbf`` * Target projection identifier (``targetSRID``): ``2056`` * Do not import Surface acoustic absorption (``ignoreGround``): ``true`` * Remove tunnels from OSM data (``removeTunnels``): ``true`` @@ -284,7 +284,7 @@ If you are using the Groovy script .. code-block:: groovy new Import_OSM().exec(connection, [ - "pathFile" : ".../data_dir/data/wpsdata/dataAssimilation/geneva.osm.pbf", + "pathFile" : "./resources/dataAssimilation/geneva.osm.pbf", "targetSRID" : 2056, "ignoreGround" : true, "removeTunnels" : true @@ -298,7 +298,7 @@ The tables ``BUILDINGS`` and ``ROADS`` are created. .. note:: If you are using NoiseModelling with the GUI and wish to visualize the data in a map, you can use the ``Table_Visualization_Map`` block. Below is the result with the two table ``BUILDINGS`` *(left)* and ``ROADS`` *(right)*. - .. image:: ./images/Data_Assimilation/BUILDINGS_ROADS.png + .. image:: ./images/tutorial/Data_Assimilation/BUILDINGS_ROADS.png :alt: BUILDINGS and ROADS .. _Generate_all_traffic_emissions_and_maps: @@ -313,7 +313,7 @@ This step consists in generating all the traffic emissions by modifying traffic To do so, users have first to execute the ``Data_Simulation`` WPS block, which has only one **optionnal** parameter : -* ``noiseMapLimit`` : final number of maps to be generated (Integer). If a value is filled, a random selection is applied to keep the number of expected maps, based on the LHS (`Latin Hypercube Sampling`_) method. +* ``noiseMapLimit`` : final number of maps to be generated (%). If a value is filled, a random selection is applied to keep the percentage(%) of expected maps, based on the LHS (`Latin Hypercube Sampling`_) method. .. _Latin Hypercube Sampling: https://en.wikipedia.org/wiki/Latin_hypercube_sampling @@ -490,8 +490,9 @@ The table ``RECEIVERS`` is created. :widths: 25, 25, 25, 25 :header-rows: 1 -.. image:: ./images/Data_Assimilation/RECEIVERS.png +.. image:: ./images/tutorial/Data_Assimilation/RECEIVERS.png :alt: RECEIVERS map + :width: 80% Step 8 : Adding sensors as receivers @@ -521,8 +522,9 @@ Result The ``RECEIVERS`` table has now new points, the sensor's one -.. image:: ./images/Data_Assimilation/RECEIVERS_and_SENSORS.png +.. image:: ./images/tutorial/Data_Assimilation/RECEIVERS_and_SENSORS.png :alt: RECEIVERS and SENSORS map + :width: 80% Step 9 : Generate dynamic road emissions @@ -670,12 +672,12 @@ or The resulting map may looks like this: -.. image:: ./images/Data_Assimilation/ASSIMILATED_MAPS_200m.png +.. image:: ./images/tutorial/Data_Assimilation/ASSIMILATED_MAPS_200m.png :alt: ASSIMILATED_MAPS map -**Legend**: Here, we applied the color scheme proposed by Beate Tomio (see :doc:`Noise_Map_Color_Scheme`) on the column ``LAEQ``. We also added the input sensors, the buildings (light grey) and the roads (white lines). +**Legend**: Here, we applied the color scheme proposed by Beate Tomio (see :doc:`Noise_Map_Color_Scheme`) on the column ``LAEQ``. We also added the input sensors, the buildings (medium grey) and the roads (light grey). **Remark**: In this example, we have chosen to have a receiver every 200m (see :ref:`Step 7 `). To achieve a denser rendering, we could have made the receiver grid denser. Below is an example, on the same area, but with a 20m grid. -.. image:: ./images/Data_Assimilation/ASSIMILATED_MAPS.png +.. image:: ./images/tutorial/Data_Assimilation/ASSIMILATED_MAPS.png :alt: ASSIMILATED_MAPS map \ No newline at end of file diff --git a/Docs/Dynamic_Tutorial.rst b/Docs/Tutorial_Dynamic.rst similarity index 79% rename from Docs/Dynamic_Tutorial.rst rename to Docs/Tutorial_Dynamic.rst index f4a2319a5..66a755180 100644 --- a/Docs/Dynamic_Tutorial.rst +++ b/Docs/Tutorial_Dynamic.rst @@ -1,4 +1,4 @@ -Dynamic Tutorial - GUI +Dynamic Maps - GUI ^^^^^^^^^^^^^^^^^^^^^^^^ Many publications have emerged showcasing the use of **NoiseModelling** to create dynamic maps (see `scientific production`_). @@ -16,7 +16,7 @@ There are three main approaches to creating dynamic maps using NoiseModelling: You have a road network and traffic flow data available at regular intervals (e.g., hourly or every 15 minutes), and you want to generate a dynamic noise map every 15 min. 3. **A road network with associated spatio-temporal data of moving sources** - You have spatio-temporal information about vehicles moving around a network (e.g., from traffic simulations such as Simuvya or SUMO; or from trajectories of drones). You want to compute **time-series data at each receiver** corresponding to the passage of these sources. + You have spatio-temporal information about vehicles moving around a network (e.g., from traffic simulations such as Symuvia or SUMO; or from trajectories of drones). You want to compute **time-series data at each receiver** corresponding to the passage of these sources. A word of caution ------------------- @@ -40,7 +40,7 @@ Import the road network (with arbitrary traffic flows) and buildings from an OSM Use ``Import_OSM`` WPS block -#. ``Path of the osm file``: Enter the path of the provided Open Street map file (can be relative to NoiseModelling): ``data_dir/data/wpsdata/map.osm.gz`` +#. ``Path of the osm file``: Enter the path of the provided Open Street map file (can be relative to NoiseModelling): ``resources/map.osm.gz`` #. ``Target projection identifier``: Enter the official France projection for this tutorial files ``2154`` #. ``Remove tunnels``: Check it #. ``Do not import surface``: Check it as we will not use this output @@ -66,27 +66,27 @@ Convert traffic to dynamic traffic flow From the network with traffic flow to individual trajectories with associated Lw -#. The Probabilistic method, this method place randomly the vehicles on the network according to the traffic flow -#. The Poisson method place the vehicles on the network according to the traffic flow following a poisson law, it keeps a coherence in the time series of the noise level +#. The Probabilistic method, this method places randomly the vehicles on the network according to the traffic flow +#. The Poisson method places the vehicles on the network according to the traffic flow following a poisson law, it keeps a coherence in the time series of the noise level Use the ``Dynamic:Flow_2_Noisy_Vehicles`` WPS block: -#. ``Method``: Enter ``TNP`` Use the Poisson method +#. ``Method``: Select ``TNP`` to use the Poisson method #. ``Roads table name``: Enter ``ROADS`` #. ``timestep``: Enter ``1`` #. ``duration``: Enter ``60`` #. ``gridStep``: Enter ``10`` -Compute noise level at receivers points for each receiver-period -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Compute noise level at receiver points for each receiver-period combination +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Use the ``NoiseModelling:Noise_level_from_source`` WPS block #. ``Buildings table name``: Enter ``BUILDINGS`` -#. ``Source geometry table name``: Enter ``SOURCES_GEOM`` Contain only the geometries of the sources (points) -#. ``Source emission table name``: Enter ``SOURCES_EMISSION`` Contain for each source index and period the noise emission +#. ``Source geometry table name``: Enter ``SOURCES_GEOM`` Contains only the geometries of the sources (points) +#. ``Source emission table name``: Enter ``SOURCES_EMISSION`` Contains for each source index and period the noise emission #. ``Receivers table name``: Enter ``RECEIVERS`` -#. ``Max Error (dB)``: Enter ``3`` Will skip further sources, reduce the computation time for this tutorial +#. ``Max Error (dB)``: Enter ``3`` Will skip further sources, reduces the computation time for this tutorial #. ``Maximum source receiver distance``: Enter ``800`` #. ``Diffraction on horizontal edges``: Check it #. ``Order of reflexion``: Enter ``0`` @@ -94,7 +94,7 @@ Use the ``NoiseModelling:Noise_level_from_source`` WPS block Compute noise indicators ~~~~~~~~~~~~~~~~~~~~~~~~~~ -This step is optional, it compute the LA10, LA50 and LA90 at each receiver from the table RECEIVERS_LEVEL +This step is optional, it computes the LA10, LA50 and LA90 time-aggregated indicators at each receiver from the table RECEIVERS_LEVEL Use the ``Acoustic_Tools:DynamicIndicators`` wps block @@ -110,12 +110,12 @@ Generate a dynamic iso-contour map for each time period based on the LAEQ of the Use the ``Acoustic_Tools:Create_Isosurface`` wps block #. ``Sound levels table``: Enter ``RECEIVERS_LEVEL`` -#. ``Smooth coefficient``: Enter ``0`` +#. ``Polygon smoothing coefficient``: Enter ``0`` Export Map to QGis ~~~~~~~~~~~~~~~~~~~ -Using ``Export_Table`` block export the following tables as files in any folder. +Use ``Export_Table`` block to export the following tables as files in any folder. #. ``CONTOURING_NOISE_MAP`` #. ``BUILDINGS`` @@ -137,7 +137,8 @@ Load the style located in the NoiseModelling folder ``Docs/styles/style_beate_to In QGis, in time window, paste the following formulae: -``datetime_from_epoch(to_real("PERIOD")*1000+1739869220000)`` +Start expression: ``datetime_from_epoch(to_real("PERIOD")*1000+1739869220000)`` +End expression: ``datetime_from_epoch(to_real("PERIOD")*1000+1739869221000)`` .. figure:: images/tutorial/dynamic/temporal_settings.png :align: center @@ -147,7 +148,7 @@ Epoch is in millisecond, so we multiply by 1000 and add any base epoch time. The With the navigation bar of QGis you can select the period to display. -.. figure:: images/tutorial/dynamic/temporal_bar_nav.png +.. figure:: images/tutorial/dynamic/temporal_bar_nav.gif :align: center :alt: Layer setting, temporal tab in QGis @@ -156,14 +157,14 @@ Case 2: A Road Network with Traffic Flows at Regular Intervals This case is similar to the **MATSim** use case (`here `_), but this tutorial generalizes the approach to fit other datasets. -This sample dataset used in this example was kindly provided by Valentin Le bescond from Université Gustave Eiffel. +This sample dataset used in this example was kindly provided by Valentin Le Bescond from Université Gustave Eiffel. Import Buildings for your study area ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Use ``Import File`` WPS block -#. ``Path of the input File``: Enter the path of building (can be relative to NoiseModelling): ``data_dir/data/wpsdata/Dynamic/Z_EXPORT_TEST_BUILDINGS.geojson`` +#. ``Path of the input File``: Enter the path of building (can be relative to NoiseModelling): ``resources/Dynamic/Z_EXPORT_TEST_BUILDINGS.geojson`` #. ``Projection identifier``: Enter SRID ``2154`` #. ``Output table name``: Enter ``buildings`` @@ -172,7 +173,7 @@ Import the road network Use ``Import File`` WPS block -#. ``Path of the input File``: Enter the path of building (can be relative to NoiseModelling): ``data_dir/data/wpsdata/Dynamic/Z_EXPORT_TEST_TRAFFIC.geojson`` +#. ``Path of the input File``: Enter the path of building (can be relative to NoiseModelling): ``resources/Dynamic/Z_EXPORT_TEST_TRAFFIC.geojson`` #. ``Projection identifier``: Enter SRID ``2154`` #. ``Output table name``: Enter ``roads`` @@ -188,44 +189,48 @@ Use ``Regular_Grid`` WPS block Split geometry and traffic periods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In the table ``ROADS``, the traffic information is given for each period in the ``TIME`` column. +In the table ``ROADS``, the traffic information is given for each period in the ``PERIOD`` column. -The following WPS block aggregate roads by the geometry and place the associated pair ``IDSOURCE``/``PERIOD`` +The following WPS block aggregates roads by the geometry and places the associated pair ``IDSOURCE``/``PERIOD`` with the corresponding road traffic into the ``SOURCES_EMISSION`` table. Use the block ``Dynamic::Split_Sources_Period`` : #. ``Source table name``: Enter ``ROADS`` #. ``Source index field name``: Enter ``LINK_ID`` -#. ``Source period field name``: Enter ``TIME``. The field time will be renamed to ``PERIOD``. +#. ``Source period field name``: Enter ``PERIOD``. -Two output table is created ``SOURCES_GEOM`` and ``SOURCES_EMISSION`` +Two output tables are created ``SOURCES_GEOM`` and ``SOURCES_EMISSION`` -Compute noise level at receivers points for each receiver-period -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Compute noise level at receiver points for each receiver-period combination +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Use the ``NoiseModelling:Noise_level_from_source`` WPS block #. ``Buildings table name``: Enter ``BUILDINGS`` -#. ``Source geometry table name``: Enter ``SOURCES_GEOM`` Contain only the geometries of the sources (points) -#. ``Source emission table name``: Enter ``SOURCES_EMISSION`` Contain for each source index and period the noise emission +#. ``Source geometry table name``: Enter ``SOURCES_GEOM`` Contains only the geometries of the sources (points) +#. ``Source emission table name``: Enter ``SOURCES_EMISSION`` Contains for each source index and period the noise emission #. ``Receivers table name``: Enter ``RECEIVERS`` #. ``Diffraction on horizontal edges``: Check it #. ``Order of reflexion``: Enter ``0`` +The ``RECEIVERS_LEVEL`` output table is created. Compute noise indicators ~~~~~~~~~~~~~~~~~~~~~~~~~~ -This step is optional, it compute the LA10, LA50 and LA90 at each receiver from the table ``LT_GEOM`` +This step is optional, it computes the LA10, LA50 and LA90 time-aggregated indicators at each receiver from the table ``RECEIVERS_LEVEL``. Use the ``Acoustic_Tools:DynamicIndicators`` wps block #. ``tableName``: Enter ``RECEIVERS_LEVEL`` #. ``columnName``: Enter ``LAEQ`` -The result table LT_GEOM can be displayed into QGis, if you filter by ``PERIOD``. +Visualizing results +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The result table ``RECEIVERS_LEVEL`` can be displayed in QGis, if you filter by ``PERIOD``. Case 3: Spatio-Temporal Data of Moving Sources ---------------------------------------------------- @@ -239,7 +244,7 @@ Import Buildings for your study area Use ``Import File`` WPS block -#. ``Path of the input File``: Enter the path of building (can be relative to NoiseModelling): ``data_dir/data/wpsdata/Dynamic/buildings_nm_ready_pop_heights.shp`` +#. ``Path of the input File``: Enter the path of building (can be relative to NoiseModelling): ``resources/Dynamic/buildings_nm_ready_pop_heights.shp`` #. ``Projection identifier``: Enter SRID ``32635`` #. ``Output table name``: Enter ``buildings`` @@ -248,10 +253,9 @@ Import the receivers (or generate your set of receivers using Regular_Grid scrip Use ``Import File`` WPS block -#. ``Path of the input File``: Enter the path of building (can be relative to NoiseModelling): ``data_dir/data/wpsdata/Dynamic/receivers_python_method0_50m_pop.shp`` +#. ``Path of the input File``: Enter the path of building (can be relative to NoiseModelling): ``resources/Dynamic/receivers_python_method0_50m_pop.shp`` #. ``Projection identifier``: Enter SRID ``32635`` #. ``Output table name``: Enter ``receivers`` -#. ``height``: Enter ``1.5`` Import the road network @@ -259,7 +263,7 @@ Import the road network Use ``Import File`` WPS block -#. ``Path of the input File``: Enter ``data_dir/data/wpsdata/Dynamic/network_tartu_32635_.geojson`` +#. ``Path of the input File``: Enter ``resources/Dynamic/network_tartu_32635_.geojson`` #. ``Projection identifier``: Enter SRID ``32635`` #. ``Output table name``: Enter ``network_tartu`` @@ -271,12 +275,12 @@ Use ``Add_Primary_Key`` WPS block #. ``Name of the column``: Enter ``PK`` #. ``Name of the table``: Enter SRID ``network_tartu`` -Import the vehicles trajectories +Import the vehicle trajectories ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Use ``Import File`` WPS block -#. ``Path of the input File``: Enter ``data_dir/data/wpsdata/Dynamic/SUMO.geojson`` +#. ``Path of the input File``: Enter ``resources/Dynamic/SUMO.geojson`` #. ``Projection identifier``: Enter SRID ``32635`` #. ``Output table name``: Enter ``vehicle`` @@ -298,19 +302,19 @@ Use ``Ind_Vehicles_2_Noisy_Vehicles`` WPS block #. ``Source geometry table``: Enter ``SOURCES_GEOM`` #. ``Individual Vehicles table``: Enter ``vehicle`` -#. ``Snap distance``: Enter ``30`` This is the maximal distance (m) to reattach individual vehicles position to the source points +#. ``Snap distance``: Enter ``30`` This is the maximal distance (m) to reattach individual vehicle positions to the source points #. ``Vehicles table format``: Enter ``SUMO`` Compute noise attenuation for each receiver-source pairs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlike the previous tutorial we will use an alternative approach here by storing the attenuation between all sources and receivers first. -The applying later this attenuation to the emission level for each period. + This attenuation will be applied later to the emission levels for each period. Use the ``NoiseModelling:Noise_level_from_source`` WPS block #. ``Buildings table name``: Enter ``BUILDINGS`` -#. ``Source geometry table name``: Enter ``SOURCES_GEOM`` Contain only the geometries of the sources (points) +#. ``Source geometry table name``: Enter ``SOURCES_GEOM`` Contains only the geometries of the sources (points) #. ``Receivers table name``: Enter ``RECEIVERS`` #. ``Maximum source receiver distance``: Enter ``300`` #. ``Diffraction on horizontal edges``: Check it @@ -333,15 +337,18 @@ Use the ``Dynamic:Noise_From_Attenuation_Matrix`` WPS block Compute noise indicators ~~~~~~~~~~~~~~~~~~~~~~~~~ -This step is optional, it compute the LA10, LA50 and LA90 at each receiver from the table ``LT_GEOM`` +This step is optional, it computes the LA10, LA50 and LA90 time-aggregated indicators at each receiver from the table ``LT_GEOM`` Use the ``Acoustic_Tools:DynamicIndicators`` wps block -#. ``tableName``: Enter ``RECEIVERS_LEVEL`` +#. ``tableName``: Enter ``LT_GEOM`` #. ``columnName``: Enter ``LAEQ`` -The result table LT_GEOM can be displayed into QGis, if you filter by ``PERIOD``. +Visualizing results +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The result table ``LT_GEOM`` can be displayed into QGis, if you filter by ``PERIOD``. .. note:: - All this tutorial done with Groovy is written on this unit test source code: `Github source `_ + All this tutorial done with Groovy is written on this unit test source code: `Github source `_ diff --git a/Docs/Tutorial_Get_Started_GUI.rst b/Docs/Tutorial_Get_Started_GUI.rst new file mode 100644 index 000000000..f4311cb21 --- /dev/null +++ b/Docs/Tutorial_Get_Started_GUI.rst @@ -0,0 +1,205 @@ +Get Started - GUI +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Below we present a simple example to help you discover NoiseModelling through its Graphical User Interface (GUI). + +Step 1: Download NoiseModelling +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Download the latest release of NoiseModelling on `Github`_. + +* Windows: you can directly download and run the ``NoiseModelling_5.x.x_install.exe`` installer file *(or you can also follow the Linux / Mac instructions below)* +* Linux or Mac: download the ``NoiseModelling_5.x.x.zip`` file and unzip it into a chosen directory + +.. warning:: + The chosen directory can be anywhere, but make sure you have write access. If you are using a company computer, the Program Files folder is probably not a good idea. + +.. warning:: + For **Linux** and **Mac** users, please make sure your Java environment is correctly set up. For more information, please read the page :doc:`Tutorial_Requirements`. **Windows** users who are using the ``.exe`` file are not concerned, since the Java Runtime Environment is **already embedded**. + +.. note:: + Starting from version 3.3, NoiseModelling releases include the user interface described in this tutorial. + +.. _Github : https://github.com/Universite-Gustave-Eiffel/NoiseModelling/releases + + + +Step 2: Start NoiseModelling GUI +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As described on the page ":doc:`Architecture`", NoiseModelling can be used through a Graphical User Interface (GUI) in a web browser. + +In this tutorial, we will use the default, already configured H2GIS database. + +These tools (WPS Builder and H2GIS) are already included in the archive, so you don't have to install them separately. + +To launch NoiseModelling with the GUI, start it from a command prompt (terminal). This will start a local server on your computer, which provides the GUI as a web application. + +Please execute: + +* Windows: ``NoiseModelling.exe`` or ``NoiseModelling_xxx\start_windows.bat`` +* Linux or Mac: ``NoiseModelling_xxx/start_linux_macos.sh`` *(make sure the file is allowed to be executed before running it)* + +.. tip:: + NoiseModelling will stay open as long as the command window is open. If you close it, NoiseModelling will automatically stop and the GUI will no longer be available. + +.. _H2GIS : http://www.h2gis.org/ + +Step 3: Open NoiseModelling GUI +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The NoiseModelling GUI is built using the :doc:`WPS_Builder` component and runs as a web application provided by the local server started in Step 2. + +By running NoiseModelling your default web browser should have been opened to the http://localhost:8000 address. If not please go to this URL, if something went wrong you should have more information on your terminal. + +.. figure:: images/tutorial/get_started_gui/Tutorial1_nm_landing.png + :align: center + :width: 80% + + Noise Modelling GUI landing page + +Click ``builder`` to open the builder. + +.. figure:: images/tutorial/get_started_gui/Tutorial1_nm_open.png + :align: center + :width: 80% + +You are now ready to discover the power of NoiseModelling! + +Step 4: Load input files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To compute your first noise map, you need to load input geographic files into the NoiseModelling database. + +In this tutorial, we have 5 layers, zoomed in on the city center of `Lorient`_ (France): Buildings, Roads, Ground type, Topography (DEM) and Receivers. + +.. _Lorient : https://www.openstreetmap.org/relation/30305 + +In the ``resources/`` sub-folder of the NoiseModelling installation, you will find all the data that will be used in the tutorials. + +You will import these layers into your database using the ``Import File`` blocks. + +- Drag the ``Import File`` block into the Builder window +- Select the ``Path of the input File`` box and enter ``resources/buildings.shp`` in the ``pathFile`` field *(on the right-side column)* +- Then click on ``Run Process`` after selecting one of the input/output boxes of your process + +.. figure:: images/tutorial/get_started_gui/Tutorial1_Image1bis.gif + :align: center + +Repeat this operation for the 4 other files: + +- ``resources/ground_type.shp`` +- ``resources/receivers.shp`` +- ``resources/ROADS2.shp`` +- ``resources/dem.geojson`` + +Files are uploaded to the database when the Console window displays the name of the layer. + + +.. note:: + - If you get the message ``Error opening database``, please refer to the note in Step 1. + - The process is supposed to be quick (<5 sec.). In case of a timeout, try restarting NoiseModelling (see Step 2). + - Orange blocks are mandatory + - Beige blocks are optional + - If all input blocks are optional, you must modify at least one of these blocks to be able to run the process + - Blocks get a solid border when they are ready to run + - Read the :doc:`WPS_Builder` page for more information + +Once done, you can check whether the tables were correctly imported into the database. To do so, drag/drop and execute the ``Display_Database`` WPS script (in the "Database_Manager" section). You should see on the right panel the table list (and their columns if you checked the option in the ``Display columns of the tables`` block). + +.. figure:: images/tutorial/get_started_gui/Tutorial1_display_db.png + :align: center + :width: 100% + +Step 5: Convert road traffic into noise emission sources lines +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The first step is to convert the traffic information on the roads to noise levels (vehicles per hour to an average value in dB) + +Drag & Drop the ``Road Emission from Traffic`` block into the WPS Builder window. + +Enter the name of the corresponding table in your database: + +- Roads table name: ``ROADS2`` This table contains the road geometries with traffic data for day, evening and night + +When ready, you can press ``Run Process``. + +As a result, the table ``LW_ROADS`` will be created in your database. This table contain the noise emission of your roads. The next step will run a simulation of the noise propagation to the receivers position. + +Step 6: Run Calculation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To run the calculation, drag the ``Noise_level_from_sources`` block into the WPS Builder window. + +Then, select the orange blocks and enter the name of the corresponding table in your database: + +- Building table name: ``BUILDINGS`` +- Source table name: ``LW_ROADS`` This table contains the road geometries with the noise emission values for day, evening and night +- Receivers table name: ``RECEIVERS`` Locations where noise levels are evaluated +- DEM table name: ``DEM`` Digital elevation model +- Ground absorption table: ``GROUND_TYPE`` Nature of the ground +- Diffraction on horizontal edges: ``☑`` check it (sound propagation goes over buildings) +- Maximum source-receiver distance: set ``2000`` meters (do not look for sound sources further than 2 km) +- Order of reflection: set ``0`` to disable it (faster but less accurate) + +The beige blocks correspond to optional parameters (e.g. ``DEM table name``, ``Ground absorption table name``, ``Diffraction on vertical edges``, ...). + +When ready, you can press ``Run Process``. + +.. figure:: images/tutorial/get_started_gui/Tutorial1_Image2bis.png + :align: center + +As a result, the table ``RECEIVERS_LEVEL`` will be created in your database. This table corresponds to the noise levels computed at receiver points. The column PERIOD corresponds to the 4 different periods of the day (D, E, N and DEN). + + +Step 7: Export (& see) the results +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can now export the output tables *(one by one)* in your preferred export format using the ``Export_Table`` block, giving the path of the file you want to create. + +.. warning:: + Don't forget to add the file extension (*e.g.* ``c:/home/receivers_level.geojson`` or ``c:/home/receivers_level.shp``). (Read more info about file extensions here: :doc:`Tutorials_FAQ`) + +.. figure:: images/tutorial/get_started_gui/Tutorial1_Image3.PNG + :align: center + +For example, you can export the tables in ``.shp`` format. This format can be read with most GIS tools such as the free and open-source `QGIS`_ and `SAGA`_ software. + +.. _QGIS : https://www.qgis.org/fr/site/ +.. _SAGA : http://www.saga-gis.org/en/index.html + +.. note:: + For those who are new to GIS and want to get started with QGIS, we advise you to follow `this tutorial`_. + +.. _this tutorial : https://docs.qgis.org/3.22/en/docs/training_manual/basic_map/index.html + +To obtain the following image, use the styling options in your GIS and assign a color gradient to the ``LAEQ`` column of your exported ``RECEIVERS_LEVEL`` table. + +.. figure:: images/tutorial/get_started_gui/Tutorial1_Image4.PNG + :align: center + +To display the result for a specific period, filter the rendering by the field PERIOD in QGIS. + +.. figure:: images/tutorial/get_started_gui/Tutorial1_FilterMenu.png + :align: center + + Popup menu + +.. figure:: images/tutorial/get_started_gui/Tutorial1_FilterWindow.png + :align: center + + Filter window + +.. tip:: + Now that you have made your first noise map (congratulations!), you can try again by adding or changing optional parameters to see the differences. + + +Step 8: Know the possibilities +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now that you have finished this introduction tutorial, take the time to read the description of each of the WPS blocks available in your NoiseModelling version. + +By clicking on each of the inputs or outputs, you will find a lot of information. + +.. figure:: images/tutorial/get_started_gui/Tutorial1_ImageLast.gif + :align: center diff --git a/Docs/Tutorial_Get_Started_Script.rst b/Docs/Tutorial_Get_Started_Script.rst new file mode 100644 index 000000000..6c65bf792 --- /dev/null +++ b/Docs/Tutorial_Get_Started_Script.rst @@ -0,0 +1,67 @@ +NoiseModelling client line interface (CLI) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In this tutorial, we describe the different method to pilot NoiseModelling thanks to scripts. To do so, we will use a separate command-line interface, called ``ScriptRunner``, in which the GUI has been removed (no more :doc:`WPS_Builder`). + +From that point, NoiseModelling can be executed in 3 different manners: + +#. with simple command lines +#. with Bash script +#. with Groovy script + +To illustrate, users are invited to reproduce the tutorial ":doc:`Tutorial_Get_Started_GUI`" in command lines. + +.. note:: + This tutorial is mainly dedicated to advanced users. + +.. warning:: + The URL is here adapted to Linux or Mac users. Windows user may adapt the address by replacing ``/`` by ``\`` in the folders paths. + +Requirements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. warning:: + For all users (**Linux** , **Mac** and **Windows**), please make sure your Java environment is well configured. For more information, please read the page :doc:`Tutorial_Requirements`. + + +1. Simple command line +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Using the terminal of your operating system + +Below is an example of a bash instruction, executing the :doc:`functions/Import_and_Export/Import_File` (located in the directory ``scripts/``). + +.. literalinclude:: scripts/nm_terminal.bash + :language: bash + :linenos: + +.. warning :: + Adapt ``/home/user/NoiseModelling`` address with the real installation folder of NoiseModelling. Use the appropriate ``./bin/ScriptRunner`` or ``./bin/ScriptRunner.bat`` *(depending on if you are on Linux / Mac or Windows)* file, which is located in the ``bin/`` directory. + + +2. Bash script +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Below is an example of a sequence of simple .groovy scripts, using bash instructions and launching the steps described in the ":doc:`Tutorial_Get_Started_GUI`". + +.. literalinclude:: scripts/get_started_tutorial_simple.bash + :language: bash + :linenos: + + +3. Groovy script +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Below is an example of a complex .groovy script, launching the different steps described in the ":doc:`Tutorial_Get_Started_GUI`". + +.. literalinclude:: ../noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/get_started_tutorial_complex.groovy + :language: groovy + :linenos: + +You can find this script ``get_started_tutorial_complex.groovy`` on the installation folder of NoiseModelling + +To run it use this bash command. + +.. literalinclude:: scripts/run_get_started_tutorial_complex.bash + :language: bash + :linenos: diff --git a/Docs/Matsim_Tutorial.rst b/Docs/Tutorial_Matsim.rst similarity index 55% rename from Docs/Matsim_Tutorial.rst rename to Docs/Tutorial_Matsim.rst index 91bfd8455..33d7f82cf 100644 --- a/Docs/Matsim_Tutorial.rst +++ b/Docs/Tutorial_Matsim.rst @@ -25,20 +25,21 @@ Prerequisites The data ~~~~~~~~~~~~~~~ -You can download and unzip the data in any folder from here : https://github.com/Symexpo/matsim-noisemodelling/releases/download/v5.0.0/scenario_matsim.zip +You can download and unzip the data in any folder from here: https://github.com/Universite-Gustave-Eiffel/NoiseModelling/releases/download/v5.X-Matsim-Test-Scenario/scenario_matsim.zip -The data folder should contain the following files : +The data folder should contain the following files: -- ``nantes_mini.osm.pbf`` : the Openstreetmap data of the area. We'll use it to import buildings into NoiseModelling. -- ``detailed_network.csv`` : A file containing the 'true' geometries of the road segments (called "links" in MATSim) -- ``output_events.xml.gz`` : A file containing the list of MATSim events from the simulation. -- ``output_facilities.xml.gz`` : A file containing the list of facilities, the agent's activity locations. -- ``output_network.xml.gz`` : A file containing the MATSim road network, a list of nodes and links. -- ``output_plans.xml.gz`` : A file containing the list of agents and their final planned schedule. -- ``output_experienced_plans.xml.gz`` : A file containing the list of agents and their final experienced schedule wich may differ from the inital planned one. -- ``output_persons.csv.gz`` : A file containing the simple list of agents and some of there socioeconomic characteristics +- ``nantes_mini.osm.pbf``: the Openstreetmap data of the area. We'll use it to import buildings into NoiseModelling. +- ``detailed_network.csv``: A file containing the 'true' geometries of the road segments (called "links" in MATSim) +- ``output_allVehicles.xml.gz``: A file containing the various vehicles used by the agents in the simulation. +- ``output_events.xml.gz``: A file containing the list of MATSim events from the simulation. +- ``output_facilities.xml.gz``: A file containing the list of facilities, the agent's activity locations. +- ``output_network.xml.gz``: A file containing the MATSim road network, a list of nodes and links. +- ``output_plans.xml.gz``: A file containing the list of agents and their final planned schedule. +- ``output_experienced_plans.xml.gz``: A file containing the list of agents and their final experienced schedule which may differ from the initial planned one. +- ``output_persons.csv.gz``: A file containing the simple list of agents and some of there socioeconomic characteristics -Step 1 : Import Buildings +Step 1: Import Buildings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The first thing we're going to do is to import buildings. @@ -47,29 +48,29 @@ Since we're only interested in buildings, you can also check the ``Do not import .. _2154: https://epsg.io/2154 -.. figure:: images/matsim/osm_pbf_wps.png +.. figure:: images/tutorial/matsim/osm_pbf_wps.png :align: center -You should end up with a ``BUILDINGS`` table containing the city center buildings. +You should end up with a ``BUILDINGS`` table containing the city center buildings. If you want to visualize the buildings in NoiseModelling, you can use the ``Table visualization Map`` WPS block (in the *Database Manager* section) with ``Name of the table`` set to *BUILDINGS* and ``Projection identifier`` set to *2154*. -.. figure:: images/matsim/buildings_table.png +.. figure:: images/tutorial/matsim/buildings_table.png :align: center -Step 2 : Import MATSim Traffic Data +Step 2: Import MATSim Traffic Data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Now we can import the traffic data from the MATSim simulation. To do that, we use the ``Traffic_From_Events`` WPS block. -The mandatory inputs are : +The mandatory inputs are: -- ``folder`` : the path of the MATSim folder, here it is where you put the content of the ``scenario_matsim.zip`` file +- ``folder``: the path of the MATSim folder, here it is where you put the content of the ``scenario_matsim.zip`` file An important option is ``The size of time bins in seconds`` which represents the time period you want to aggregate the traffic data over. Here let's use 900 to get data every 15 minutes. -One optional but very important input is the ``Network CSV`` file path. The idea is that when the MATSim scenario was run, the link geometries were simplified to save computation time. -This simplification of roads geometry is a bad thing for NoiseModelling since we take buidlings into account (simplified links can pass through buildings) and since source-receiver distance has a big impact on noise levels. -That's why the ``network.csv`` file is given with the other data files. It contains the "real" geometry of links before MATSim simplification process (FYI, This is obtained by setting the 'outputDetailedLinkGeometryFile' option to a file name in the ``pt2matsim`` config file). +One optional, but very important input, is the ``Network CSV`` file path option. The idea is that when the MATSim scenario was run, the link geometries were simplified to save computation time. +This simplification of roads geometry is a bad thing for NoiseModelling since we take buildings into account (simplified links can pass through buildings) and since source-receiver distance has a big impact on noise levels. +That's why the ``detailed_network.csv`` file is given with the other data files. It contains the "real" geometry of links before MATSim simplification process (FYI, This is obtained by setting the 'outputDetailedLinkGeometryFile' option to a file name in the ``pt2matsim`` config file). An other important parameter is the ``populationFactor``. This corresponds to the downscaling factor that was used to generate the list of agents. Typically, this list of agents is generated based on the available census and survey data for an administrative area. Here, for our use case, the Matsim scenario and it's agents were generated by using only 0,1% of the area total population (that is a population factor of 0.001). @@ -77,7 +78,7 @@ Here, for our use case, the Matsim scenario and it's agents were generated by us You can explore the other options by reading their descriptions. Here we are going to set them as follows: - Network CSV file: ``/path/to/your/scenario_matsim/detailed_network.csv`` -- Export additional traffic data ? : ``true`` +- Export additional traffic data ?: ``true`` - Path of the Matsim output folder: ``/path/to/your/scenario_matsim`` - populationFactor: ``0.001`` - The size of time bins in seconds: ``900`` @@ -85,41 +86,41 @@ You can explore the other options by reading their descriptions. Here we are goi - Skip unused links ?: ``true`` - Projection identifier: ``2154`` -.. figure:: images/matsim/traffic_events_wps.png +.. figure:: images/tutorial/matsim/traffic_events_wps.png :align: center You should end up with a ``MATSIM_ROADS`` table containing the links ids and their geometry and a ``MATSIM_ROADS_LW`` table containing the noise power level of each link per 15 min time slice. -.. figure:: images/matsim/roads_table.png +.. figure:: images/tutorial/matsim/roads_table.png :align: center -Step 3 : Import MATSim Activities +Step 3: Import MATSim Activities ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The next step consists in importing the activities locations from the MATSim simulation.In MATSim, activities are also called facilities. -Let's use the ``Import_Activities`` WPS bloc. The inputs descriptions are quite straightforward : +Let's use the ``Import_Activities`` WPS bloc. The inputs descriptions are quite straightforward: - Name of created table: ``ACTIVITIES`` - Projection identifier: ``2154`` - Path of MatSim facilities file: ``/path/to/your/scenario_mastim/output_facilities.xml.gz`` -.. figure:: images/matsim/import_activities_wps.png +.. figure:: images/tutorial/matsim/import_activities_wps.png :align: center You should end up with a ``ACTIVITIES`` table containing the activities location, and few other properties. -.. figure:: images/matsim/activities_table.png +.. figure:: images/tutorial/matsim/activities_table.png :align: center -Step 4 : Assign a Receiver to each Activity +Step 4: Assign a Receiver to each Activity ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Now, if you look closely, activities are placed in unorthodox locations, sometimes in the river, sometimes in buildings, etc. This is irrelevant for a MATSim simulation but here we want to calculate noise levels, so we need properly placed receivers. -So we want to assign a properly placed receiver for every activity we imported. We do that in 2 steps : +So we want to assign a properly placed receiver for every activity we imported. We do that in 2 steps: 1. we calculate all the "valid" receiver positions using the ``Building_Grid`` WPS bloc 2. we choose, for each activity the right receiver. @@ -129,13 +130,13 @@ Or we can randomly choose a receiver on the closest building of each activity us Here we are going to use the latter way, the random one. -Let's calculate all the receivers around our buildings using the ``Building_Grid`` WPS bloc with the following inputs : +Let's calculate all the receivers around our buildings using the ``Building_Grid`` WPS bloc with the following inputs: -- Buildings table table : ``BUILDINGS`` -- Distance between receivers : ``5.0`` -- Height : ``4.0`` +- Buildings table table: ``BUILDINGS`` +- Distance between receivers: ``5.0`` +- Height: ``4.0`` -That will place receviers around all the buildings, at 4 meter high and 5 meters apart. +That will place receivers around all the buildings, at 4 meter high and 5 meters apart. Now, we must use the ``Receivers_From_Activity_Random`` WPS bloc. The inputs are simple, you just have to specify the names of the previously created tables @@ -144,81 +145,42 @@ Now, we must use the ``Receivers_From_Activity_Random`` WPS bloc. The inputs are - Name of the table containing the buildings: ``BUILDINGS`` - Name of the table containing the receivers: ``RECEIVERS`` -.. figure:: images/matsim/receiver_activities_wps.png +.. figure:: images/tutorial/matsim/receiver_activities_wps.png :align: center -You should end up with a ``ACTIVITY_RECEIVERS`` table containing the new location (``THE_GEOM``, in blue below) as well as the orignal matsim position (``ORIGIN_GEOM``, in red below). +You should end up with a ``ACTIVITY_RECEIVERS`` table containing the new location (``THE_GEOM``, in blue below) as well as the original matsim position (``ORIGIN_GEOM``, in red below). You can inspect the results to see where each activity is placed now. -.. figure:: images/matsim/activity_receivers_table.png +.. figure:: images/tutorial/matsim/activity_receivers_table.png :align: center -Step 5 : Calculate Noise Attenuation Matrix +Step 5: Calculate Noise Receiver Levels ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In this step, we want to calculate and store the noise propagation part of NoiseModelling. -We need this because we actually have several power spectrum for every road segment, one for every timestep of 15min. -In the end we want to have a noise map every 15 minutes (96 maps in total). If we do that directly, by calling something like ``Noise_level_from_source`` WPS bloc 96 times, we would be calculating the exact same noise propagation 96 times. +In this step, we want to calculate a noise level for every receiver, every 15 minutes (96 maps in total). -So the process is as follows : - -1. we use the ``MATSIM_ROADS`` table as a SOURCE table. It only contains geometries, without any power levels, so the ``Noise_level_from_source`` bloc will compute acoustic attenuation by virtually attributing a power level of 0dB for every road link. -2. We use the ``Noise_level_from_source`` WPS bloc and setting the ``confExportSourceId`` input paramter. - -The ``confExportSourceId`` parameter will actually ouput, for every recevier, the list of sources that contribute to the resulting levels, with the source-receiver noise attenuation. - -We'll then use this attenuation matrix in the next steps to get the 96 noise maps. - -Calculate the attenuation matrix ----------------------------------- +We'll use the ``Noise_level_from_source`` WPS bloc. When the using the ``Sources emission table name``, the WPS bloc will automatically take into account the time bins defined in the emission table. +For more details about the different parameters, browse the NoiseModelling general documentation. Let's use the previously generated table to launch our propagation calculation. -As explained before, we'll use the ``Noise_level_from_source`` WPS bloc with the ``Separate receiver level by source identifier`` parameter enabled. -For more details about the different parameters, browse the NoiseModelling general documentation. - -The parameters we will use are the following : +The parameters we will use are the following: - Buildings table name: ``BUILDINGS`` - Receivers table name: ``ACTIVITY_RECEIVERS`` -- Sources table name: ``MATSIM_ROADS`` +- Sources geometry table name: ``MATSIM_ROADS`` +- Sources emission table name: ``MATSIM_ROADS_LW`` - Maximum source-receiver distance: ``250`` - Maximum source reflexion distance: ``50`` - Order of reflexion: ``1`` -- Separate receiver level by source identifier: ``true`` - Diffraction on vertical edges: ``false`` - Diffraction on horizontal edges: ``true`` -.. figure:: images/matsim/noise_from_source_wps.png - :align: center - -We should end up with a table called ``RECEIVERS_LEVEL`` that contains a list of contributing source attenuation for every receiver. -We can see such a list for the receiver n°1 in the figure below: - -.. figure:: images/matsim/lday_geom_table.png - :align: center - - -Step 6 : Calculate Noise Maps -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -We have noise power levels every 15 minutes in the ``MATSIM_ROADS_LW`` table, and a source-receiver noise attenuation matrix in the ``RECEIVERS_LEVEL`` table. -We just need to combine the two to get receivers noise levels every 15 minutes. - -This is the purpose of the ``Noise_From_Attenuation_Matrix_MatSim`` WPS bloc. -We just have set the right tables as input as follows : - -- Attenuation matrix table name: ``RECEIVERS_LEVEL`` -- Output table name: ``RESULT_GEOM`` -- Table name of the MATSIM table containing the roads LW stats per timeBin: ``MATSIM_ROADS_LW`` -- Table name of the MATSIM table containing the roads geometries: ``MATSIM_ROADS`` -- Table name of the MATSIM table containing the receivers: ``ACTIVITY_RECEIVERS`` - -.. figure:: images/matsim/noise_from_attenuation_wps.png +.. figure:: images/tutorial/matsim/noise_from_source_wps.png :align: center -It takes some time but in the end you should get a noise spectrum for every receiver every 15 minutes in the table ``RESULT_GEOM``. +We should end up with a table called ``RECEIVERS_LEVEL`` that contains a list of noise levels for every receiver, at every 15-minute interval. We have our noise maps ! @@ -230,13 +192,13 @@ Export the data Here we'll look at a nice way to look at the results with QGIS. -First we need to export the ``RESULT_GEOM`` table data into a Shapefile. -We'll simply use the ``Export_Table WPS`` bloc with the following parameters : +First we need to export the ``RECEIVERS_LEVEL`` table data into a Shapefile. +We'll simply use the ``Export_Table WPS`` bloc with the following parameters: -- Name of the table: ``RESULT_GEOM`` +- Name of the table: ``RECEIVERS_LEVEL`` - Path of the file you want to export: ``/path/to/wherever/results.shp`` -.. figure:: images/matsim/results_export_wps.png +.. figure:: images/tutorial/matsim/results_export_wps.png :align: center View it in QGIS @@ -245,7 +207,7 @@ View it in QGIS .. role:: raw-html(raw) :format: html -Let's go into QGIS. We are going to import 2 layers : an osm background and our results. +Let's go into QGIS. We are going to import 2 layers: an osm background and our results. .. note:: For those who are new to GIS and want to get started with QGIS, we advise you to follow `this tutorial`_ as a start. @@ -257,22 +219,22 @@ Let's go into QGIS. We are going to import 2 layers : an osm background and our You should see a lot of points all of the same color. -We now need to choose a timeslice we want to visualize, let's pick the timeBin of 10h (36000 seconds). +We now need to choose a time-slice we want to visualize, let's pick the timeBin of 10h (36000 seconds). If you right click on the receivers layer and click on ``Filter...`` you should see the filter dialog. To filter results for the 10h00_10h15 time period you can enter the following filter query : - ``TIME = 36000`` + ``PERIOD = 36000`` The last step is to color the dots based on the LEQA field. -Here is my configuration : +The following configuration can be used: -.. figure:: images/matsim/symbology_results_qgis.png +.. figure:: images/tutorial/matsim/symbology_results_qgis.png :align: center -And the final result, between 10h00 and 10h15 : +And the final result, between 10h00 and 10h15: -.. figure:: images/matsim/results_10h_qgis.png +.. figure:: images/tutorial/matsim/results_10h_qgis.png :align: center @@ -282,11 +244,11 @@ Going Further Now maybe we just want to compute actual noise maps instead of just the noise levels at some specific points. In this case we'd want to use a different receiver grid using the ``Delaunay_Grid`` WPS bloc. -Then we can use the same ``Noise_level_from_source`` and ``Noise_From_Attenuation_Matrix_MatSim`` WPS blocs to calculate the noise levels at every receiver at every timestep. +Then we can use the same ``Noise_level_from_source`` WPS blocs to calculate the noise levels at every receiver at every timestep. -If you then select a specific timeBin you can then run a ``Create_Isosurface`` WPS bloc to create a noise map. +You can then run a ``Create_Isosurface`` WPS bloc to create a noise map, it will also automatically detect the PERIOD and produce one noise map per time bin. -Here is an example of a noise map for the 10h00_10h15 time period : +Here is an example of a noise map for the 10h to 10h15 time period: -.. figure:: images/matsim/map_10h_qgis.png +.. figure:: images/tutorial/matsim/map_10h_qgis.png :align: center diff --git a/Docs/Noise_Map_From_OSM_Tutorial.rst b/Docs/Tutorial_Noise_Map_From_OSM.rst similarity index 80% rename from Docs/Noise_Map_From_OSM_Tutorial.rst rename to Docs/Tutorial_Noise_Map_From_OSM.rst index 5a99f08c0..c035f18e6 100644 --- a/Docs/Noise_Map_From_OSM_Tutorial.rst +++ b/Docs/Tutorial_Noise_Map_From_OSM.rst @@ -1,7 +1,7 @@ Noise Map from OSM - GUI ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In this tutorial, we are going to produce a noise map, using `OpenStreetMap`_ (OSM) data. The exercice will be made through NoiseModelling with Graphic User Interface (GUI). +In this tutorial, we are going to produce a noise map, using `OpenStreetMap`_ (OSM) data. The exercise will be made through NoiseModelling with Graphic User Interface (GUI). .. _OpenStreetMap : https://www.openstreetmap.org/ @@ -10,10 +10,10 @@ Prerequisites ~~~~~~~~~~~~~~~~~ * You need at least NoiseModelling v.3.0.6; the best is always to use last release -* We assume you already installed/configured Java and installed NoiseModelling. If not, follow Step 1 in ":doc:`Get_Started_GUI`" page +* We assume you already installed/configured Java and installed NoiseModelling. If not, follow Step 1 in ":doc:`Tutorial_Get_Started_GUI`" page .. warning:: - If you have just finished the ":doc:`Get_Started_GUI`" tutorial, please clean your database with the WPS block ``Clean_Database``. Don't forget to check the ``Are you sure`` check box before running the process. + If you have just finished the ":doc:`Tutorial_Get_Started_GUI`" tutorial, please clean your database with the WPS block ``Clean_Database``. Don't forget to check the ``Are you sure`` check box before running the process. Step 1: Get OSM data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -43,7 +43,7 @@ In the email you will receive from BBBike, use the link to download your data. Y To avoid potential upcoming errors rename the file ``planet_xx.xx,xx.xx.osm.pbf`` to something simpler (*e.g.* ``my_area.osm.pbf``). .. note:: - Developped by `Wolfram Schneider`_, BBBike is a free of charge service (for non-professional purpose). If you like Wolfram's job and wants to help him support the server costs, you are invited to `donate`_. + Developed by `Wolfram Schneider`_, BBBike is a free of charge service (for non-professional purpose). If you like Wolfram's job and wants to help him support the server costs, you are invited to `donate`_. .. _Wolfram Schneider : https://wolfram.schneider.org/ .. _donate : https://extract.bbbike.org/community.html#donate @@ -54,8 +54,8 @@ Import to the database To import the ``.pbf`` file into the NoiseModelling database, we use the ``Import_OSM`` WPS block (note that this block also allows to load ``.osm`` or ``.osm.gz`` files). #. ``Target projection identifier``: enter the corresponding SRID *(see note below)* (*e.g.* ``2154`` for french Lambert 93) -#. ``Path of the OSM file``: enter the adress of your ``my_area.osm.pbf`` file (*e.g.* ``/home/noisemodelling/my_area.osm.pbf``) -#. If needeed, check the 4 other optionnal options +#. ``Path of the OSM file``: enter the address of your ``my_area.osm.pbf`` file (*e.g.* ``/home/noisemodelling/my_area.osm.pbf``) +#. If needed, check the 4 other optional options #. When ready, click on the green ``Run Process`` button Once done, three tables must be created: ``BUILDINGS``, ``GROUND`` and ``ROADS`` @@ -97,13 +97,13 @@ Export tables into files * Export a table: It is also possible to export the tables via ``Export_Table`` WPS script, in Shapefile, CSV or GeoJSON format. -* View the files: Then open these files into your preferred Geographic Information System (*e.g* `QGIS`_, `OrbisGIS`_, ...). You can then graphically visualize your geometries layer, but also the data contained in it. Take the time to familiarize yourself with your chosen GIS. +* View the files: Then open these files into your preferred Geographic Information System (*e.g* `QGIS`_, `OpenJUMP`_, ...). You can then graphically visualize your geometries layer, but also the data contained in it. Take the time to familiarize yourself with your chosen GIS. * Add a background map: Most of the GIS allow you to add an `WMS`_ OSM `background map`_: (see an `example with QGIS`_) * Change colors: Most of the GIS allow you to change layer colors (*e.g.* ``GROUND`` layer in green, ``BUILDINGS`` in gray, ``ROADS`` in red). -.. _OrbisGIS: http://orbisgis.org/ +.. _OpenJUMP: https://github.com/openjump-gis/openjump .. _QGIS: http://qgis.org/ .. _WMS : https://www.ogc.org/standards/wms .. _background map : https://wiki.openstreetmap.org/wiki/Tile_servers @@ -115,7 +115,7 @@ Step 3: Generate a Receiver table The locations of noise level evaluation points needs to be defined. -Use ``Delaunay_Grid`` with the previously generated BUILDINGS table as the buildings table and ROADS as *Sources table name*. +Use :doc:`functions/Receivers/Delaunay_Grid`` with the previously generated ``BUILDINGS`` table as the buildings table and ``ROADS`` as *Sources table name*. Other parameters are optional. Don't forget to view your resulting layer in ``WPSBuilder`` or in your GIS to check that it meets your expectations. @@ -126,7 +126,7 @@ This processing block will give the possibility to generate a noise map later. Step 4: Associate emission noise level with roads ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``Road_Emission_from_Traffic`` block is used to generate a road layer, called ``LW_ROADS``, containing LW emission noise level values in accordance with the emission laws of the CNOSSOS model. The format of the input road layer can be found in the description of the WPS Block. +The :doc:`functions/NoiseModelling/Road_Emission_from_Traffic` block is used to generate a road layer, called ``LW_ROADS``, containing LW emission noise level values in accordance with the emission laws of the CNOSSOS model. The format of the input road layer can be found in the description of the WPS Block. Don't forget to view your resulting layers *(see Step 2)* to check that it meets your expectations. @@ -134,13 +134,13 @@ Don't forget to view your resulting layers *(see Step 2)* to check that it meets Step 5: Source to Receiver Propagation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``Noise_level_from_source`` block allows to generate a layer of receiver points with associated sound levels corresponding to the sound level emitted by the sources (created table ``LW_ROADS``) propagated to the receivers according to the CNOSSOS-EU. propagation laws. +The :doc:`functions/NoiseModelling/Noise_level_from_source` block allows to generate a layer of receiver points with associated sound levels corresponding to the sound level emitted by the sources (use the created table ``LW_ROADS`` as *Source geometry table name*) propagated to the receivers according to the CNOSSOS-EU. propagation laws. Step 6: Create Isosurfaces map ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Create an interpolation of levels between receivers points using the block ``Create_Isosurface``. +Create an interpolation of levels between receivers points using the block :doc:`functions/Acoustic_Tools/Create_Isosurface`. Set ``RECEIVERS_LEVEL`` as ``Name of the noise table``. @@ -158,5 +158,5 @@ You can view this layer in your favorite GIS. Drop the file in QGIS then filter You can then apply a (revert) color gradient on ``ISOLABEL`` field. -.. figure:: images/tutorial/Tutorial2_ContouringNoiseMap.png +.. figure:: images/tutorial/Noise_Map_From_OSM/Tutorial2_ContouringNoiseMap.png :align: center diff --git a/Docs/Noise_Map_From_Point_Source.rst b/Docs/Tutorial_Noise_Map_From_Point_Source.rst similarity index 80% rename from Docs/Noise_Map_From_Point_Source.rst rename to Docs/Tutorial_Noise_Map_From_Point_Source.rst index e7d5afb7a..6fa6fb3cb 100644 --- a/Docs/Noise_Map_From_Point_Source.rst +++ b/Docs/Tutorial_Noise_Map_From_Point_Source.rst @@ -1,9 +1,9 @@ Noise Map from Point Source - GUI ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In this tutorial, we are going to produce a noise map, based on a unique source point. The exercice will be made through NoiseModelling with Graphic User Interface (GUI). +In this tutorial, we are going to produce a noise map, based on a unique source point. The exercise will be made through NoiseModelling with Graphic User Interface (GUI). -To make it more simple, we will use the data used in the :doc:`Get_Started_GUI` tutorial. +To make it more simple, we will use the data used in the :doc:`Tutorial_Get_Started_GUI` tutorial. This tutorial is divided in 5 steps: @@ -28,11 +28,11 @@ To create the source point, we will use the free and opensource GIS software `QG Load data into QGIS ------------------------- -Once installed, launch QGIS and load the three ``buildings.shp``, ``roads.shp`` and ``ground_type.shp`` files (that are in the folder ``../NoiseModelling_5.0.0/data_dir/data/wpsdata/``). To do so, you can just drag & drop these files into the ``Layers`` menu (bottom left of the user interface). Or you can also select them thanks to the dedicated panel opened via the ``Layer / Add a layer / Add a vectorial layer... /`` menu (or use ``Ctrl+Maj+V`` shortcut) +Once installed, launch QGIS and load the three ``buildings.shp``, ``roads.shp`` and ``ground_type.shp`` files (that are in the folder ``../NoiseModelling/resources/``). To do so, you can just drag & drop these files into the ``Layers`` menu (bottom left of the user interface). Or you can also select them thanks to the dedicated panel opened via the ``Layer / Add a layer / Add a vectorial layer... /`` menu (or use ``Ctrl+Maj+V`` shortcut) You should see your input data in the map as below: -.. figure:: images/Noise_Map_From_Point_Source/load_data_qgis.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/load_data_qgis.png :align: center Initialize the source point layer @@ -62,7 +62,7 @@ Once done, click on ``Add to Fields List``. Then redo this step with the followi You should have something like this -.. figure:: images/Noise_Map_From_Point_Source/create_source_point_layer.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/create_source_point_layer.png :align: center Once done, click on ``OK`` button. The new layer ``Point_Source`` should appear in your ``Layers`` panel. @@ -73,19 +73,19 @@ Add a new source point Now we have an empty layer. It's time to feed it with a point geometry. -By default, the new temporary layer is already turned into edtion mode. If not, you can activate it thanks to these two options: +By default, the new temporary layer is already turned into edition mode. If not, you can activate it thanks to these two options: * In the ``Layers`` panel, select the ``Point_Source`` layer and make a right-click. Choose ``Toggle Editing`` * or you can click on the "Yellow pencil" icon in the toolbar -.. figure:: images/Noise_Map_From_Point_Source/edit_layer_source.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/edit_layer_source.png :align: center Now we can add a new point, by clicking on the dedicated icon (see illustration below) and then by clicking somewhere in the map. To have an interesting resulting noise map, choose to place your source point next to buildings. -.. figure:: images/Noise_Map_From_Point_Source/place_point_source.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/place_point_source.png :align: center Click on the map where you want to create the source point. Once clicked, a new dialog appears and you are invited to fill the following attributes: @@ -93,22 +93,22 @@ Click on the map where you want to create the source point. Once clicked, a new * ``PK``: 1 * ``HZD500`` : 90 -.. figure:: images/Noise_Map_From_Point_Source/fill_attributes.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/fill_attributes.png :align: center Once done, click on ``OK``. The source point is now visible in the map (the blue point in the illustration below). -.. figure:: images/Noise_Map_From_Point_Source/layer_source.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/layer_source.png :align: center Now, we have to save this temporary layer into a flat file. To do so, just make a right-click on the layer name and choose the ``Make permanent`` option. -.. figure:: images/Noise_Map_From_Point_Source/convert_point_source_geojson.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/convert_point_source_geojson.png :align: center In the new dialog, select ``GeoJSON`` file format and then define the path and the name of your resulting .geojson file. Press ``OK`` when ready. -.. figure:: images/Noise_Map_From_Point_Source/save_geojson.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/save_geojson.png :align: center Your ``Point_Source.geojson`` file is now ready to be imported in NoiseModelling. @@ -130,11 +130,11 @@ For your information, you can open ``.geojson`` files in most of text editor. If Step 2: Import input data in NoiseModelling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once NoiseModelling is launched (see ``Step 2: Start NoiseModelling GUI`` in :doc:`Get_Started_GUI` page), load the four ``BUILDINGS``, ``ROADS`` and ``GROUND_TYPE``, ``POINT_SOURCE`` layers (see ``Step 4: Load input files`` for more details). +Once NoiseModelling is launched (see ``Step 2: Start NoiseModelling GUI`` in :doc:`Tutorial_Get_Started_GUI` page), load the four ``BUILDINGS``, ``ROADS`` and ``GROUND_TYPE``, ``POINT_SOURCE`` layers (see ``Step 4: Load input files`` for more details). If you use the ``Database_Manager:Display_Database`` WPS script, you should see your four tables like below: -.. figure:: images/Noise_Map_From_Point_Source/table_list_NM.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/table_list_NM.png :align: center Step 3: Generate the noise map @@ -150,9 +150,9 @@ Use the ``Receivers:Delaunay_Grid`` WPS script. Fill the two following mandatory * ``Source table name`` : ``POINT_SOURCE`` * ``Buildings table name`` : ``BUILDINGS`` -Once done, you should have two new tables : ``RECEIVERS`` *(illustrated below with the purple small points)* and ``TRIANGLES`` +Once done, you should have a new table : ``RECEIVERS`` *(illustrated below with the purple small points)* -.. figure:: images/Noise_Map_From_Point_Source/table_receivers.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/table_receivers.png :align: center Calculate noise levels @@ -166,7 +166,7 @@ Use the ``NoiseModelling:Noise_level_from_source`` WPS script. Fill the three fo Once ready, click on ``Run Process`` button. -You should then have this message: ``Calculation Done ! RECEIVERS_LEVEL table(s) have been created.`` +A new table ``RECEIVERS_LEVEL`` is created. Generate noise level isosurfaces ---------------------------------- @@ -175,21 +175,21 @@ Use the ``Acoustic_Tools:Create_Isosurface`` WPS script. Fill the following mand * ``Sound levels table`` : ``RECEIVERS_LEVEL`` -You should have this message: ``Table CONTOURING_NOISE_MAP created`` +A new table ``CONTOURING_NOISE_MAP`` is created. Now, you can export this table into a .shapefile, using the ``Import_and_Export:Export_Table`` WPS script. -You can then visualize this file into QGIS *(just load the file as seen before)*. The resulting table *(in grey)* is illustred below +You can then visualize this file into QGIS *(just load the file as seen before)*. The resulting table *(in grey)* is illustrated below -.. figure:: images/Noise_Map_From_Point_Source/table_contouring.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/table_contouring.png :align: center Filter the table according to a single period (ex. DEN): -.. figure:: images/tutorial/Tutorial1_FilterMenu.png +.. figure:: images/tutorial/get_started_gui/Tutorial1_FilterMenu.png :align: center -.. figure:: images/tutorial/Tutorial1_FilterWindow.png +.. figure:: images/tutorial/get_started_gui/Tutorial1_FilterWindow.png :align: center @@ -198,7 +198,7 @@ Apply a color palette adapted to acoustics In QGIS, since the isosurface table is not easy to read *(everything is grey in our example)*, we will change the color palette to have colors depending on the noise levels. This information is present in the field ``ISOLVL`` in the attributes table. To open it, just select the layer ``CONTOURING_NOISE_MAP`` and press ``F6``. -.. figure:: images/Noise_Map_From_Point_Source/contouring.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/contouring.png :align: center To adapt the colors, we will apply a cartographic style. This style: @@ -219,17 +219,17 @@ To adapt the colors, we will apply a cartographic style. This style: Once downloaded, make a double click on the layer ``CONTOURING_NOISE_MAP``. It will opens the property panel. Here, click on the ``Symbology`` tab. In the ``Style`` menu *(at the bottom)*, choose ``Load style``. Then in the opened dialog, click on the ``...`` icon to search the ``style_beate_tomio.sld`` file. Once selected, click on ``Load style``. -.. figure:: images/Noise_Map_From_Point_Source/style_sld.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/style_sld.png :align: center The style with its different colors is now displayed. -.. figure:: images/Noise_Map_From_Point_Source/style_scale.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/style_scale.png :align: center Press ``OK`` to apply and close the dialog. Your noise map is now well colorized and you can navigate into it to see the influence of buildings on noise levels. -.. figure:: images/Noise_Map_From_Point_Source/style_map.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/style_map.png :align: center @@ -239,9 +239,9 @@ Step 4: Change the default parameters To produce this noise map, we used, in most of WPS scripts, default parameters (*e.g* the height of the source, the number of reflections, the air temperature, …). You are prompted to redo some of the previous steps by changing some of the settings. You will then be able to visually see what impact they have on the final noise map. .. note:: - To change optionnal parameters *(the yellow boxes)* just select them and fill the needed informations in the right-side menu. + To change optional parameters *(the yellow boxes)* just select them and fill the needed information in the right-side menu. -.. figure:: images/Noise_Map_From_Point_Source/change_parameters.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/change_parameters.png :align: center Step 5 (bonus): Change the directivity @@ -276,7 +276,7 @@ Each of the sound sources has its own directivity. For the exercise we will use Below is an illustration generated from train directivity formula. -.. figure:: images/Noise_Map_From_Point_Source/directivity_rail.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/directivity_rail.png :align: center @@ -306,7 +306,7 @@ To play with directivity, we need to add 4 fields in the source point table: * ``Type`` : Integer * ``Length`` : 2 -.. figure:: images/Noise_Map_From_Point_Source/yaw_pitch_roll.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/yaw_pitch_roll.png :align: center .. note:: @@ -328,7 +328,7 @@ by { "PK": 1, "HZD500": 100.0, "YAW": 45, "PITCH": 0, "ROLL": 0, "DIR_ID" : 1 } -Here we can see that the Yaw is setted to 45°. Pitch and Roll are equal to 0, and the directivity is defined as ``1`` and will refer to the directivy table (see below). +Here we can see that the Yaw is set to 45°. Pitch and Roll are equal to 0, and the directivity is defined as ``1`` and will refer to the directivity table (see below). So your final .geojson file should look like this @@ -349,11 +349,11 @@ Import data Now, in NoiseModelling we have to: -* Import the ``Directivy.csv`` file +* Import the ``Directivity.csv`` file * Reimport the ``Point_Source.geojson`` file in order to take into account the changes -* Import the ``dem.geojson`` file, which is placed here ``./NoiseModelling_5.0.0/data_dir/data/wpsdata/dem.geojson``. By taking into account the ground elevation, this file will help us to get better results. +* Import the ``dem.geojson`` file, which is placed here ``resources/dem.geojson``. By taking into account the ground elevation, this file will help us to get better results. -To do so, just use the ``Import_and_Export:Import_Table`` WPS script. +To do so, just use the ``Import and Export:Import file`` WPS script. Generate the Delaunay triangulation @@ -396,5 +396,5 @@ Use the ``Import_and_Export:Export_Table`` WPS script to export the ``CONTOURING Then, load ``CONTOURING_NOISE_MAP_DIRECTIVITY.shp`` into QGIS and filter the period to ``DEN``. Apply the ``noisemap_style.sld`` style, and compare with ``CONTOURING_NOISE_MAP.shp`` produced in Step 3. -.. figure:: images/Noise_Map_From_Point_Source/contouring_directivity_compare.png +.. figure:: images/tutorial/Noise_Map_From_Point_Source/contouring_directivity_compare.png :align: center diff --git a/Docs/Tutorial_Requirements.rst b/Docs/Tutorial_Requirements.rst new file mode 100644 index 000000000..1a5803341 --- /dev/null +++ b/Docs/Tutorial_Requirements.rst @@ -0,0 +1,75 @@ +Requirements +^^^^^^^^^^^^^^^^^ + +Java environment +~~~~~~~~~~~~~~~~~~~~ + +Since NoiseModelling is developed with the `Java langage`_, you will need to install the Java Runtime Environment (JRE) on your computer to use the application. + +NoiseModelling requires Java >= 11. Any version of Java 11 or later is supported. + +.. _Java langage : https://en.wikipedia.org/wiki/Java_(programming_language) + +Windows +---------- + +If you are launching NoiseModelling thanks to the ``NoiseModelling_xxx_install.exe`` file, the JRE is already inside, so **you don't have anything to do**. + +If you are not using the ``.exe`` file, you have to launch NoiseModelling thanks to the ```start_windows.bat`` file (in the ``NoiseModelling_xxx.zip`` release file). In this case, Java >= 11 has to be installed before. + +Download and install Java: choose between `OpenJDK`_ or `Oracle`_ versions. + +.. _this document : https://confluence.atlassian.com/doc/setting-the-java_home-variable-in-windows-8895.html + + +Linux or Mac +------------- + +If not already done, you have to install the Java version >= 11. + +#. Check whether Java is already installed:: + + java -version + + The command should print a version starting with ``11``. Otherwise, install Java first. + +#. Download and install Java: choose between `OpenJDK`_ or `Oracle`_ versions. + +#. Find the installation path to use for ``JAVA_HOME``. + + *On Linux*:: + + readlink -f "$(command -v java)" + + This prints a path ending with ``/bin/java`` (for example + ``/usr/lib/jvm/java-22-openjdk-amd64/bin/java``); ``JAVA_HOME`` is the parent + directory of ``bin`` (here ``/usr/lib/jvm/java-22-openjdk-amd64``). + + *On macOS*:: + + /usr/libexec/java_home -v latest + + This prints the directory that must be used as ``JAVA_HOME`` for Java. + +#. Set the ``JAVA_HOME`` environment variable and update your ``PATH`` (adapt the + path with the one found above):: + + export JAVA_HOME=/usr/lib/jvm/java-22-openjdk-amd64 + export PATH="$JAVA_HOME/bin:$PATH" + + On macOS you can also use:: + + export JAVA_HOME=$(/usr/libexec/java_home -v latest) + export PATH="$JAVA_HOME/bin:$PATH" + +#. Verify that ``JAVA_HOME`` is correctly set:: + + echo $JAVA_HOME + + You should get the Java directory (for example + ``/usr/lib/jvm/java-22-openjdk-amd64``). If this is not the case, you are + invited to follow the steps `proposed here`_. + +.. _proposed here: https://stackoverflow.com/questions/24641536/how-to-set-java-home-in-linux-for-all-users +.. _OpenJDK : https://www.azul.com/downloads/ +.. _Oracle : https://www.oracle.com/java/technologies/downloads/ diff --git a/Docs/Validation.rst b/Docs/Validation.rst index 86d7a07ee..aae512d39 100644 --- a/Docs/Validation.rst +++ b/Docs/Validation.rst @@ -63,10 +63,10 @@ Note that all the tests entilted ``TCxx`` (`see example`_) are coming from the ` .. _CNOSSOS-EU: https://circabc.europa.eu/sd/a/9566c5b9-8607-4118-8427-906dab7632e2/Directive_2015_996_EN.pdfde -.. _code: https://github.com/Ifsttar/NoiseModelling/ +.. _code: https://github.com/Universite-Gustave-Eiffel/NoiseModelling/ -.. _here: https://github.com/Ifsttar/NoiseModelling/blob/4.X/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/EvaluateAttenuationCnossosTest.java +.. _here: https://github.com/Universite-Gustave-Eiffel/NoiseModelling/blob/4.X/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/EvaluateAttenuationCnossosTest.java -.. _see example: https://github.com/Ifsttar/NoiseModelling/blob/621ec99568ac14d72ef78557cfc2ee910a72c138/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/EvaluateAttenuationCnossosTest.java#L453 +.. _see example: https://github.com/Universite-Gustave-Eiffel/NoiseModelling/blob/621ec99568ac14d72ef78557cfc2ee910a72c138/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/EvaluateAttenuationCnossosTest.java#L453 .. _ISO/TR 17534-4:2020 : https://www.iso.org/standard/72115.html \ No newline at end of file diff --git a/Docs/WPS_Blocks.rst b/Docs/WPS_Blocks.rst index c61a2fb98..dcb43d5fb 100644 --- a/Docs/WPS_Blocks.rst +++ b/Docs/WPS_Blocks.rst @@ -12,9 +12,9 @@ The WPS standard defines how a client can request the execution of a process, an NoiseModelling and WPS ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Since release v.3.0.0, NoiseModelling comes with various WPS scripts, encapsulated in so-called blocks. These blocks, written in `Groovy`_ language, are executed thanks to the `GeoServer`_ WPS engine. +Since release v.3.0.0, NoiseModelling comes with various WPS scripts, encapsulated in so-called blocks. These blocks, written in `Groovy`_ script language. -Physically stored as ``.groovy`` files *(openable in any text editor)*, they are located in the ``NoiseModelling\\data_dir\\scripts\\wps\\`` directory. +Physically stored as ``.groovy`` files *(openable in any text editor)*, they are located in the ``NoiseModelling/scripts`` directory. .. tip:: To know the functionality of each WPS block, wait a few moments with your mouse on the block, a tooltip text will appear. @@ -22,13 +22,10 @@ Physically stored as ``.groovy`` files *(openable in any text editor)*, they are .. note:: With each new version, new blocks are added. Be curious and check out the latest version! - -.. _Geoserver: https://geoserver.org/ .. _Groovy: https://groovy-lang.org/ Create your own WPS block ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Please see `Advanced Users Section`_, because now you want to be one! +Please see :doc:`Own_Wps`, because now you want to be one! -.. _Advanced Users Section : Own_Wps diff --git a/Docs/WPS_Builder.rst b/Docs/WPS_Builder.rst index d5f1c7d98..0c6a79c71 100644 --- a/Docs/WPS_Builder.rst +++ b/Docs/WPS_Builder.rst @@ -5,7 +5,7 @@ What is WPS Builder ? ~~~~~~~~~~~~~~~~~~~~~~~~~~~ WPS Builder allows to creates graphical process workflows that can be easily executed and reproduced. It allows Web Processing Services to operate through a user interface. -We have developed a version of WPS Builder adapted to the needs of NoiseModelling. This version being very close to the original version initially developped by former Boundlessgeo company. +We have developed a version of WPS Builder adapted to the needs of NoiseModelling. This version being very close to `the original version initially developed by former BoundlessGEO company `_. Frequently Asked Question @@ -16,41 +16,61 @@ What do the colors correspond to? --------------------------------- - Orange block are mandatory - Beige blocks are optional -- Green block are unfortunately useless *(not due to NoiseModelling)* -- Blocks get solid border when they are ready +- Green block are the output of the process* +- Blocks get solid border when they are ready/filled Can I save my WPS Builder project? ------------------------------------ Yes. To save your WPS Builder project you two possibilities: -#. Save in the local browser storage -#. Export into a JSON file +#. Export the blocks state into a JSON file +#. Export the blocks state and the whole database into a zip file (limited to 500 MB database) -1. Local browser -***************** -Click on the ``File`` icon and then choose ``Save to local browser storage``. This way, your working environment will saved in the memory of your web browser. +1. Export/Import the blocks state +********************************* -Once you restart NoiseModelling, you can reload this environment by clicking on ``File / Open from local browser storage`` - -2. Export into JSON -******************** - -Click on the ``File`` icon and then choose ``Export to clipboard``. In the opening panel, you have a JSON text that you can copy / paste and save into a ```.txt`` or ``json`` file. +Click on the ``File`` icon and then choose ``Save project``. The browser will save the file in your download folder. .. figure:: images/WPS_Builder/export_clipboard.png :align: center :width: 75% -Once you restart NoiseModelling, you can reload this environment by clicking on ``File / Import clipboard``. In the opening panel, paste your JSON text and click ``Ok``. +Once you want to recover the saved state, click on ``File / Open project`` and select the saved file. +2. Export/Import the database +***************************** -Why everything is wrong when I use "Enter"? ---------------------------------------------- +Click on the ``File`` icon and then choose ``Save project with database``. The browser will save the file in your download folder. -Don't click on your ``Enter`` keyboard key, it refreshes web page. - -I can't link process block between them? +How to run multiple processing at once ? ---------------------------------------- -It is normal... this feature has not yet been implemented! +You can use the output of a processing block (like ``Import File``) as the input of another process. To do this keep the left button of your mouse down while dragging the white square on the right side of a green output block to the left white square of the input of another process. Then run the last process in the chain in order to execute the whole processing. + +I want to run the same processing but using a script not using my web browser, how do it ? +------------------------------------------------------------------------------------------ + +NoiseModelling WebServer is using the standard protocol named OGC Web Processing Service (`WPS`_) Interface Standard. When you run a WPS block the WPS Builder is generating an equivalent Python script into the Python tab in the user interface. You can just copy/paste the script in a Python console and it should work (no dependency) as long as the NoiseModelling program is running in the background. + +The generated Python script is using the synchronous WPS execution, so the server will not respond until the process is done or after the 60 seconds default timeout. + +If the timeout is reached it will always return a message "Long running process.." like in the WPS Builder (But the job will still running on the server). + +But you can use the asynchronous WPS API so the server will return a message immediately with links to follow the progression of the execution of your job. + +You can use the `OwsLib Python library `_ to do so, here is an example of how to do it: + +.. literalinclude:: scripts/OwsLib_ListProcess.py + :language: python + :caption: List all available processes + :linenos: + + +.. literalinclude:: scripts/OwsLib_ExecuteProcess.py + :language: python + :caption: Execute a processes + :linenos: + +.. _WPS: https://www.ogc.org/standards/wps + diff --git a/Docs/conf.py b/Docs/conf.py index 848587845..d5008b197 100644 --- a/Docs/conf.py +++ b/Docs/conf.py @@ -15,7 +15,8 @@ # import os # import sys # sys.path.insert(0, os.path.abspath('.')) - +import os +import xml.etree.ElementTree as ET # -- Project information ----------------------------------------------------- @@ -24,9 +25,22 @@ author = u'Aumond P., Fortin N., Le Bescond V., Petit G.' # The short X.Y version -version = u'5.0' -# The full version, including alpha/beta/rc tags -release = u'5.0.0-SNAPSHOT' + +def get_version_from_pom(): + pom_path = os.path.join(os.path.dirname(__file__), '..', 'pom.xml') + if os.path.exists(pom_path): + tree = ET.parse(pom_path) + root = tree.getroot() + ns = {'maven': 'http://maven.apache.org/POM/4.0.0'} + version_elem = root.find('maven:version', ns) + if version_elem is None: + version_elem = root.find('version') + if version_elem is not None: + return version_elem.text + return u'5.0.0-SNAPSHOT' + +release = get_version_from_pom() +version = u'.'.join(release.split('.')[:2]) # -- General configuration --------------------------------------------------- @@ -92,7 +106,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'venv'] # -- Options for HTML output ------------------------------------------------- @@ -105,7 +119,11 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] +# html_static_path = ["_static"] + +# Get rid of duplicate label warnings when using several time the same +# title +suppress_warnings = ['autosectionlabel.*'] # -- Options for HTMLHelp output --------------------------------------------- diff --git a/Docs/functions/Acoustic_Tools/Add_Laeq_Leq_columns.rst b/Docs/functions/Acoustic_Tools/Add_Laeq_Leq_columns.rst new file mode 100644 index 000000000..ced338bfe --- /dev/null +++ b/Docs/functions/Acoustic_Tools/Add_Laeq_Leq_columns.rst @@ -0,0 +1,38 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Add Laeq Leq columns +==================== + +Add LAeq and Leq columns + +Overview +-------- + +➡️ Add the columns LAeq and Leq to a table with octave band values from 63 Hz to 8000 Hz. +The columns of the table should be named HZ63, HZ125,..., HZ8000 with an HZ prefix that can be changed. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``prefix`` — *Prefix of the frequency bands column* + Prefix of the columns containing the octave bands. (STRING) For example: HZ + + Type: ``String`` + +``tableName`` — *Name of the table* + Name of the table on which LAeq and Leq columns will be added. + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Acoustic_Tools/Create_Isolines.rst b/Docs/functions/Acoustic_Tools/Create_Isolines.rst new file mode 100644 index 000000000..d8def71f9 --- /dev/null +++ b/Docs/functions/Acoustic_Tools/Create_Isolines.rst @@ -0,0 +1,52 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Create Isolines +=============== + +Overview +-------- + +Generate isolines (isophones) by linear interpolation on triangle edges (marching-triangles). One multilines map per PERIOD and per LEVEL is created. Main output table : ISOLINES_NOISE_MAP with : - PERIOD : receivers period label (VARCHAR). - LEVEL : isoline value (DOUBLE). - THE_GEOM : MULTILINESTRING/LINESTRING geometry. Additional output tables : one table per PERIOD, named L_ISOLINES_NOISE_MAP, containing only the isolines of that PERIOD (same structure as above). + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``receiversTable`` — *Receivers level table* + Name of the receivers level table.Shall contain : IDRECEIVER, PERIOD, THE_GEOM, LAEQ (or any field to contour). + + Type: ``String`` + +``trianglesTable`` — *Triangles table* + Name of the triangles table.Shall contain : PK, THE_GEOM, PK_1, PK_2, PK_3, CELL_ID. + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``fieldName`` — *Field to contour* + Receivers numeric field to contour (e.g. LAEQ). + + Type: ``String`` + + Default: ``LAEQ`` + +``isoClasses`` — *Iso levels (dB)* + Comma-separated levels. + + Type: ``String`` + + Default: ``35.0,40.0,45.0,50.0,55.0,60.0,65.0,70.0,75.0,80.0,200.0`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Acoustic_Tools/Create_Isosurface.rst b/Docs/functions/Acoustic_Tools/Create_Isosurface.rst new file mode 100644 index 000000000..c448d04fb --- /dev/null +++ b/Docs/functions/Acoustic_Tools/Create_Isosurface.rst @@ -0,0 +1,68 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Create Isosurface +================= + +Create isosurfaces from a NoiseModelling resulting table and its associated TRIANGLES table. + +Overview +-------- + +➡️ Create isosurfaces from a NoiseModelling resulting table and its associated TRIANGLES table. +🚨 The triangle table must have been created using the "Receivers/Delaunay_Grid" WPS block. ✅ The output table is called CONTOURING_NOISE_MAP + +.. figure:: create_isosurface.png + :align: center + :alt: Create isosurfaces + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``resultTable`` — *Sound levels table* + Name of the sound levels table, generated from the "Noise_level_from_source" WPS block. (STRING) Example : RECEIVERS_LEVEL + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``isoClass`` — *Iso levels in dB* + Separation of sound levels for isosurfaces. The first range is from -∞ to the first value (excluded). The next range is from the first value (included) to the next value (excluded). Read this documentation for more information about sound levels classes. + + Type: ``String`` + + Default: ``35.0,40.0,45.0,50.0,55.0,60.0,65.0,70.0,75.0,80.0,200.0`` + +``keepTriangles`` — *Keep triangles* + Point inside areas with the same iso levels are kept so elevation variation into same iso level areas will be preserved but the output data size will be higher. Keeping triangles will reduce significantly the computation time. + + Type: ``Boolean`` + + Default: ``false`` + +``resultTableField`` — *Field of result table* + Field to read in the result table to make the iso surface. + + Type: ``String`` + + Default: ``LAEQ`` + +``smoothCoefficient`` — *Polygon smoothing coefficient* + This coefficient (Bezier curve coefficient) will smooth the generated isosurfaces. If equal to 0, it disables the smoothing step and will keep the altitude of final polygons (3D geojson can be viewed on https://kepler.gl).Use this option with keepTriangles to keep the altitude variation into same iso level areas. + + Type: ``Double`` + + Default: ``0`` + +Output +------ + +``result`` — *Output table* + Name of the output table containing the isosurfaces. The table is created in the same schema as the input result table. (STRING) + + Type: ``String`` + diff --git a/Docs/functions/Acoustic_Tools/DynamicIndicators.rst b/Docs/functions/Acoustic_Tools/DynamicIndicators.rst new file mode 100644 index 000000000..d82e4332a --- /dev/null +++ b/Docs/functions/Acoustic_Tools/DynamicIndicators.rst @@ -0,0 +1,47 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +DynamicIndicators +================= + +Compute dynamic indicators + +Overview +-------- + +Computes dynamic percentile indicators (L10, L50, L90) for each row in the table + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``columnName`` — *Column name* + Column name on which to perform the calculation. (STRING) For example : LEAQ + + Type: ``String`` + +``tableName`` — *Name of the table* + Name of the table on which to perform the calculation. The table must contain multiple sound level values for a single receiver. The columns of the table should be named HZ63, HZ125,..., HZ8000 with an HZ prefix that can be changed. (STRING) For example : RECEIVERS_LEVEL + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``outputTableName`` — *Name of the output table* + Name of the output table + + Type: ``String`` + + Default: ``tableName_DYN_IND`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/wpsbuilder/wps_images/create_isosurface.png b/Docs/functions/Acoustic_Tools/create_isosurface.png similarity index 100% rename from wpsbuilder/wps_images/create_isosurface.png rename to Docs/functions/Acoustic_Tools/create_isosurface.png diff --git a/Docs/functions/Data_Assimilation/All_Possible_Configuration.rst b/Docs/functions/Data_Assimilation/All_Possible_Configuration.rst new file mode 100644 index 000000000..054e35f78 --- /dev/null +++ b/Docs/functions/Data_Assimilation/All_Possible_Configuration.rst @@ -0,0 +1,37 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +All Possible Configuration +========================== + +All configurations + +Overview +-------- + +Process to generate all configurations. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``temperatureValues`` — *Temperature values* + List of temperature values for the road traffic emission + + Type: ``String`` + +``trafficValues`` — *Traffic values* + List of variation values in % for traffic like [0.01,1.0, 2.0,3,4] + + Type: ``String`` + +Output +------ + +``result`` — *ALL_CONFIGURATIONS* + A sql table named ALL_CONFIGURATIONS + + Type: ``String`` + diff --git a/Docs/functions/Data_Assimilation/Create_Assimilated_Maps.rst b/Docs/functions/Data_Assimilation/Create_Assimilated_Maps.rst new file mode 100644 index 000000000..4722e4223 --- /dev/null +++ b/Docs/functions/Data_Assimilation/Create_Assimilated_Maps.rst @@ -0,0 +1,42 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Create Assimilated Maps +======================= + +Creation of the result table + +Overview +-------- + +Creates the ASSIMILATED_MAPS table by joining the best configuration table with the receivers noise levels. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``bestConfigTable`` — *The best configuration table* + The best configuration table + + Type: ``String`` + +``outputTable`` — *The output table name* + The output table name + + Type: ``String`` + +``receiverLevel`` — *The receivers Level table* + The receivers Level table + + Type: ``String`` + +Output +------ + +``result`` — *The result table* + The result table + + Type: ``String`` + diff --git a/Docs/functions/Data_Assimilation/Data_Simulation.rst b/Docs/functions/Data_Assimilation/Data_Simulation.rst new file mode 100644 index 000000000..503a91132 --- /dev/null +++ b/Docs/functions/Data_Assimilation/Data_Simulation.rst @@ -0,0 +1,32 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Data Simulation +=============== + +Overview +-------- + +Method for performing a series of operations to generate noise maps + +Arguments +--------- + +Optional inputs +~~~~~~~~~~~~~~~ + +``noiseMapLimit`` — *Number of map* + The optional parameter between 1 and 100 corresponding to the percentage of number of maps relative to the maximal number of combinations + + Type: ``Integer`` + + Default: ``100`` + +Output +------ + +``result`` — *Noise map table* + LW_ROADS and ROADS_GEOM tables output + + Type: ``String`` + diff --git a/Docs/functions/Data_Assimilation/Extract_Best_Configuration.rst b/Docs/functions/Data_Assimilation/Extract_Best_Configuration.rst new file mode 100644 index 000000000..28e807056 --- /dev/null +++ b/Docs/functions/Data_Assimilation/Extract_Best_Configuration.rst @@ -0,0 +1,42 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Extract Best Configuration +========================== + +Extraction of the best configurations + +Overview +-------- + +Extraction of the best maps, i.e. those that minimise the difference between the measured and simulated values, by calculating the minimum median values. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``noiseMapTable`` — *Noise map table* + Table of "noiseMapTable" containing the noise maps after simulation + + Type: ``String`` + +``observationTable`` — *Measurement table* + Table of "observationSensor" containing the training data Set + + Type: ``String`` + +``tempToleranceThreshold`` — *Temperature tolerance threshold* + Temperature tolerance threshold used to filter and extract the best configurations + + Type: ``Double`` + +Output +------ + +``result`` — *Best Configuration Table* + BEST_CONFIGURATION_FULL table created + + Type: ``String`` + diff --git a/Docs/functions/Data_Assimilation/Merged_Sensors_Receivers.rst b/Docs/functions/Data_Assimilation/Merged_Sensors_Receivers.rst new file mode 100644 index 000000000..8a8d8b06a --- /dev/null +++ b/Docs/functions/Data_Assimilation/Merged_Sensors_Receivers.rst @@ -0,0 +1,37 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Merged Sensors Receivers +======================== + +Merged Sensors and Receivers + +Overview +-------- + +Merges sensor locations into an existing RECEIVERS table previously created with a regular grid. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableReceivers`` — *The receiver table* + The receiver table + + Type: ``String`` + +``tableSensors`` — *The Sensors table* + The Sensors table + + Type: ``String`` + +Output +------ + +``result`` — *Merged table* + Receiver table containing all sensors + + Type: ``String`` + diff --git a/Docs/functions/Data_Assimilation/NMs_4_BestConfigs.rst b/Docs/functions/Data_Assimilation/NMs_4_BestConfigs.rst new file mode 100644 index 000000000..35b74f8d9 --- /dev/null +++ b/Docs/functions/Data_Assimilation/NMs_4_BestConfigs.rst @@ -0,0 +1,37 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +NMs 4 BestConfigs +================= + +Dynamic Road Traffic Emission + +Overview +-------- + +Creation of the dynamic road using best configurations + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``bestConfig`` — *The best configuration table* + The best configuration table BEST_CONFIGURATION_FULL + + Type: ``String`` + +``roadEmission`` — *The Road Emission table* + The Road Emission table LW_ROADS + + Type: ``String`` + +Output +------ + +``results`` — *Dynamic Road Emission Table* + Dynamic Road Emission Table using best configuration LW_ROADS_best + + Type: ``String`` + diff --git a/Docs/functions/Data_Assimilation/Prepare_Sensors.rst b/Docs/functions/Data_Assimilation/Prepare_Sensors.rst new file mode 100644 index 000000000..4e3f24c06 --- /dev/null +++ b/Docs/functions/Data_Assimilation/Prepare_Sensors.rst @@ -0,0 +1,55 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Prepare Sensors +=============== + +Preparation of Sensor data + +Overview +-------- + +Extracts sensor data for a given period and creates SQL tables + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``endDate`` — *End Time Stamp* + The end timestamp to extract the dataset in format "%Y-%m-%d %H:%M:%S" + + Type: ``String`` + +``startDate`` — *Start Time Stamp* + The start timestamp to extract the dataset in format "%Y-%m-%d %H:%M:%S" + + Type: ``String`` + +``targetSRID`` — *Target projection identifier* + 🌍 Target projection identifier (also called SRID) of your table. + It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Web Mercator projection). + + 🚨 The target SRID must be in metric coordinates (e.g 2056 for Geneva). + + Type: ``Integer`` + +``trainingRatio`` — *Training data percentage* + Training data as a percentage of total data + + Type: ``Float`` + +``workingFolder`` — *Working directory path with input files* + Folder containing .csv files "device_mapping_sf", the .osm file and the folder "devices_data" + + Type: ``String`` + +Output +------ + +``result`` — *Sql tables output* + Sql tables "SENSORS_MEASUREMENTS", "SENSORS_LOCATION", "SENSORS_MEASUREMENTS_TRAINING" + + Type: ``String`` + diff --git a/Docs/functions/Database_Manager/Add_Primary_Key.rst b/Docs/functions/Database_Manager/Add_Primary_Key.rst new file mode 100644 index 000000000..eff0b7a46 --- /dev/null +++ b/Docs/functions/Database_Manager/Add_Primary_Key.rst @@ -0,0 +1,38 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Add Primary Key +=============== + +Add primary key column or constraint + +Overview +-------- + +➡️ Adds a Primary Key (🔑) column, or adds a Primary Key constraint to an existing column. +It is necessary to add a Primary Key on one of the columns for the source and receiver tables before doing a calculation. 💡 If the table already has a Primary Key, it will remove the constraint before the operation. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``pkName`` — *Name of the column* + Name of the column to be added, or for which the main key constraint will be added. 💡 Primary keys must contain UNIQUE values, and cannot contain NULL values + + Type: ``String`` + +``tableName`` — *Name of the table* + Name of the table on which a primary key will be added + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Database_Manager/Clean_Database.rst b/Docs/functions/Database_Manager/Clean_Database.rst new file mode 100644 index 000000000..2d1d37f9a --- /dev/null +++ b/Docs/functions/Database_Manager/Clean_Database.rst @@ -0,0 +1,32 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Clean Database +============== + +Delete all database tables + +Overview +-------- + +➡️ Delete all non-system tables of the database. 🚨 Use with caution + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``areYouSure`` — *Are you sure?* + Are you sure you want to delete all the tables in the database? + + Type: ``Boolean`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Database_Manager/Display_Database.rst b/Docs/functions/Database_Manager/Display_Database.rst new file mode 100644 index 000000000..7998cc6d3 --- /dev/null +++ b/Docs/functions/Database_Manager/Display_Database.rst @@ -0,0 +1,35 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Display Database +================ + +Display the list of tables (and their attributes). + +Overview +-------- + +➡️ Displays the list of tables that are in the database. +Optionally it is also possible to display their attributes ("showColumns" parameter). 💡 To visualize the content of (a part of) a table, you can use "Table Visualization Data" script. + +Arguments +--------- + +Optional inputs +~~~~~~~~~~~~~~~ + +``showColumns`` — *Display columns of the tables* + Would you also like to display the column name in the tables?💡 Note : A small yellow key symbol (🔑) will appear if the column as a Primary Key constraint. + + Type: ``Boolean`` + + Default: ``true`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Database_Manager/Drop_a_Table.rst b/Docs/functions/Database_Manager/Drop_a_Table.rst new file mode 100644 index 000000000..b9bd4afe0 --- /dev/null +++ b/Docs/functions/Database_Manager/Drop_a_Table.rst @@ -0,0 +1,32 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Drop a Table +============ + +Remove a table from the database. + +Overview +-------- + +➡️ Remove a table from the database. 🚨 Use with caution + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableToDrop`` — *Name of the table to drop* + Name of the table to drop + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Database_Manager/Table_Visualization_Data.rst b/Docs/functions/Database_Manager/Table_Visualization_Data.rst new file mode 100644 index 000000000..763a9ba7b --- /dev/null +++ b/Docs/functions/Database_Manager/Table_Visualization_Data.rst @@ -0,0 +1,43 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Table Visualization Data +======================== + +Display first rows of a query result. + +Overview +-------- + +➡️ Display the content of a SQL query result. +You can provide either a table name or a complete SELECT SQL query. Using "linesNumber" parameter, you can choose the number of lines to display 🚨 Be careful, this treatment can be very long if the query returns many rows. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableName`` — *Table name* + Table name or SQL SELECT query (e.g., mytable or SELECT * FROM mytable) + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``linesNumber`` — *Number of rows* + Number of rows you want to display. This parameter is ignored if your SQL query already contains a LIMIT clause. + + Type: ``Integer`` + + Default: ``10`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Database_Manager/Table_Visualization_Map.rst b/Docs/functions/Database_Manager/Table_Visualization_Map.rst new file mode 100644 index 000000000..66e93345e --- /dev/null +++ b/Docs/functions/Database_Manager/Table_Visualization_Map.rst @@ -0,0 +1,41 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Table Visualization Map +======================= + +Display a table on a map. + +Overview +-------- + +➡️ Display a table containing a geometric column on a map 🗺 +Technically, it groups all the geometries of a table and returns them in WKT OGC format. 🚨 Be careful, this treatment can be blocked if the table is too large. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableName`` — *Name of the table* + Name of the table you want to display. + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``inputSRID`` — *Projection identifier* + 🌍 Original projection identifier (also called SRID) of your table. It should be an EPSG code, a integer with 4 or 5 digits (ex: 3857 is Web Mercator projection). (INTEGER) All coordinates will be projected from the specified EPSG to WGS84 coordinates. This entry is optional because many formats already include the projection and you can also import files without geometry attributes. + + Type: ``Integer`` + +Output +------ + +``result`` — *Result output geometry* + This is the output geometry in WKT OGC format + + Type: ``Geometry`` + diff --git a/Docs/functions/Deprecated/Noise_level_from_traffic.rst b/Docs/functions/Deprecated/Noise_level_from_traffic.rst new file mode 100644 index 000000000..d847e8804 --- /dev/null +++ b/Docs/functions/Deprecated/Noise_level_from_traffic.rst @@ -0,0 +1,319 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Noise level from traffic +======================== + +Compute noise level directly from road traffic data + +Overview +-------- + +➡️ Computes Noise map from each period from the traffic flow rate and speed estimates (specific format, see input details). +🌍 Tables must be projected in a metric coordinate system (SRID). Use "Change_SRID" WPS Block if needed. ✅ The output table is RECEIVERS_LEVEL The output tables contain: + +* IDRECEIVER: an identifier (INTEGER, PRIMARY KEY) + +* IDSOURCE: an identifier of the source (INTEGER) if keepSource is true + +* THE_GEOM : the 3D geometry of the receivers (POINT) + +* PERIOD : time period ex. D, E, N, DEN (Varchar) + +* Lw63, Lw125, Lw250, Lw500, Lw1000, Lw2000, Lw4000, Lw8000, Laeq, Leq: noise level at receiver (REAL) + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableBuilding`` — *Buildings table name* + 🏠 Name of the Buildings table The table must contain: + + * THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON) + + * HEIGHT : the height of the building (FLOAT) + + Type: ``String`` + +``tableReceivers`` — *Receivers table name* + Name of the Receivers table The table must contain: + + * PK : an identifier. It shall be a primary key (INTEGER, PRIMARY KEY) + + * THE_GEOM : the 3D geometry of the sources (POINT, MULTIPOINT) + + 💡 This table can be generated from the WPS Blocks in the "Receivers" folder + + Type: ``String`` + +``tableRoads`` — *Roads table name* + 🛣 Name of the Roads table, traffic can be provided here but are limited to DAY EVENING NIGHT periods This function recognize the following columns (* mandatory): + + * PK * : an identifier. It shall be a primary key (INTEGER, PRIMARY KEY) + + * LV_D TV_E TV_N : Hourly average light vehicle count (6-18h)(18-22h)(22-6h) (DOUBLE) + + * MV_D MV_E MV_N : Hourly average medium heavy vehicles, delivery vans > 3.5 tons, buses, touring cars, etc. with two axles and twin tyre mounting on rear axle count (6-18h)(18-22h)(22-6h) (DOUBLE) + + * HGV_D HGV_E HGV_N : Hourly average heavy duty vehicles, touring cars, buses, with three or more axles (6-18h)(18-22h)(22-6h) (DOUBLE) + + * WAV_D WAV_E WAV_N : Hourly average mopeds, tricycles or quads ≤ 50 cc count (6-18h)(18-22h)(22-6h) (DOUBLE) + + * WBV_D WBV_E WBV_N : Hourly average motorcycles, tricycles or quads > 50 cc count (6-18h)(18-22h)(22-6h) (DOUBLE) + + * LV_SPD_D LV_SPD_E LV_SPD_N : Hourly average light vehicle speed (6-18h)(18-22h)(22-6h) (DOUBLE) + + * MV_SPD_D MV_SPD_E MV_SPD_N : Hourly average medium heavy vehicles speed (6-18h)(18-22h)(22-6h) (DOUBLE) + + * HGV_SPD_D HGV_SPD_E HGV_SPD_N : Hourly average heavy duty vehicles speed (6-18h)(18-22h)(22-6h) (DOUBLE) + + * WAV_SPD_D WAV_SPD_E WAV_SPD_N : Hourly average mopeds, tricycles or quads ≤ 50 cc speed (6-18h)(18-22h)(22-6h) (DOUBLE) + + * WBV_SPD_D WBV_SPD_E WBV_SPD_N : Hourly average motorcycles, tricycles or quads > 50 cc speed (6-18h)(18-22h)(22-6h) (DOUBLE) + + * PVMT : CNOSSOS road pavement identifier (ex: NL05)(default NL08) (VARCHAR) + + * TEMP_D TEMP_E TEMP_N : Average day, evening, night temperature (default 20℃) (6-18h)(18-22h)(22-6h)(DOUBLE) + + * TS_STUD : A limited period Ts (in months) over the year where a average proportion pm of light vehicles are equipped with studded tyres (0-12) (DOUBLE) + + * PM_STUD : Average proportion of vehicles equipped with studded tyres during TS_STUD period (0-1) (DOUBLE) + + * JUNC_DIST : Distance to junction in meters (DOUBLE) + + * JUNC_TYPE : Type of junction (k=0 none, k = 1 for a crossing with traffic lights ; k = 2 for a roundabout) (INTEGER) + + * SLOPE : Slope (in %) of the road section. If the field is not filled in, the LINESTRING z-values will be used to calculate the slope and the traffic direction (way field) will be force to 3 (bidirectional). (DOUBLE) + + * WAY : Define the way of the road section. 1 = one way road section and the traffic goes in the same way that the slope definition you have used, 2 = one way road section and the traffic goes in the inverse way that the slope definition you have used, 3 = bi-directional traffic flow, the flow is split into two components and correct half for uphill and half for downhill (INTEGER) + + 💡 This table can be generated from the WPS Block "Import_OSM" + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``coefficientVersion`` — *Coefficient version* + 🌧 Cnossos coefficient version (1 = 2015, 2 = 2020) + + Type: ``Integer`` + + Default: ``2`` + +``confDiffHorizontal`` — *Diffraction on horizontal edges* + Compute or not the diffraction on horizontal edges + + Type: ``Boolean`` + + Default: ``false`` + +``confDiffVertical`` — *Diffraction on vertical edges* + Compute or not the diffraction on vertical edges. Following Directive 2015/996, enable this option for rail and industrial sources only + + Type: ``Boolean`` + + Default: ``false`` + +``confExportSourceId`` — *Separate receiver level by source identifier* + Keep source identifier in output in order to get noise contribution of each noise source. When only the source geometry is given, the attenuation between each pair of "source-receiver" points is specified (commonly referred to as the "attenuation matrix") + + Type: ``Boolean`` + + Default: ``false`` + +``confFavourableOccurrencesDefault`` — *Probability of occurrences* + Comma-delimited string containing the probability ([0,1]) of occurrences of favourable propagation conditions. Follow the clockwise direction. The north slice is the last array index (n°16 in the schema below) not the first one + + .. figure:: acoustics_parameters_confFavorableOccurrences.png + :align: center + :alt: Noise level from traffic + + Type: ``String`` + + Default: ``0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5`` + +``confHumidity`` — *Relative humidity* + 🌧 Humidity for noise propagation (%) [0,100] + + Type: ``Double`` + + Default: ``70`` + +``confMaxError`` — *Max Error (dB)* + Threshold for excluding negligible sound sources in calculations.This parameter is ignored if no emission level is specified or if you set it to 0 dB. This parameter have a great impact on computation time. + + Type: ``Double`` + + Default: ``0.1`` + +``confMaxReflDist`` — *Maximum source-reflexion distance* + Maximum search distance of walls / facades from the "Source-Receiver" segment, for the calculation of specular reflections (meters). + + .. figure:: acoustics_parameters_confMaxReflDist.png + :align: center + :alt: Noise level from traffic + + Type: ``Double`` + + Default: ``50`` + +``confMaxSrcDist`` — *Maximum source-receiver distance* + Maximum distance between source and receiver (FLOAT, in meters). + + .. figure:: acoustics_parameters_confMaxSrcDist.png + :align: center + :alt: Noise level from traffic + + Type: ``Double`` + + Default: ``150`` + +``confMinWallReflDist`` — *Ignore close reflections* + Optional maximum receiver-to-wall distance (meters) below which reflection cut profiles are ignored. With regard to the population’s exposure to noise, it is recommended that the contribution due to reflection off the façade wall of the building where the resident lives should be disregarded. If you have placed the receivers 0.1 m from the façades, you can set this parameter to 0.2 m. This offset is set to ensure that the contribution from the nearby wall is ignored. Use 0 to keep all reflections. + + Type: ``Double`` + + Default: ``0`` + +``confRaysName`` — *Export scene* + Save each mnt, buildings and propagation rays into the specified table (ex:RAYS) or file URL (ex: file:///Z:/dir/map.kml) You can set a table name here in order to save all the rays computed by NoiseModelling. The number of rays has been limited in this script in order to avoid memory exception. 🛠 + + Type: ``String`` + +``confReflOrder`` — *Order of reflexion* + Maximum number of reflections to be taken into account (INTEGER). 🚨 Adding 1 order of reflexion can significantly increase the processing time + + Type: ``Integer`` + + Default: ``1`` + +``confTemperature`` — *Air temperature* + 🌡 Air temperature (°C) + + Type: ``Double`` + + Default: ``15`` + +``confThreadNumber`` — *Thread number* + Number of thread to use on the computer (INTEGER). 🛠 + + Type: ``Integer`` + + Default: ``0`` + +``frequencyFieldPrepend`` — *Frequency field name* + Frequency field name prepend. Ex. for 1000 Hz frequency the default column name is HZ1000 + + Type: ``String`` + + Default: ``HZ`` + +``paramWallAlpha`` — *Wall absorption coefficient* + Wall absorption coefficient [0,1] (between ``0`` : "fully reflective" and ``1`` : "fully absorbent")🛠 + + Type: ``Double`` + +``tableDEM`` — *DEM table name* + Name of the Digital Elevation Model (DEM) table The table must contain: + + * THE_GEOM : the 3D geometry of the sources (POINT, MULTIPOINT). + + 💡 This table can be generated from the WPS Block "Import_Asc_File" + + Type: ``String`` + +``tableGroundAbs`` — *Ground absorption table name* + Name of the surface/ground acoustic absorption table The table must contain: + + * THE_GEOM : the 2D geometry of the sources (POLYGON or MULTIPOLYGON) + + * G : the acoustic absorption of a ground (FLOAT between 0 : very hard and 1 : very soft) + + Type: ``String`` + +``tablePeriodAtmosphericSettings`` — *Atmospheric settings table name for each time period* + Name of the Atmospheric settings table The table must contain the following columns: + + * PERIOD : time period (VARCHAR PRIMARY KEY) + + * WINDROSE : probability of occurrences of favourable propagation conditions (ARRAY(16)) + + * TEMPERATURE : Temperature in celsius (FLOAT) + + * PRESSURE : air pressure in pascal (FLOAT) + + * HUMIDITY : air humidity in percentage (FLOAT) + + * GDISC : choose between accept G discontinuity or not (BOOLEAN) default true + + * PRIME2520 : choose to use prime values to compute eq. 2.5.20 (BOOLEAN) default false + + Type: ``String`` + +``tableRoadsTraffic`` — *Roads traffic table name* + 🛣 Name of the Roads traffic table per period This function recognize the following columns (* mandatory): + + * IDSOURCE * : an identifier. It shall be linked to the primary key of tableRoads (INTEGER) + + * PERIOD * : Time period, you will find this column on the output (VARCHAR) + + * LV : Hourly average light vehicle count (DOUBLE) + + * MV : Hourly average medium heavy vehicles, delivery vans > 3.5 tons, buses, touring cars, etc. with two axles and twin tyre mounting on rear axle count (DOUBLE) + + * HGV : Hourly average heavy duty vehicles, touring cars, buses, with three or more axles (DOUBLE) + + * WAV : Hourly average mopeds, tricycles or quads ≤ 50 cc count (DOUBLE) + + * WBV : Hourly average motorcycles, tricycles or quads > 50 cc count (DOUBLE) + + * LV_SPD : Hourly average light vehicle speed (DOUBLE) + + * MV_SPD : Hourly average medium heavy vehicles speed (DOUBLE) + + * HGV_SPD : Hourly average heavy duty vehicles speed (DOUBLE) + + * WAV_SPD : Hourly average mopeds, tricycles or quads ≤ 50 cc speed (DOUBLE) + + * WBV_SPD : Hourly average motorcycles, tricycles or quads > 50 cc speed (DOUBLE) + + * PVMT : CNOSSOS road pavement identifier (ex: NL05)(default NL08) (VARCHAR) + + * TS_STUD : A limited period Ts (in months) over the year where a average proportion pm of light vehicles are equipped with studded tyres (0-12) (DOUBLE) + + * PM_STUD : Average proportion of vehicles equipped with studded tyres during TS_STUD period (0-1) (DOUBLE) + + * JUNC_DIST : Distance to junction in meters (DOUBLE) + + * JUNC_TYPE : Type of junction (k=0 none, k = 1 for a crossing with traffic lights ; k = 2 for a roundabout) (INTEGER) + + * SLOPE : Slope (in %) of the road section. If the field is not filled in, the LINESTRING z-values will be used to calculate the slope and the traffic direction (way field) will be force to 3 (bidirectional). (DOUBLE) + + * WAY : Define the way of the road section. 1 = one way road section and the traffic goes in the same way that the slope definition you have used, 2 = one way road section and the traffic goes in the inverse way that the slope definition you have used, 3 = bi-directional traffic flow, the flow is split into two components and correct half for uphill and half for downhill (INTEGER) + + Type: ``String`` + +``tableSourceDirectivity`` — *Source directivity table name* + Name of the emission directivity table If not specified the default is train directivity of CNOSSOS-EU The table must contain the following columns: + + * DIR_ID : identifier of the directivity sphere (INTEGER) + + * THETA : [-90;90] Vertical angle in degree. 0° front 90° top -90° bottom (FLOAT) + + * PHI : [0;360] Horizontal angle in degree. 0° front 90° right (FLOAT) + + * LW63, LW125, LW250, LW500, LW1000, LW2000, LW4000, LW8000 : attenuation levels in dB for each octave or third octave (FLOAT) + + Type: ``String`` + +Output +------ + +``result`` — *Created table* + Name of the table containing the results of the computation. Can be used as input for another process. + + Type: ``String`` + diff --git a/Docs/functions/Deprecated/acoustics_parameters_confFavorableOccurrences.png b/Docs/functions/Deprecated/acoustics_parameters_confFavorableOccurrences.png new file mode 100644 index 000000000..e9a03ab29 Binary files /dev/null and b/Docs/functions/Deprecated/acoustics_parameters_confFavorableOccurrences.png differ diff --git a/Docs/functions/Deprecated/acoustics_parameters_confMaxReflDist.png b/Docs/functions/Deprecated/acoustics_parameters_confMaxReflDist.png new file mode 100644 index 000000000..dee0101f4 Binary files /dev/null and b/Docs/functions/Deprecated/acoustics_parameters_confMaxReflDist.png differ diff --git a/Docs/functions/Deprecated/acoustics_parameters_confMaxSrcDist.png b/Docs/functions/Deprecated/acoustics_parameters_confMaxSrcDist.png new file mode 100644 index 000000000..4a274f322 Binary files /dev/null and b/Docs/functions/Deprecated/acoustics_parameters_confMaxSrcDist.png differ diff --git a/Docs/functions/Dynamic/Flow_2_Noisy_Vehicles.rst b/Docs/functions/Dynamic/Flow_2_Noisy_Vehicles.rst new file mode 100644 index 000000000..be7f07ac0 --- /dev/null +++ b/Docs/functions/Dynamic/Flow_2_Noisy_Vehicles.rst @@ -0,0 +1,69 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Flow 2 Noisy Vehicles +===================== + +From Road traffic flows to noisy individual vehicles + +Overview +-------- + +Calculates individual vehicle position and noise level based on average traffic flows. A first output table is called : SOURCES_GEOM which is needed to compute the Noise Attenuation Matrixand contain : - IDSOURCE : an identifier (INTEGER, PRIMARY KEY). - ROAD_ID : id link to the road segment (INTEGER). - THE_GEOM : the 3D geometry of the sources (POINT). The output table is called : SOURCES_EMISSION and contain : - PK : an identifier (INTEGER, PRIMARY KEY). - IDSOURCE : link to the source point (INTEGER). - PERIOD : The TIMESTAMP iteration (VARCHAR).- HZ63, HZ125, HZ250, HZ500, HZ1000,HZ2000, HZ4000, HZ8000 : 8 columns giving the instantaneous emission sound level for each octave band (FLOAT). + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``method`` — *Selected Method* + Two methods are available : - PROBA : Probabilistic representation of vehicle appearances for each time step (quicker, but sacrifices temporal coherence) Aumond, P., Jacquesson, L., & Can, A. (2018). Probabilistic modeling framework for multisource sound mapping. Applied Acoustics, 139, 34-43. . - TNP : Simplified vehicle movements (slower, but maintaining temporal coherence) De Coensel, B.; Brown, A.L.; Tomerini, D. A road traffic noise pattern simulation model that includes distributions of vehicle sound power levels. Appl. Acoust. 2016, 111, 170–178. . + + Type: ``String`` + + Allowed values: ``PROBA``, ``TNP`` + +``tableRoads`` — *Roads table name* + Name of the Roads table. + The table shall contain : - PK : an identifier. It shall be a primary key (INTEGER, PRIMARY KEY) + - LV_D : Hourly average light and heavy vehicle count (DOUBLE) + - HGV_D : Hourly average heavy vehicle count (DOUBLE) + - LV_SPD_D : Hourly average light vehicle speed (DOUBLE) + - HGV_SPD_D : Hourly average heavy vehicle speed (DOUBLE) + - PVMT : CNOSSOS road pavement identifier (ex: NL05) (VARCHAR) This table can be generated from the WPS Block 'Import_OSM'. . + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``duration`` — *duration in sec.* + Number of seconds to compute (INTEGER). + + Type: ``Integer`` + + Default: ``60`` + +``gridStep`` + Distance between location of vehicle along the network in meters. + + Type: ``Integer`` + + Default: ``10`` + +``timestep`` + Number of iterations. Timestep in sec. + + Type: ``Integer`` + + Default: ``1`` + +Output +------ + +``result`` — *Generated table name* + Name of the generated table. Can be used as the input of other process. + + Type: ``String`` + diff --git a/Docs/functions/Dynamic/Ind_Vehicles_2_Noisy_Vehicles.rst b/Docs/functions/Dynamic/Ind_Vehicles_2_Noisy_Vehicles.rst new file mode 100644 index 000000000..e19576ac5 --- /dev/null +++ b/Docs/functions/Dynamic/Ind_Vehicles_2_Noisy_Vehicles.rst @@ -0,0 +1,57 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Ind Vehicles 2 Noisy Vehicles +============================= + +Convert Individual Vehicles traffic to emission noise level and Snap them to the network point sources. + +Overview +-------- + +Calculating dynamic road emissions based on vehicles trajectories and snap them to the network The output table is called : SOURCES_EMISSION and contain : - IDSOURCE : an identifier (INTEGER). - PERIOD : The TIMESTAMP iteration (STRING).- HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000 : 8 columns giving the emission sound level for each octave band (FLOAT). + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableFormat`` — *Format of the individual Vehicles table* + Format of the individual Vehicles table. Can be for the moment SUMO or Matsim. See in the code to understand the different format. + + Type: ``String`` + +``tableSourceGeom`` — *table of the source geometry* + table of points source geometry, the output emission will be reattached to the index of this table according to the snap distance. Should be SOURCES_GEOM See Point_Source_From_Network to convert lines to points + + Type: ``String`` + +``tableVehicles`` — *table of the individual Vehicles* + it should contain timestep, geometry (POINT), speed, acceleration, veh_type... + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``distance2snap`` — *Maximum distance to snap on the network point sources* + Maximum distance to snap on the network point sources + + Type: ``Double`` + +``keepNoEmissionGeoms`` — *Keep source geometries without emission value* + Do not delete source geometries that does not contain any emission value. Default to true, it reduce the computation time when evaluating the attenuation + + Type: ``Boolean`` + + Default: ``true`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Dynamic/Noise_From_Attenuation_Matrix.rst b/Docs/functions/Dynamic/Noise_From_Attenuation_Matrix.rst new file mode 100644 index 000000000..0c763b725 --- /dev/null +++ b/Docs/functions/Dynamic/Noise_From_Attenuation_Matrix.rst @@ -0,0 +1,55 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Noise From Attenuation Matrix +============================= + +Noise Map From Attenuation Matrix + +Overview +-------- + + + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``attenuationTable`` — *Attenuation Matrix Table name* + Attenuation Matrix Table name, Obtained from the Noise_level_from_source script with "confExportSourceId" enabled. Should be RECEIVERS_LEVEL + The table must contain the following fields : + IDRECEIVER, IDSOURCE, THE_GEOM, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000 + + Type: ``String`` + +``lwTable`` — *LW(PERIOD)* + LW(PERIOD) ex. SOURCES_EMISSION + The table must contain the following fields : + IDSOURCE, PERIOD, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000 + IDSOURCE link to primary key of attenuation table and PERIOD a varchar + + Type: ``String`` + +``outputTable`` — *outputTable Matrix Table name* + outputTable + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``lwTable_sourceId`` — *LW(PERIOD) source index field* + LW(PERIOD) source index field. Default is IDSOURCE + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Dynamic/Point_Source_From_Network.rst b/Docs/functions/Dynamic/Point_Source_From_Network.rst new file mode 100644 index 000000000..0c4710966 --- /dev/null +++ b/Docs/functions/Dynamic/Point_Source_From_Network.rst @@ -0,0 +1,47 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Point Source From Network +========================= + +Create Point Source From a network + +Overview +-------- + +Creates a SOURCES_GEOM point source table from a network linestring table. This table is useful to compute the attenuation matrix between sources and receivers.Create point sources from the network every "gridStep" meters. This point source will be used to compute the noise attenuation level from them to each receiver. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableNetwork`` — *Input table name* + Name of the network table. + + Must contain at least:- PK: identifier with a Primary Key constraint- THE_GEOM: geometric column + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``gridStep`` + Distance between location of possible sources along the network in meters. + + Type: ``Integer`` + +``height`` — *Source height* + Height of the source in meters. + + Type: ``Double`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Dynamic/Split_Sources_Period.rst b/Docs/functions/Dynamic/Split_Sources_Period.rst new file mode 100644 index 000000000..8fb93b06d --- /dev/null +++ b/Docs/functions/Dynamic/Split_Sources_Period.rst @@ -0,0 +1,55 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Split Sources Period +==================== + +Aggregate by source index + +Overview +-------- + +Split a single table with duplicated geometry and source identifier into SOURCES_GEOM and SOURCES_EMISSION tables + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``sourceIndexFieldName`` — *Source index field name* + The field name of the source index, will be translated into IDSOURCE + + Type: ``String`` + +``sourcePeriodFieldName`` — *Source period field name* + The field name of the source period (ex. T), will be translated into PERIOD + + Type: ``String`` + +``tableSourceDynamic`` — *Source table name* + Name of the Source table. The source table have for the same index multiple periods, other columns can be any supported columns of noise level from emission or noise level from traffic + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``sourceEmissionTableName`` — *Source emission table name* + The output table that contain for each source index, the period and other attributes of the source. Default is SOURCES_EMISSION. Can be used directly on noise_level_from_source or Noise_From_Attenuation_Matrix + + Type: ``String`` + +``sourceGeomTableName`` — *Source geometry table name* + The output table that contain the distinct source index with the appropriate geometry. Default is SOURCES_GEOM + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Experimental/Noise_Map_Difference.rst b/Docs/functions/Experimental/Noise_Map_Difference.rst new file mode 100644 index 000000000..b4648712d --- /dev/null +++ b/Docs/functions/Experimental/Noise_Map_Difference.rst @@ -0,0 +1,63 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Noise Map Difference +==================== + +Map Difference + +Overview +-------- + +➡️ Computes the difference between two noise maps + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``mainMapTable`` — *Primary map table name* + Name of the table containing the primary noise map data. + + The table must contain the following columns: + PK, THE_GEOM, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000, LAEQ, LEQ + + Type: ``String`` + +``outTable`` — *Name of created table* + Name of the table you want to create + + The table will contain the following columns: + PK, THE_GEOM, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000, LAEQ, LEQ + + Type: ``String`` + +``secondMapTable`` — *Secondary map table name* + Name of the table containing the second noise map data. + + The table must contain the following columns: + PK, THE_GEOM, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000, LAEQ, LEQ + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``invert`` — *Invert the substraction ?* + Invert the substraction? + + * False (default) : Primary map - Second map + + * True : Second map - Primary map + + Type: ``Boolean`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Experimental/Road_Emission_From_AADF.rst b/Docs/functions/Experimental/Road_Emission_From_AADF.rst new file mode 100644 index 000000000..7485ee374 --- /dev/null +++ b/Docs/functions/Experimental/Road_Emission_From_AADF.rst @@ -0,0 +1,39 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Road Emission From AADF +======================= + +Compute Road Emission + +Overview +-------- + +➡️ Compute Road Emission Noise Map from Estimated Annual average daily flows (AADF) estimates. +This block allows to calculate a road traffic noise emission map from the AADF estimates given in the ROADS.shp file of the tutorial. The average traffic is first converted to hourly traffic before the calculation of Lday, Levening and Lnight using distribution in Berengier et al., 2019 : "DEUFRABASE: A Simple Tool for the Evaluation of the Noise Impact of Pavements in Typical Road Geometries". + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``sourcesTableName`` — *Sources table name* + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``databaseName`` — *Name of the database* + Name of the database (default : first found db) + + Type: ``String`` + +Output +------ + +``result`` — *Result* + + Type: ``String`` + diff --git a/Docs/functions/Experimental/Road_Emission_From_TMJA.rst b/Docs/functions/Experimental/Road_Emission_From_TMJA.rst new file mode 100644 index 000000000..ed31d5f7a --- /dev/null +++ b/Docs/functions/Experimental/Road_Emission_From_TMJA.rst @@ -0,0 +1,38 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Road Emission From TMJA +======================= + +Compute Road Emission + +Overview +-------- + +➡️ Compute Road Emission Noise Map from Estimated Annual average daily flows (TMJA) estimates. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``sourcesTableName`` — *Sources table name* + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``databaseName`` — *Name of the database* + Name of the database (default : first found db) + + Type: ``String`` + +Output +------ + +``result`` — *Result* + + Type: ``String`` + diff --git a/Docs/functions/Experimental_Matsim/Agent_Exposure.rst b/Docs/functions/Experimental_Matsim/Agent_Exposure.rst new file mode 100644 index 000000000..a476052c5 --- /dev/null +++ b/Docs/functions/Experimental_Matsim/Agent_Exposure.rst @@ -0,0 +1,79 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Agent Exposure +============== + +Calculate Matsim agents exposure + +Overview +-------- + +Loads a Matsim plans.xml file and calculate agents noise exposure, based on previously calculated timesliced noisemap at receiver positions, linked with matsim activities (facilities) + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``dataTable`` — *Table containing the noise data* + Table containing the noise data + The table must contain the following fields : + PK, IDRECEIVER, THE_GEOM, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ000, HZ8000, PERIOD + + Type: ``String`` + +``experiencedPlansFile`` — *Path of the Matsim output_experienced_plans file* + Path of the Matsim output_plans file For example : /home/matsim/simulation_output/output_experienced_plans.xml.gz + + Type: ``String`` + +``outTableName`` — *Name of created table* + Name of the table you want to create from the file. + The table will contain the following fields : + PK, PERSON_ID, HOME_FACILITY, HOME_GEOM, WORK_FACILITY, WORK_GEOM, LAEQ, HOME_LAEQ, DIFF_LAEQ + + Type: ``String`` + +``plansFile`` — *Path of the Matsim output_plans file* + Path of the Matsim output_plans file For example : /home/matsim/simulation_output/output_plans.xml.gz + + Type: ``String`` + +``receiversTable`` — *Table containing the receivers position* + Table containing the receivers position + The table must contain the following fields : + PK, FACILITY, ORIGIN_GEOM, THE_GEOM, TYPES + + Type: ``String`` + +``timeBinSize`` — *The size of time bins in seconds.* + This parameter dictates the time resolution of the resulting data + The time information stored will be the starting time of the time bins + For exemple with a timeBinSize of 3600, the data will be analysed using the following timeBins: + 0, 3600, 7200, ..., 79200, 82800 + + Type: ``Integer`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``SRID`` — *Projection identifier* + Original projection identifier (also called SRID) of your tables.It should be an EPSG code; an integer with 4 or 5 digits (ex: 3857 is Web Mercator projection). + + Type: ``Integer`` + +``personsCsvFile`` + Path of the Matsim output_persons csv file For example : /home/matsim/simulation_output/output_persons.csv.gz + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Experimental_Matsim/Import_Activities.rst b/Docs/functions/Experimental_Matsim/Import_Activities.rst new file mode 100644 index 000000000..a230ef56e --- /dev/null +++ b/Docs/functions/Experimental_Matsim/Import_Activities.rst @@ -0,0 +1,47 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Import Activities +================= + +Import Matsim "facilities" file + +Overview +-------- + +containing agents activities location. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``facilitiesPath`` — *Path of the Matsim facilities file* + Path of the Matsim facilities file + + Type: ``String`` + +``outTableName`` — *Name of created table* + Name of the table you want to create + The table will contain the following fields : + PK, FACILITY, THE_GEOM, TYPES, BUILDING_ID + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``SRID`` — *Projection identifier* + Original projection identifier (also called SRID) of your table.It should be an EPSG code, a integer with 4 or 5 digits (ex: 3857 is Web Mercator projection). + + Type: ``Integer`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Experimental_Matsim/Plot_Exposition_Distribution.rst b/Docs/functions/Experimental_Matsim/Plot_Exposition_Distribution.rst new file mode 100644 index 000000000..1c75f30de --- /dev/null +++ b/Docs/functions/Experimental_Matsim/Plot_Exposition_Distribution.rst @@ -0,0 +1,45 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Plot Exposition Distribution +============================ + +Overview +-------- + +Plot a graph displaying the distribution of a chosen field in a previously calculated Matsim agents noise exposition table. Will display a Graph Window on the server + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``expositionField`` — *Field containing noise exposition* + Field containing noise exposition + + Type: ``String`` + +``expositionsTableName`` — *Name of the table containing the expositions* + Name of the table containing the expositions + The table must contain the following fields : + PK, PERSON_ID, HOME_FACILITY, HOME_GEOM, WORK_FACILITY, WORK_GEOM, LAEQ, HOME_LAEQ, DIFF_LAEQ + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``otherExpositionField`` — *Other field containing noise exposition* + Other field containing noise exposition + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Experimental_Matsim/Receivers_From_Activities_Closest.rst b/Docs/functions/Experimental_Matsim/Receivers_From_Activities_Closest.rst new file mode 100644 index 000000000..ddb06274a --- /dev/null +++ b/Docs/functions/Experimental_Matsim/Receivers_From_Activities_Closest.rst @@ -0,0 +1,48 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Receivers From Activities Closest +================================= + +Choose closest receivers for Matsim activities + +Overview +-------- + +Choose the closest receiver in a RECEIVERS table for every Mastim activity in an ACTIVITIES table + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``activitiesTable`` — *Name of the table containing the activities* + Name of the table containing the activities + The table must contain the following fields : + PK, FACILITY, THE_GEOM, TYPES + + Type: ``String`` + +``outTableName`` — *Name of created table* + Name of the table you want to create + The table will contain the following fields : + PK, FACILITY, ORIGIN_GEOM, THE_GEOM, TYPES + + Type: ``String`` + +``receiversTable`` — *Name of the table containing the receivers* + Name of the table containing the receivers + The table must contain the following fields : + PK, THE_GEOM + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Experimental_Matsim/Receivers_From_Activities_Random.rst b/Docs/functions/Experimental_Matsim/Receivers_From_Activities_Random.rst new file mode 100644 index 000000000..3aa66f8aa --- /dev/null +++ b/Docs/functions/Experimental_Matsim/Receivers_From_Activities_Random.rst @@ -0,0 +1,65 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Receivers From Activities Random +================================ + +Choose a random receivers for Matsim activities + +Overview +-------- + +Choose the closest building for every Mastim activity in an ACTIVITIES table, and then chose a random receiver previously generated around this building. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``activitiesTable`` — *Name of the table containing the activities* + Name of the table containing the activities + The table must contain the following fields : + PK, FACILITY, THE_GEOM, TYPES + + Type: ``String`` + +``buildingsTable`` — *Name of the table containing the buildings* + Name of the table containing the buildings + The table must contain the following fields : + PK, THE_GEOM + + Type: ``String`` + +``outTableName`` — *Name of created table* + Name of the table you want to create + The table will contain the following fields : + PK, FACILITY, ORIGIN_GEOM, THE_GEOM, TYPES, BUILD_PK + + Type: ``String`` + +``receiversTable`` — *Name of the table containing the receivers* + Name of the table containing the receivers + The table must contain the following fields : + PK, THE_GEOM, BUILD_PK + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``randomSeed`` — *Random seed* + Random seed + + Type: ``Integer`` + + Default: ``1234`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Experimental_Matsim/Traffic_From_Events.rst b/Docs/functions/Experimental_Matsim/Traffic_From_Events.rst new file mode 100644 index 000000000..6981d8ef9 --- /dev/null +++ b/Docs/functions/Experimental_Matsim/Traffic_From_Events.rst @@ -0,0 +1,114 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Traffic From Events +=================== + +Import traffic data from Matsim simulation output folder + +Overview +-------- + +Read Matsim events output file in order to get traffic NoiseModelling input + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``folder`` — *Path of the Matsim output folder* + Path of the Matsim output folder For example : /home/matsim/simulation_output + The folder must contain at least the following files: + + - output_network.xml.gz + + - output_allVehicles.xml.gz + + - output_events.xml.gz + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``SRID`` — *Projection identifier* + Projection identifier (also called SRID) of the geometric data.It should be an EPSG code, a integer with 4 or 5 digits (ex: 3857 is Web Mercator projection). + + Type: ``Integer`` + +``exportTraffic`` — *Export additionnal traffic data ?* + Define if you want to output average speed and flow per vehicle category in an additional table + + Type: ``Boolean`` + + Default: ``false`` + +``link2GeometryFile`` — *Network CSV file* + The path of the pt2matsim CSV file generated when importing OSM network. Ignored if not set. + The file must contain at least two columns : + + - The link ID + + - The WKT geometry + + Type: ``String`` + +``outTableName`` — *Output table name* + Name of the table you want to create. + A table with this name will be created plus another with a "_LW" suffix + For exemple if set to "MATSIM_ROADS (default value)": + + - the table MATSIM_ROADS, with the link ID and the geometry field + + - the table MATSIM_ROADS_LW, with the link ID and the traffic data + + Type: ``String`` + +``populationFactor`` — *Population Factor* + Set the population factor of the MATSim simulation + Must be a decimal number between 0 and 1 + + Type: ``Double`` + + Default: ``1.0`` + +``skipUnused`` — *Skip unused links ?* + Define if links with unused traffic should be omitted in the output table. + + Type: ``Boolean`` + + Default: ``true`` + +``timeBinMax`` — *The maximum of time bins in seconds* + The maximum of time bins in seconds, + + Type: ``Integer`` + + Default: ``86400`` + +``timeBinMin`` — *The minimum of time bins in seconds* + The minimum of time bins in seconds + + Type: ``Integer`` + + Default: ``0`` + +``timeBinSize`` — *The size of time bins in seconds.* + This parameter dictates the time resolution of the resulting data + The time information stored will be the starting time of the time bins + For exemple with a timeBinSize of 3600, the data will be analysed using the following timeBins: + 0, 3600, 7200, ..., 79200, 82800 + + Type: ``Integer`` + + Default: ``3600`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Geometric_Tools/Change_SRID.rst b/Docs/functions/Geometric_Tools/Change_SRID.rst new file mode 100644 index 000000000..fcbd8639c --- /dev/null +++ b/Docs/functions/Geometric_Tools/Change_SRID.rst @@ -0,0 +1,42 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Change SRID +=========== + +Change or set SRID + +Overview +-------- + +➡️ Assign a new Spatial Reference Identifier (SRID) to the specified table +🚨 If the table: - has already an associated SRID: the new SRID is applied to the table and a reprojection of geometries is done, - has no associated SRID: the new SRID is applied to the table but without doing a reprojection of geometries. + +.. figure:: change_SRID.png + :align: center + :alt: Change SRID + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``newSRID`` — *Projection identifier* + 🌍 New projection identifier (also called SRID) of your table. It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Pseudo-Mercator projection) + + Type: ``Integer`` + +``tableName`` — *Name of the table* + Name of the table you want to change the SRID (and reproject if the table has already a SRID) + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Geometric_Tools/Clean_Buildings_Table.rst b/Docs/functions/Geometric_Tools/Clean_Buildings_Table.rst new file mode 100644 index 000000000..80f284277 --- /dev/null +++ b/Docs/functions/Geometric_Tools/Clean_Buildings_Table.rst @@ -0,0 +1,31 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Clean Buildings Table +===================== + +Overview +-------- + +➡️ Clean the BUILDINGS table, avoiding overlapping areas and unclosed polygons. +NoiseModelling propagation code does not support intersecting polygons well ✅ The input table will be erased and replaced by the cleaned one. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableName`` — *Buildings table name* + Name of the Buildings table. The table must be projected in a metric coordinate system (SRID). Use "Change_SRID" WPS Block if needed. The table shall contain: - THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON).- HEIGHT : the height of the building (FLOAT) + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Geometric_Tools/Enrich_DEM.rst b/Docs/functions/Geometric_Tools/Enrich_DEM.rst new file mode 100644 index 000000000..009c31244 --- /dev/null +++ b/Docs/functions/Geometric_Tools/Enrich_DEM.rst @@ -0,0 +1,126 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Enrich DEM +========== + +Overview +-------- + +➡️ Insert altimetric points coming from input layers into the input DEM. +This script works with five input layers: + +* Digital Elevation Model (DEM) to be enriched + +* Orographic lines + +* Hydrograpic network + +* Roads + +* Railways + +And six parameters: + +* Road width (roadWidth): Name of column where the road width is stored (Mandatory) + +* Roads platform height (hRoad) (Optional). Default value = 0m + +* Railroads right-of-way (railWidth): Name of column where the railroad right-of-way is stored (Mandatory) + +* Rail platform height (hRail) (Optional). Default value = 0.5m + +* Input SRID (inputSRID): SRID of the input tables (Optional) + +* Output suffixe (outputSuffixe): Suffixe applied at the end of the resuling table name (Optional). If not specified, "ENRICHED" is applied + +In the schema below, orange points will be inserted into the DEM. d2, d3 and d4 are deduced from the information provided in the parameter railWidth, using the following formula: + +* d2 = (railWidth - 5.5)/2 + +* d3 = (railWidth - 4)/2 + +* d4 = (railWidth)/2 + +.. figure:: railway_plateform.png + :align: center + :alt: Railways platform + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``inputDEM`` — *Input DEM table* + Name of the input DEM table to be enriched + + Type: ``String`` + +``inputHydro`` — *Input hydrographic table* + Name of the input hydrographic network table + + Type: ``String`` + +``inputOro`` — *Input orography table* + Name of the input orography table + + Type: ``String`` + +``inputRail`` — *Input railways table* + Name of the input railways table + + Type: ``String`` + +``inputRoad`` — *Input roads table* + Name of the input roads table + + Type: ``String`` + +``railWidth`` — *Railways width* + Name of column where the railways width is stored + + Type: ``String`` + +``roadWidth`` — *Road width* + Name of column where the road width is stored + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``hRail`` — *Railways platform height* + Railways platform height (in meters) (Optional) + + Type: ``double`` + + Default: ``0.5`` + +``hRoad`` — *Roads platform height* + Roads platform height (in meters) (Optional) + + Type: ``Double`` + + Default: ``0`` + +``inputSRID`` — *Input SRID* + 🌍 SRID of the input tables. 🛠 If not specified, the SRID from DEM layer is applied. If DEM has no SRID, 0 is applied + + Type: ``Integer`` + +``outputSuffixe`` — *Output suffix* + Suffix applied at the end of the resulting table name + + Type: ``String`` + + Default: ``ENRICHED`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Geometric_Tools/Enrich_DEM_with_lines.rst b/Docs/functions/Geometric_Tools/Enrich_DEM_with_lines.rst new file mode 100644 index 000000000..a776f97bb --- /dev/null +++ b/Docs/functions/Geometric_Tools/Enrich_DEM_with_lines.rst @@ -0,0 +1,70 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Enrich DEM with lines +===================== + +Overview +-------- + +➡️ Insert altimetric points coming from linestring input layers into the input DEM. +This script works with two input layers: + +* Digital Elevation Model (DEM) to be enriched + +* A linestring layer (e.g: hydrographic network, ...) in which coordinates have a Z dimension + +And three optional parameters: + +* Input SRID (inputSRID): SRID of the input tables + +* Source (source): Text indicating the source of the linestring layer. Can be useful to distinguish the points in the resulting DEM . If not specified, "LINESTRING" is applied + +* Output suffix (outputsuffix): suffix applied at the end of the resuling table name. If not specified, "ENRICHED" is applied + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``inputDEM`` — *Input DEM table* + Name of the input DEM table to be enriched + + Type: ``String`` + +``inputLine`` — *Input Linestring table* + Name of the input Linestring table + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``inputSRID`` — *Input SRID* + 🌍 SRID of the input tables. 🛠 If not specified, the SRID from DEM layer is applied. If DEM has no SRID, 0 is applied + + Type: ``Integer`` + +``outputsuffix`` — *Output suffix* + Suffix applied at the end of the resulting table name + + Type: ``String`` + + Default: ``ENRICHED`` + +``source`` — *Source* + Text indicating the source of the linestring layer (Optional) + + Type: ``String`` + + Default: ``LINESTRING`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Geometric_Tools/Enrich_DEM_with_rail.rst b/Docs/functions/Geometric_Tools/Enrich_DEM_with_rail.rst new file mode 100644 index 000000000..4d9e2b672 --- /dev/null +++ b/Docs/functions/Geometric_Tools/Enrich_DEM_with_rail.rst @@ -0,0 +1,91 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Enrich DEM with rail +==================== + +Enrich DEM with railways + +Overview +-------- + +➡️ Insert altimetric points coming from railways into the input DEM. +This script works with two input layers: + +* Digital Elevation Model (DEM) to be enriched + +* Railways + +And four parameters: + +* Railroads right-of-way (railWidth): Name of column where the railroad right-of-way is stored (Mandatory) + +* Rail platform height (hRail): Railways platform height (Optional). Default value = 0.5m + +* Input SRID (inputSRID): SRID of the input tables (Optional) + +* Output suffix (outputsuffix): suffix applied at the end of the resuling table name (Optional). If not specified, "ENRICHED" is applied + +In the schema below, orange points will be inserted into the DEM. d2, d3 and d4 are deduced from the information provided in the parameter railWidth, using the following formula: + +* d2 = (railWidth - 5.5)/2 + +* d3 = (railWidth - 4)/2 + +* d4 = (railWidth)/2 + +.. figure:: railway_plateform.png + :align: center + :alt: Railways platform + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``inputDEM`` — *Input DEM table* + Name of the input DEM table to be enriched + + Type: ``String`` + +``inputRail`` — *Input railways table* + Name of the input railways table + + Type: ``String`` + +``railWidth`` — *Railways width* + Name of column where the railways width is stored + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``hRail`` — *Railways platform height* + Railways platform height (in meters) (Optional) + + Type: ``double`` + + Default: ``0.5`` + +``inputSRID`` — *Input SRID* + 🌍 SRID of the input tables. 🛠 If not specified, the SRID from DEM layer is applied. If DEM has no SRID, 0 is applied + + Type: ``Integer`` + +``outputsuffix`` — *Output suffix* + Suffix applied at the end of the resulting table name 🛠 If not specified, "ENRICHED" is applied + + Type: ``String`` + + Default: ``ENRICHED`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Geometric_Tools/Enrich_DEM_with_road.rst b/Docs/functions/Geometric_Tools/Enrich_DEM_with_road.rst new file mode 100644 index 000000000..ce1417169 --- /dev/null +++ b/Docs/functions/Geometric_Tools/Enrich_DEM_with_road.rst @@ -0,0 +1,79 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Enrich DEM with road +==================== + +Enrich DEM with roads + +Overview +-------- + +➡️ Insert altimetric points coming from roads into the input DEM. +This script works with two input layers: + +* Digital Elevation Model (DEM) to be enriched + +* Roads + +And four parameters: + +* Roads right-of-way (roadWidth): Name of column where the road right-of-way is stored (Mandatory) + +* Road platform height (hRoad): Roads platform height (Optional). Default value = 0.0m + +* Input SRID (inputSRID): SRID of the input tables (Optional) + +* Output suffix (outputSuffix): Suffix applied at the end of the resulting table name (Optional). If not specified, "ENRICHED" is applied + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``inputDEM`` — *Input DEM table* + Name of the input DEM table to be enriched + + Type: ``String`` + +``inputRoad`` — *Input roads table* + Name of the input roads table + + Type: ``String`` + +``roadWidth`` — *Road width* + Name of column where the road width is stored + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``hRoad`` — *Roads platform height* + Roads platform height (in meters) (Optional) + + Type: ``Double`` + + Default: ``0`` + +``inputSRID`` — *Input SRID* + 🌍 SRID of the input tables. 🛠 If not specified, the SRID from DEM layer is applied. If DEM has no SRID, 0 is applied + + Type: ``Integer`` + +``outputSuffix`` — *Output suffix* + Suffix applied at the end of the resulting table name + + Type: ``String`` + + Default: ``ENRICHED`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Geometric_Tools/Enrich_Landcover_with_rail.rst b/Docs/functions/Geometric_Tools/Enrich_Landcover_with_rail.rst new file mode 100644 index 000000000..879246ed4 --- /dev/null +++ b/Docs/functions/Geometric_Tools/Enrich_Landcover_with_rail.rst @@ -0,0 +1,89 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Enrich Landcover with rail +========================== + +Enrich Landcover with railways + +Overview +-------- + +➡️ Insert rail ground surfaces into the input LANDCOVER. +This script works with two input layers: + +* Landcover to be enriched + +* Railways + +And four parameters: + +* Railroads right-of-way (railWidth): Name of column where the railroad right-of-way is stored (Mandatory) + +* Rail platform height (hRail): Railways platform height (Optional). Default value = 0.5m + +* Input SRID (inputSRID): SRID of the input tables (Optional) + +* Output suffix (outputsuffix): suffix applied at the end of the resuling table name (Optional). If not specified, "ENRICHED" is applied + +In the schema below, orange points will be inserted into the DEM. d2, d3 and d4 are deduced from the information provided in the parameter railWidth, using the following formula: + +* d2 = (railWidth - 5.5)/2 + +* d3 = (railWidth - 4)/2 + +* d4 = (railWidth)/2 + +.. figure:: railway_plateform.png + :align: center + :alt: Railways platform + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``gColumn`` — *G column* + Ground absorption coefficient (G) column name + + Type: ``String`` + +``inputLandcover`` — *Input landcover table* + Name of the input landcover table + + Type: ``String`` + +``inputRail`` — *Input railways table* + Name of the input railways table + + Type: ``String`` + +``railWidth`` — *Railways width* + Name of column where the railways width is stored + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``inputSRID`` — *Input SRID* + 🌍 SRID of the input tables. 🛠 If not specified, the SRID from DEM layer is applied. If DEM has no SRID, 0 is applied + + Type: ``Integer`` + +``outputsuffix`` — *Output suffix* + Suffix applied at the end of the resulting table name + + Type: ``String`` + + Default: ``ENRICHED`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Geometric_Tools/Point_Source_0dB_From_Network.rst b/Docs/functions/Geometric_Tools/Point_Source_0dB_From_Network.rst new file mode 100644 index 000000000..1d3ba4682 --- /dev/null +++ b/Docs/functions/Geometric_Tools/Point_Source_0dB_From_Network.rst @@ -0,0 +1,45 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Point Source 0dB From Network +============================= + +Create 0 dB Source From Roads + +Overview +-------- + +➡️ Creates a SOURCE table from a ROAD table. +The SOURCE table can then be used in the Noise_level_from_source WPS block with the "confExportSourceId" set to true. The Noise_level_from_source output will contain a list of "source-receiver" attenuation matrix independent of the source absolute noise power levels. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableRoads`` — *Input table name* + Name of the Roads table. + + Must contain at least:- PK: identifier with a Primary Key constraint- THE_GEOM: geometric column + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``gridStep`` + Distance between location of vehicle along the network in meters. + + Type: ``Integer`` + + Default: ``10`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Geometric_Tools/Screen_to_building.rst b/Docs/functions/Geometric_Tools/Screen_to_building.rst new file mode 100644 index 000000000..0a0560d5d --- /dev/null +++ b/Docs/functions/Geometric_Tools/Screen_to_building.rst @@ -0,0 +1,41 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Screen to building +================== + +Convert screens to building format + +Overview +-------- + +➡️ Convert the screens to the building format. +A width of 10 cm will be defined. If you also give a building table, this WPS script allows you to merge the two layers together. Tables must be projected in a same metric coordinate system (SRID). Use "Change_SRID" WPS Block if needed. ✅ The output table is called : BUILDINGS_SCREENS and contain: - THE_GEOM : the 2D geometry of the created table (POLYGON or MULTIPOLYGON). - HEIGHT : the height of the created polygons (FLOAT) + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableScreens`` — *Screens table name* + Name of the Screens table. The table must contain: - THE_GEOM : the 2D geometry of the screens (POLYGON or MULTIPOLYGON). - HEIGHT : the height of the screens (FLOAT) + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``tableBuilding`` — *Buildings table name* + Name of the Buildings table. The table must contain: - THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON). - HEIGHT : the height of the building (FLOAT) + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Geometric_Tools/Set_Height.rst b/Docs/functions/Geometric_Tools/Set_Height.rst new file mode 100644 index 000000000..328e5cac2 --- /dev/null +++ b/Docs/functions/Geometric_Tools/Set_Height.rst @@ -0,0 +1,43 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Set Height +========== + +Overview +-------- + +➡️ Update the geometry by adding a height from the column in the input table that contains the heights or elevations or from a static value. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableName`` — *Name of the table* + Name of the table on which the height will be modified. + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``height`` — *New height* + New height for the input table (in meters) (FLOAT) + + Type: ``Double`` + +``heightColumn`` + The column name in the input table that contains the heights + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Geometric_Tools/Simplify_Geometries.rst b/Docs/functions/Geometric_Tools/Simplify_Geometries.rst new file mode 100644 index 000000000..221fb42b5 --- /dev/null +++ b/Docs/functions/Geometric_Tools/Simplify_Geometries.rst @@ -0,0 +1,48 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Simplify Geometries +=================== + +Overview +-------- + +➡️ Use Douglas-Peucker algorithm to simplify geometries in the selected table. +✅ The input table geometries will be updated. + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableName`` — *Name of the table* + Name of the table on which geometries will be simplified + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``distanceTolerance`` — *Distance tolerance* + Sets the tolerance distance for the simplification (FLOAT) + + Type: ``Double`` + + Default: ``1`` + +``preserveTopology`` — *Preserve topology ?* + Do you want to preserve topology? + + Type: ``Boolean`` + + Default: ``false`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/wpsbuilder/wps_images/change_SRID.png b/Docs/functions/Geometric_Tools/change_SRID.png similarity index 100% rename from wpsbuilder/wps_images/change_SRID.png rename to Docs/functions/Geometric_Tools/change_SRID.png diff --git a/wpsbuilder/wps_images/railway_plateform.png b/Docs/functions/Geometric_Tools/railway_plateform.png similarity index 100% rename from wpsbuilder/wps_images/railway_plateform.png rename to Docs/functions/Geometric_Tools/railway_plateform.png diff --git a/wpsbuilder/wps_images/train_plateforme.png b/Docs/functions/Geometric_Tools/train_plateforme.png similarity index 100% rename from wpsbuilder/wps_images/train_plateforme.png rename to Docs/functions/Geometric_Tools/train_plateforme.png diff --git a/Docs/functions/Import_and_Export/Export_Table.rst b/Docs/functions/Import_and_Export/Export_Table.rst new file mode 100644 index 000000000..fdb7e4de4 --- /dev/null +++ b/Docs/functions/Import_and_Export/Export_Table.rst @@ -0,0 +1,40 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Export Table +============ + +Overview +-------- + +➡️ Export table from the database into a local file. +Valid file extensions: csv, dbf, geojson, gpx, bz2, gz, osm, shp, tsv, fgb + +.. figure:: export_table.png + :align: center + :alt: Export table + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``exportPath`` — *Path of the file you want to export* + 📂 Path of the file, including its extension. For example: c:/home/receivers.geojson + + Type: ``String`` + +``tableToExport`` — *Name of the table* + Table Name or SQL Query Option 1: Simple table name Enter the name of an existing table, e.g.: mytable Option 2: SQL query with parenthesis Wrap your SELECT query in parenthesis to export filtered or joined data Example: (SELECT * FROM mytable WHERE field = 1) + + Type: ``String`` + +Output +------ + +``result`` — *Exported table name* + The name of the exported table, can be used as input for another process + + Type: ``String`` + diff --git a/Docs/functions/Import_and_Export/Import_Asc_File.rst b/Docs/functions/Import_and_Export/Import_Asc_File.rst new file mode 100644 index 000000000..4dcb1c265 --- /dev/null +++ b/Docs/functions/Import_and_Export/Import_Asc_File.rst @@ -0,0 +1,57 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Import Asc File +=============== + +Import Asc File. + +Overview +-------- + +➡️ Import ESRI Ascii Raster file and convert into a Digital Elevation Model (DEM) compatible with NoiseModelling (X,Y,Z). +Valid file extensions : asc and asc.gz . ✅ The output table is called: DEM and contain: - THE_GEOM: the 3D point cloud of the DEM (POINT) + +.. figure:: import_asc_file.png + :align: center + :alt: Import asc file + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``pathFile`` — *Path of the ESRI Ascii Raster file* + 📂 Path of the ESRI Ascii Raster file you want to import, including its extension. Files can be gzip compressed. For example: c:/home/receivers.asc or c:/home/receivers.asc.gz + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``downscale`` — *Skip pixels on each axis* + Divide the number of rows and columns read by the following coefficient (FLOAT) + + Type: ``Integer`` + + Default: ``1.0`` + +``fence`` — *Fence geometry* + Create DEM table only in the provided polygon + + Type: ``Geometry`` + +``inputSRID`` — *Projection identifier* + 🌍 Original projection identifier (also called SRID) of the .asc files. It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Pseudo-Mercator projection) + + Type: ``Integer`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Import_and_Export/Import_Asc_Folder.rst b/Docs/functions/Import_and_Export/Import_Asc_Folder.rst new file mode 100644 index 000000000..915547871 --- /dev/null +++ b/Docs/functions/Import_and_Export/Import_Asc_Folder.rst @@ -0,0 +1,52 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Import Asc Folder +================= + +Import all .asc files from a folder + +Overview +-------- + +➡️ Import all files with .asc extension from a folder to the database +✅ The resulting tables will have the same name as the input files + +.. figure:: import_asc_folder.png + :align: center + :alt: Import asc folder + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``pathFolder`` — *Path of the folder* + 📂 Path of the folder For example: c:/home/inputdata/ + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``downscale`` — *Skip pixels on each axis* + Divide the number of rows and columns read by the following coefficient (FLOAT) + + Type: ``Integer`` + + Default: ``1.0`` + +``inputSRID`` — *Projection identifier* + 🌍 Original projection identifier (also called SRID) of the .asc file. It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Pseudo-Mercator projection) + + Type: ``Integer`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Import_and_Export/Import_File.rst b/Docs/functions/Import_and_Export/Import_File.rst new file mode 100644 index 000000000..07a845a34 --- /dev/null +++ b/Docs/functions/Import_and_Export/Import_File.rst @@ -0,0 +1,57 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Import File +=========== + +Overview +-------- + +➡️ Import file into the database. +Valid file extensions: csv, dbf, geojson, json, geojson.gz, gpx, osm.bz2, osm.gz, osm, shp, tsv + +.. figure:: import_file.png + :align: center + :alt: Import file + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``pathFile`` — *Path of the input File* + 📂 Path of the file you want to import, including its extension. For example: c:/home/buildings.geojson + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``ifTableExists`` — *Table exists operation* + What to do if a table with the same name already exists ? + + Type: ``String`` + + Default: ``Overwrite`` + + Allowed values: ``Skip import``, ``Overwrite``, ``Raise error`` + +``inputSRID`` — *Projection identifier* + 🌍 Original projection identifier (also called SRID) of your table. It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Pseudo-Mercator projection). This entry is optional because many formats already include the projection and you can also import files without geometry attributes. If the table is geometric and if this parameter is not filled and:- the file has a .prj file associated: the SRID is deduced from the .prj - the file has no .prj file associated: we apply the WGS84 (EPSG:4326) code + + Type: ``Integer`` + +``tableName`` — *Name of created table* + Name of the table you want to create from the file. 🛠 + + Type: ``String`` + +Output +------ + +``outputTable`` — *Name of the created table* + Name of the created table + + Type: ``String`` + diff --git a/Docs/functions/Import_and_Export/Import_Folder.rst b/Docs/functions/Import_and_Export/Import_Folder.rst new file mode 100644 index 000000000..3a51d1239 --- /dev/null +++ b/Docs/functions/Import_and_Export/Import_Folder.rst @@ -0,0 +1,50 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Import Folder +============= + +Import all files from a folder + +Overview +-------- + +➡️ Import all files with a specified extension from a folder to the database. +Valid file extensions: csv, dbf, geojson, gpx, bz2, gz, osm, shp, tsv. ✅ The resulting tables will have the same name as the input files + +.. figure:: import_folder.png + :align: center + :alt: Import folder + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``importExt`` — *Extension to import* + Extension to import. For example: shp + + Type: ``String`` + +``pathFolder`` — *Path of the folder* + 📂 Path of the folder For example : c:/home/inputdata/ + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``inputSRID`` — *Projection identifier* + 🌍 Original projection identifier (also called SRID) of your table. It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Pseudo-Mercator projection). This entry is optional because many formats already include the projection and you can also import files without geometry attributes. If the table is geometric and if this parameter is not filled and:- the file has a .prj file associated: the SRID is deduced from the .prj - the file has no .prj file associated: we apply the WGS84 (EPSG:4326) code + + Type: ``Integer`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Import_and_Export/Import_OSM.rst b/Docs/functions/Import_and_Export/Import_OSM.rst new file mode 100644 index 000000000..2b3aa1185 --- /dev/null +++ b/Docs/functions/Import_and_Export/Import_OSM.rst @@ -0,0 +1,144 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Import OSM +========== + +Import BUILDINGS, GROUND and ROADS tables from OSM + +Overview +-------- + +➡️ Convert .osm, .osm.gz or .osm.pbf file into NoiseModelling input tables. We recommend using OSMBBBike : https://extract.bbbike.org/ +The following output tables will be created: +- BUILDINGS : a table containing the buildings +- GROUND : a table containing ground acoustic absorption, based on OSM landcover surfaces +- ROADS : a table containing the roads. As OSM does not include data on road traffic flows, default values are assigned according to the -Good Practice Guide for Strategic Noise Mapping and the Production of Associated Data on Noise Exposure - Version 2 + +💡 The user can choose to avoid creating some of these tables by checking the dedicated boxes + +.. figure:: import_osm_file.png + :align: center + :alt: Import OSM file + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``pathFile`` — *Path of the OSM file* + 📂 Path of the OSM file, including its extension (.osm, .osm.gz or .osm.pbf). + For example: c:/home/area.osm.pbf + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``eliminateNoTrafficRoads`` — *Eliminate no traffic roads* + If checked, only roads with these "TYPE" values will remain: + - bus_guideway: Dedicated lanes or tracks for buses + - busway: Bus-only lanes + - living_street: Residential streets with pedestrian priority + - motorway: High-speed, restricted-access highways + - motorway_link: Connector ramps for motorways + - primary: Major roads linking large cities + - primary_link: Connector ramps for primary roads + - raceway: Racing tracks + - residential: Roads in residential areas + - road: Generic roads + - secondary: Roads connecting smaller towns + - secondary_link: Connector ramps for secondary roads + - service: Service lanes (access to parking lots, etc.) + - tertiary: Roads connecting villages and hamlets + - tertiary_link: Connector ramps for tertiary roads + - trunk: Important roads that are not motorways + - trunk_link: Connector ramps for trunk roads + - unclassified: Minor roads not fitting higher classifications + - rest_area: Areas for rest along roads + - traffic_calming: Traffic calming features (speed bumps, etc.) + - traffic_island: Traffic islands + + If not checked, all roads are processed as before. + + Type: ``Boolean`` + + Default: ``false`` + +``ignoreBuilding`` — *Do not import Buildings* + ✅ If the box is checked → the table BUILDINGS will NOT be created. + + 🟩 If the box is NOT checked → the table BUILDINGS will be created and will contain: + - PK : An identifier. It shall be a primary key (INTEGER, PRIMARY KEY) + - THE_GEOM : The 2D geometry of the building (POLYGON or MULTIPOLYGON). + - HEIGHT : The height of the building (FLOAT). If this information is not available then it is deduced from the number of floors (if available) with the addition of a small random variation from one building to another. Finally, if no information is available, a height of 5m is set by default. + + Type: ``Boolean`` + + Default: ``false`` + +``ignoreGround`` — *Do not import Surface acoustic absorption* + ✅ If the box is checked → the table GROUND will NOT be created. + + 🟩 If the box is NOT checked → the table GROUND will be created and will contain: + - PK : An identifier. It shall be a primary key (INTEGER, PRIMARY KEY) + - ID_WAY : OSM identifier (INTEGER) + - THE_GEOM : The 2D geometry of the sources (POLYGON or MULTIPOLYGON) + - PRIORITY : Since NoiseModelling does not allowed overlapping geometries, if this is the case, this column is used to prioritize the geometry that will win over the other one when cutting. The order is given according to the type of land use + - G : The acoustic absorption of a ground (FLOAT) (between 0 : very hard and 1 : very soft) + + Type: ``Boolean`` + + Default: ``false`` + +``ignoreRoads`` — *Do not import Roads* + ✅ If the box is checked → the table ROADS will NOT be created. + + 🟩 If the box is NOT checked → the table ROADS will be created and will contain: + - PK : An identifier. It shall be a primary key (INTEGER, PRIMARY KEY) + - ID_WAY : OSM identifier (INTEGER) + - THE_GEOM : The 2D geometry of the sources (LINESTRING or MULTILINESTRING) + - LV_D : Hourly average light and heavy vehicle count (6-18h) (DOUBLE) + - LV_E : Hourly average light and heavy vehicle count (18-22h) (DOUBLE) + - LV_N : Hourly average light and heavy vehicle count (22-6h) (DOUBLE) + - HGV_D : Hourly average heavy vehicle count (6-18h) (DOUBLE) + - HGV_E : Hourly average heavy vehicle count (18-22h) (DOUBLE) + - HGV_N : Hourly average heavy vehicle count (22-6h) (DOUBLE) + - LV_SPD_D : Hourly average light vehicle speed (6-18h) (DOUBLE) + - LV_SPD_E : Hourly average light vehicle speed (18-22h) (DOUBLE) + - LV_SPD_N : Hourly average light vehicle speed (22-6h) (DOUBLE) + - HGV_SPD_D : Hourly average heavy vehicle speed (6-18h) (DOUBLE) + - HGV_SPD_E : Hourly average heavy vehicle speed (18-22h) (DOUBLE) + - HGV_SPD_N : Hourly average heavy vehicle speed (22-6h) (DOUBLE) + - PVMT : CNOSSOS road pavement identifier (ex: NL05) (VARCHAR) + + 💡 These information are deduced from the roads importance in OSM.. + + Type: ``Boolean`` + + Default: ``false`` + +``removeTunnels`` — *Remove tunnels from OSM data* + ✅ If checked, remove roads from OSM data that contain OSM tag tunnel=yes. + + Type: ``Boolean`` + + Default: ``false`` + +``targetSRID`` — *Target projection identifier* + 🌍 Target projection identifier (also called SRID) of your table. + It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Web Mercator projection). + + 🚨 The target SRID must be in metric coordinates. + + Type: ``Integer`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Import_and_Export/Import_OSM_Pedestrian.rst b/Docs/functions/Import_and_Export/Import_OSM_Pedestrian.rst new file mode 100644 index 000000000..88eb85e33 --- /dev/null +++ b/Docs/functions/Import_and_Export/Import_OSM_Pedestrian.rst @@ -0,0 +1,45 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Import OSM Pedestrian +===================== + +Import Pedestrian tables from OSM + +Overview +-------- + +➡️ Convert .osm, .osm.gz or .osm.pbf file into NoiseModelling input tables. + +The following output tables will be created: +- BUILDINGS : a table containing the buildings +💡 The user can choose to avoid creating some of these tables by checking the dedicated boxes + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``pathFile`` — *Path of the OSM file* + 📂 Path of the OSM file, including its extension (.osm, .osm.gz or .osm.pbf). + For example: c:/home/area.osm.pbf + + Type: ``String`` + +``targetSRID`` — *Target projection identifier* + 🌍 Target projection identifier (also called SRID) of your table. + It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Web Mercator projection). + + ❗ The target SRID must be in metric coordinates. + + Type: ``Integer`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Import_and_Export/Import_Symuvia.rst b/Docs/functions/Import_and_Export/Import_Symuvia.rst new file mode 100644 index 000000000..9250f065f --- /dev/null +++ b/Docs/functions/Import_and_Export/Import_Symuvia.rst @@ -0,0 +1,45 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Import Symuvia +============== + +Import Symuvia File + +Overview +-------- + +➡️ Import Symuvia outputs (as .xml) into the database + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``pathFile`` — *Path of the input File* + 📂 Path of the input File (including extension .xml) For example: c:/home/mysymuviafile.xml + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``inputSRID`` — *Symuvia output file SRID* + Symuvia output file SRID 🛠 + + Type: ``Integer`` + +``tableName`` — *Name of created table* + Do not write the name of a table that contains a space 🛠 + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/Import_and_Export/Linked_Table.rst b/Docs/functions/Import_and_Export/Linked_Table.rst new file mode 100644 index 000000000..59287b8c2 --- /dev/null +++ b/Docs/functions/Import_and_Export/Linked_Table.rst @@ -0,0 +1,83 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Linked Table +============ + +Overview +-------- + +➡️ Create a table into the database linked to an external database. The data is not stored into the database + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``databaseUrl`` — *Database URL* + Connection url of the database. For PostGIS + jdbc:postgresql_h2://hostname:5432/databaseName. For H2 + jdbc:h2:tcp://localhost/D:/data/test + + Type: ``String`` + +``localTableName`` — *Name of created table* + Name of the local linked table. + + Type: ``String`` + +``password`` — *User password* + User password when connecting to the external database + + Type: ``String`` + +``remoteTableName`` — *External table name* + External Table name or query. If a query is used instead of the original table name, then the table is read only. Queries must be enclosed in parenthesis: (SELECT * FROM ORDERS). + + Type: ``String`` + +``username`` — *User name* + User name when connecting to the external database + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``driverClass`` — *Driver name* + Name of the class to connect to the external database. + + Type: ``String`` + + Default: ``org.h2gis.postgis_jts.Driver`` + + Allowed values: ``org.h2gis.postgis_jts.Driver``, ``org.h2.Driver`` + +``fetchSize`` — *Fetch size* + the number of rows fetched, a hint with non-negative number of rows to fetch from the external table at once, may be ignored by the driver of external database. 0 is default and means no hint. The value is passed to java.sql.Statement.setFetchSize() method. + + Type: ``Integer`` + + Default: ``0`` + +``force`` — *Force* + Create the LINKED TABLE even if the remote database/table does not exist. + + Type: ``Boolean`` + +``remoteSchemaName`` — *External table schema* + External Table Schema ex: public + + Type: ``String`` + + Default: ``public`` + +Output +------ + +``result`` — *Local table name* + The name of the local linked table, can be used as an input for another process + + Type: ``String`` + diff --git a/wpsbuilder/wps_images/export_table.png b/Docs/functions/Import_and_Export/export_table.png similarity index 100% rename from wpsbuilder/wps_images/export_table.png rename to Docs/functions/Import_and_Export/export_table.png diff --git a/wpsbuilder/wps_images/import_asc_file.png b/Docs/functions/Import_and_Export/import_asc_file.png similarity index 100% rename from wpsbuilder/wps_images/import_asc_file.png rename to Docs/functions/Import_and_Export/import_asc_file.png diff --git a/wpsbuilder/wps_images/import_asc_folder.png b/Docs/functions/Import_and_Export/import_asc_folder.png similarity index 100% rename from wpsbuilder/wps_images/import_asc_folder.png rename to Docs/functions/Import_and_Export/import_asc_folder.png diff --git a/wpsbuilder/wps_images/import_file.png b/Docs/functions/Import_and_Export/import_file.png similarity index 100% rename from wpsbuilder/wps_images/import_file.png rename to Docs/functions/Import_and_Export/import_file.png diff --git a/wpsbuilder/wps_images/import_folder.png b/Docs/functions/Import_and_Export/import_folder.png similarity index 100% rename from wpsbuilder/wps_images/import_folder.png rename to Docs/functions/Import_and_Export/import_folder.png diff --git a/wpsbuilder/wps_images/import_osm_file.png b/Docs/functions/Import_and_Export/import_osm_file.png similarity index 100% rename from wpsbuilder/wps_images/import_osm_file.png rename to Docs/functions/Import_and_Export/import_osm_file.png diff --git a/Docs/functions/NoiseModelling/Atmospheric_Template.rst b/Docs/functions/NoiseModelling/Atmospheric_Template.rst new file mode 100644 index 000000000..c3ea8e0ed --- /dev/null +++ b/Docs/functions/NoiseModelling/Atmospheric_Template.rst @@ -0,0 +1,60 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Atmospheric Template +==================== + +Generate default atmospheric settings from the PERIOD field of a noise emission table + +Overview +-------- + +➡️ Generate default atmospherics settings from the PERIOD field of a noise emission table. It is used to export the result table to be edited and reimported to be used into Noise_level_from_source. This table make you able to change the temperature and other settings for each time period of the simulation + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableSourcesEmission`` — *Sources emission table name* + Name of the Sources table (ex. SOURCES_EMISSION) The table must contain: + + * IDSOURCE * : an identifier. It shall be linked to the primary key of tableRoads (INTEGER) + + * PERIOD * : Time period, you will find this column on the output (VARCHAR) + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``tablePeriodAtmosphericSettings`` — *Atmospheric settings table name output for each time period* + Name of the Atmospheric settings table The table will contain the following columns: + + * PERIOD : time period (VARCHAR PRIMARY KEY) + + * WINDROSE : probability of occurrences of favourable propagation conditions (ARRAY(16)) + + * TEMPERATURE : Temperature in celsius (FLOAT) + + * PRESSURE : air pressure in pascal (FLOAT) + + * HUMIDITY : air humidity in percentage (FLOAT) + + * GDISC : choose between accept G discontinuity or not (BOOLEAN) default true + + * PRIME2520 : choose to use prime values to compute eq. 2.5.20 (BOOLEAN) default false + + Type: ``String`` + + Default: ``SOURCES_ATMOSPHERIC`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/NoiseModelling/Noise_level_from_source.rst b/Docs/functions/NoiseModelling/Noise_level_from_source.rst new file mode 100644 index 000000000..8d78ea555 --- /dev/null +++ b/Docs/functions/NoiseModelling/Noise_level_from_source.rst @@ -0,0 +1,264 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Noise level from source +======================= + +Computes the propagation from the sounds sources to the receivers + +Overview +-------- + +➡️ Computes the propagation from the sounds sources to the receivers location using the noise emission table. +🌍 Tables must be projected in a metric coordinate system (SRID). Use "Change_SRID" WPS Block if needed. ✅ The output table are called: RECEIVERS_LEVEL The output table contain: + +* IDRECEIVER: receiver an identifier (INTEGER) linked to RECEIVERS table primary key + +* IDSOURCE: source identifier (INTEGER) linked to SOURCES_GEOM primary key. Only if Keep source id is checked. + +* PERIOD : Time period (VARCHAR) ex. L D E and DEN. Only if you provide emission power to sources or the atmospheric settings table. + +* THE_GEOM : the 3D geometry of the receivers with the Z as the altitude (POINTZ) + +* Hz63, Hz125, Hz250, Hz500, Hz1000,Hz2000, Hz4000, Hz8000 : 8 columns giving the sound level for each octave band (FLOAT) + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableBuilding`` — *Buildings table name* + 🏠 Name of the Buildings table The table must contain: + + * THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON) + + * HEIGHT : the height of the building (FLOAT) + + * G : Optional, Wall absorption value if g is [0, 1] or wall surface impedance ([N.s.m-4] static air flow resistivity of material) if G is [20, 20000] (default is 0.1 if the column G does not exists) (FLOAT) + + Type: ``String`` + +``tableReceivers`` — *Receivers table name* + Name of the Receivers table The table must contain: + + * PK : an identifier. It shall be a primary key (INTEGER, PRIMARY KEY) + + * THE_GEOM : the 3D geometry of the sources (POINT, MULTIPOINT) + + 💡 This table can be generated from the WPS Blocks in the "Receivers" folder + + Type: ``String`` + +``tableSources`` — *Sources geometry table name* + Name of the Sources table (if only geometry is specified) The table must contain (* mandatory): + + * PK * : an identifier. It shall be a primary key (INTEGER, PRIMARY KEY) + + * THE_GEOM * : the 3D geometry of the sources (POINT, MULTIPOINT, LINESTRING, MULTILINESTRING). According to CNOSSOS-EU, you need to set a height of 0.05 m for a road traffic emission + + * HZD63, HZD125, HZD250, HZD500, HZD1000, HZD2000, HZD4000, HZD8000 : 8 columns giving the day emission sound level for each octave band (FLOAT) + + * HZE : 8 columns giving the evening emission sound level for each octave band (FLOAT) + + * HZN : 8 columns giving the night emission sound level for each octave band (FLOAT) + + * YAW : Source horizontal orientation in degrees. For points 0° North, 90° East. For lines 0° line direction, 90° right of the line direction. (FLOAT) + + * PITCH : Source vertical orientation in degrees. 0° front, 90° top, -90° bottom. (FLOAT) + + * ROLL : Source roll in degrees (FLOAT) + + * DIR_ID : identifier of the directivity sphere from tableSourceDirectivity parameter or train directivity if not provided -> OMNIDIRECTIONAL(0), ROLLING(1), TRACTIONA(2), TRACTIONB(3), AERODYNAMICA(4), AERODYNAMICB(5), BRIDGE(6) (INTEGER) + + 💡 This table can be generated from the WPS Block "Road_Emission_from_Traffic" + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``confDiffHorizontal`` — *Diffraction on horizontal edges* + Compute or not the diffraction on horizontal edges + + Type: ``Boolean`` + + Default: ``false`` + +``confDiffVertical`` — *Diffraction on vertical edges* + Compute or not the diffraction on vertical edges. Following Directive 2015/996, enable this option for rail and industrial sources only + + Type: ``Boolean`` + + Default: ``false`` + +``confExportSourceId`` — *Separate receiver level by source identifier* + Keep source identifier in output in order to get noise contribution of each noise source. When only the source geometry is given, the attenuation between each pair of "source-receiver" points is specified (commonly referred to as the "attenuation matrix") + + Type: ``Boolean`` + + Default: ``false`` + +``confFavourableOccurrencesDefault`` — *Probability of occurrences* + Comma-delimited string containing the probability ([0,1]) of occurrences of favourable propagation conditions. Follow the clockwise direction. The north slice is the last array index (n°16 in the schema below) not the first one. + + .. figure:: acoustics_parameters_confFavorableOccurrences.png + :align: center + :alt: Noise level from source + + Type: ``String`` + + Default: ``0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5`` + +``confHumidity`` — *Relative humidity* + 🌧 Humidity for noise propagation (%) [0,100] + + Type: ``Double`` + + Default: ``70`` + +``confMaxError`` — *Max Error (dB)* + Threshold for excluding negligible sound sources in calculations.This parameter is ignored if no emission level is specified or if you set it to 0 dB. This parameter have a great impact on computation time. + + Type: ``Double`` + + Default: ``0.1`` + +``confMaxReflDist`` — *Maximum source-reflexion distance* + Maximum search distance of walls / facades from the "Source-Receiver" segment, for the calculation of specular reflections (meters). + + .. figure:: acoustics_parameters_confMaxReflDist.png + :align: center + :alt: Noise level from source + + Type: ``Double`` + + Default: ``50`` + +``confMaxSrcDist`` — *Maximum source-receiver distance* + Maximum distance between source and receiver (FLOAT, in meters). + + .. figure:: acoustics_parameters_confMaxSrcDist.png + :align: center + :alt: Noise level from source + + Type: ``Double`` + + Default: ``150`` + +``confMinWallReflDist`` — *Ignore close reflections* + Optional maximum receiver-to-wall distance (meters) below which reflection cut profiles are ignored. With regard to the population’s exposure to noise, it is recommended that the contribution due to reflection off the façade wall of the building where the resident lives should be disregarded. If you have placed the receivers 0.1 m from the façades, you can set this parameter to 0.2 m. This offset is set to ensure that the contribution from the nearby wall is ignored. Use 0 to keep all reflections. + + Type: ``Double`` + + Default: ``0`` + +``confRaysName`` — *Export scene* + Save each mnt, buildings and propagation rays into the specified table (ex:RAYS) or file URL (ex: file:///Z:/dir/map.kml) You can set a table name here in order to save all the rays computed by NoiseModelling. The number of rays has been limited in this script in order to avoid memory exception. 🛠 If not provided, then do not keep rays + + Type: ``String`` + +``confReflOrder`` — *Order of reflexion* + Maximum number of reflections to be taken into account (INTEGER). 🚨 Adding 1 order of reflexion can significantly increase the processing time. + + Type: ``Integer`` + + Default: ``1`` + +``confTemperature`` — *Air temperature* + 🌡 Air temperature (°C) + + Type: ``Double`` + + Default: ``15`` + +``confThreadNumber`` — *Thread number* + Number of thread to use on the computer (INTEGER). 🛠 + + Type: ``Integer`` + + Default: ``0`` + +``frequencyFieldPrepend`` — *Frequency field name* + Frequency field name prepend. Ex. for 1000 Hz frequency the default column name is HZ1000. + + Type: ``String`` + + Default: ``HZ`` + +``paramWallAlpha`` — *Wall absorption coefficient* + Wall absorption coefficient [0,1] (between ``0`` : "fully reflective" and ``1`` : "fully absorbent") + + Type: ``Double`` + + Default: ``0.1`` + +``tableDEM`` — *DEM table name* + Name of the Digital Elevation Model (DEM) table The table must contain: + + * THE_GEOM : the 3D geometry of the sources (POINT, MULTIPOINT) + + 💡 This table can be generated from the WPS Block "Import_Asc_File" + + Type: ``String`` + +``tableGroundAbs`` — *Ground absorption table name* + Name of the surface/ground acoustic absorption table The table must contain: + + * THE_GEOM : the 2D geometry of the sources (POLYGON or MULTIPOLYGON) + + * G : the acoustic absorption of a ground (FLOAT between 0 : very hard and 1 : very soft) + + Type: ``String`` + +``tablePeriodAtmosphericSettings`` — *Atmospheric settings table name for each time period* + Name of the Atmospheric settings table The table must contain the following columns: + + * PERIOD : time period (VARCHAR PRIMARY KEY) + + * WINDROSE : probability of occurrences of favourable propagation conditions (ARRAY(16)) + + * TEMPERATURE : Temperature in celsius (FLOAT) + + * PRESSURE : air pressure in pascal (FLOAT) + + * HUMIDITY : air humidity in percentage (FLOAT) + + * GDISC : choose between accept G discontinuity or not (BOOLEAN) default true + + * PRIME2520 : choose to use prime values to compute eq. 2.5.20 (BOOLEAN) default false + + Type: ``String`` + +``tableSourceDirectivity`` — *Source directivity table name* + Name of the emission directivity table If not specified the default is train directivity of CNOSSOS-EU The table must contain the following columns: + + * DIR_ID : identifier of the directivity sphere (INTEGER) + + * THETA : [-90;90] Vertical angle in degree. 0° front 90° top -90° bottom (FLOAT) + + * PHI : [0;360] Horizontal angle in degree. 0° front 90° right (FLOAT) + + * HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000 : attenuation levels in dB for each octave or third octave (FLOAT) + + Type: ``String`` + +``tableSourcesEmission`` — *Sources emission table name* + Name of the Sources table (ex. SOURCES_EMISSION) The table must contain: + + * IDSOURCE * : an identifier. It shall be linked to the primary key of tableRoads (INTEGER) + + * PERIOD * : Time period, you will find this column on the output (VARCHAR) + + * HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000 : Emission noise level in dB can be third-octave 50Hz to 10000Hz (FLOAT) + + Type: ``String`` + +Output +------ + +``result`` — *Created table* + Name of the table containing the results of the computation. Can be used as input for another process. + + Type: ``String`` + diff --git a/Docs/functions/NoiseModelling/PlotDirectivity.rst b/Docs/functions/NoiseModelling/PlotDirectivity.rst new file mode 100644 index 000000000..43f9cf6f1 --- /dev/null +++ b/Docs/functions/NoiseModelling/PlotDirectivity.rst @@ -0,0 +1,81 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +PlotDirectivity +=============== + +Plots the directivity graph of the specified DIR_ID + +Overview +-------- + +➡️ Plots the directivity graph of the specified "DIR_ID" + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``confDirId`` — *Directivity Index* + Identifier of the directivity sphere from "tableSourceDirectivity" parameter or train directivity if "tableSourceDirectivity" parameter is not filled (INTEGER) In case of train, you can use these values: + + * 0 = OMNIDIRECTIONAL + + * 1 = ROLLING + + * 2 = TRACTIONA + + * 3 = TRACTIONB + + * 4 = AERODYNAMICA + + * 5 = AERODYNAMICB + + * 6 = BRIDGE + + Type: ``Integer`` + +``confFrequency`` — *Frequency* + Frequency to plot (INTEGER). 63, 125, 250, 500, 1000, 2000, 4000, 8000 (should match with the column of tableSourceDirectivity + + Type: ``Integer`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``confScaleMaximum`` — *Maximum scale attenuation (dB)* + Maximum scale attenuation (in dB) + + Type: ``Double`` + + Default: ``0`` + +``confScaleMinimum`` — *Minimum scale attenuation (dB)* + Minimum scale attenuation (in dB) + + Type: ``Double`` + + Default: ``-35`` + +``tableSourceDirectivity`` — *Source directivity table name* + Name of the emission directivity table.🛠 If not specified the default is train directivity of CNOSSOS-EU The table must contain the following columns: + + * DIR_ID : identifier of the directivity sphere (INTEGER) + + * THETA : [-90;90] Vertical angle in degree. 0° front 90° top -90° bottom (FLOAT) + + * PHI : [0;360] Horizontal angle in degree. 0° front 90° right (FLOAT) + + * LW63, LW125, LW250, LW500, LW1000, LW2000, LW4000, LW8000 : attenuation levels in dB for each octave or third octave (FLOAT). + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + Svg/Html of the directivity chart + + Type: ``String`` + diff --git a/Docs/functions/NoiseModelling/Railway_Emission_from_Traffic.rst b/Docs/functions/NoiseModelling/Railway_Emission_from_Traffic.rst new file mode 100644 index 000000000..e041c2082 --- /dev/null +++ b/Docs/functions/NoiseModelling/Railway_Emission_from_Traffic.rst @@ -0,0 +1,88 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Railway Emission from Traffic +============================= + +Compute railway emission noise map from vehicule, traffic table AND section table. + +Overview +-------- + +➡️ Compute Rail Emission Noise Map from Day, Evening and Night traffic flow rate and speed estimates (specific format, see input details). +✅ The output table is called LW_RAILWAY + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableRailwayTrack`` — *RailWay Track table name* + Name of the Railway Track table. + This function recognize the following columns (* mandatory): + + * IDSECTION* : A section identifier (PRIMARY KEY) (INTEGER) + + * NTRACK* : Number of tracks (INTEGER) + + * TRACKSPD* : Maximum speed on the section (in km/h) (DOUBLE) + + * TRANSFER : Track transfer function identifier, e.g. "SNCF5" or "EU7" (VARCHAR) + + * ROUGHNESS : Rail roughness identifier, e.g. "SNCF1" or "EU3" (VARCHAR) + + * IMPACT : Impact noise coefficient identifier, e.g. "SNCF1" or "EU1", empty for none (VARCHAR) + + * CURVATURE : Listed code describing the curvature of the section (INTEGER) + + * BRIDGE : Bridge transfer function identifier, e.g. "EU3", empty for none (VARCHAR) + + * TRACKSPD : Commercial speed on the section (in km/h) (DOUBLE) + + * ISTUNNEL : Indicates whether the section is a tunnel or not (0 = no / 1 = yes) (BOOLEAN) + + Type: ``String`` + +``tableRailwayTraffic`` — *Railway traffic table name* + Name of the Rail traffic table. + This function recognize the following columns (* mandatory): + + * IDTRAFFIC* : A traffic identifier (PRIMARY KEY) (INTEGER) + + * IDSECTION* : A section identifier, refering to RAIL_SECTIONS table (INTEGER) + + * TRAINTYPE* : Type of vehicle, listed in the Rail_Train_SNCF_2021 file (mainly for french SNCF) (STRING) + + * TRAINSPD* : Maximum Train speed (in km/h) (DOUBLE) + + * TDAY, TEVENING and TNIGHT : Hourly average train count (6-18h)(18-22h)(22-6h) (INTEGER) + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``railwayEmissionDataFile`` — *Railway emission data file* + URL of the railway emission data file in CNOSSOS format (json). By default, the file provided with NoiseModelling is used. + + Type: ``String`` + +``trainSetDataFile`` — *Railway train set data file* + URL of the railway train set data file in CNOSSOS format (json). By default, the file provided with NoiseModelling is used. + + Type: ``String`` + +``vehicleDataFile`` — *Railway vehicle data file* + URL of the railway vehicle data file in CNOSSOS format (json). By default, the file provided with NoiseModelling is used. + + Type: ``String`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/NoiseModelling/Road_Emission_from_Traffic.rst b/Docs/functions/NoiseModelling/Road_Emission_from_Traffic.rst new file mode 100644 index 000000000..71ebae90f --- /dev/null +++ b/Docs/functions/NoiseModelling/Road_Emission_from_Traffic.rst @@ -0,0 +1,106 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Road Emission from Traffic +========================== + +Compute road emission noise map from road table. + +Overview +-------- + +➡️ Compute Road Emission Noise Map from Day Evening Night traffic flow rate and speed estimates (specific format, see input details). +✅ The output table is called: LW_ROADS + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableRoads`` — *Roads table name* + Name of the Roads table. + If you provide the PERIOD field you do not provide the fields with the extension _D _E _N. This function recognize the following columns (* mandatory) : + + * PK : If there is a primary key defined, it will be copied with the same name and set as a primary for the output table + + * IDSOURCE : an identifier, if present will be copied as is. It is expected if you will use LW_ROADS as SOURCES_EMISSION in the Noise_Level_From_Source script input (INTEGER) + + * PERIOD : Any text that could be time period ex. D, E, N, DEN (Varchar), if present will be copied as is + + * LV : Hourly average light vehicle count (DOUBLE) + + * MV : Hourly average medium heavy vehicles, delivery vans > 3.5 tons, buses, touring cars, etc. with two axles and twin tyre mounting on rear axle count (DOUBLE) + + * HGV : Hourly average heavy duty vehicles, touring cars, buses, with three or more axles (DOUBLE) + + * WAV : Hourly average mopeds, tricycles or quads ≤ 50 cc count (DOUBLE) + + * WBV : Hourly average motorcycles, tricycles or quads > 50 cc count (DOUBLE) + + * LV_SPD : Hourly average light vehicle speed (DOUBLE) + + * MV_SPD : Hourly average medium heavy vehicles speed (DOUBLE) + + * HGV_SPD : Hourly average heavy duty vehicles speed (DOUBLE) + + * WAV_SPD : Hourly average mopeds, tricycles or quads ≤ 50 cc speed (DOUBLE) + + * WBV_SPD : Hourly average motorcycles, tricycles or quads > 50 cc speed (DOUBLE) + + * LV_D LV_E LV_N : Hourly average light vehicle count (6-18h)(18-22h)(22-6h) (DOUBLE) + + * MV_D MV_E MV_N : Hourly average medium heavy vehicles, delivery vans > 3.5 tons, buses, touring cars, etc. with two axles and twin tyre mounting on rear axle count (6-18h)(18-22h)(22-6h) (DOUBLE) + + * HGV_D HGV_E HGV_N : Hourly average heavy duty vehicles, touring cars, buses, with three or more axles (6-18h)(18-22h)(22-6h) (DOUBLE) + + * WAV_D WAV_E WAV_N : Hourly average mopeds, tricycles or quads ≤ 50 cc count (6-18h)(18-22h)(22-6h) (DOUBLE) + + * WBV_D WBV_E WBV_N : Hourly average motorcycles, tricycles or quads > 50 cc count (6-18h)(18-22h)(22-6h) (DOUBLE) + + * LV_SPD_D LV_SPD_E LV_SPD_N : Hourly average light vehicle speed (6-18h)(18-22h)(22-6h) (DOUBLE) + + * MV_SPD_D MV_SPD_E MV_SPD_N : Hourly average medium heavy vehicles speed (6-18h)(18-22h)(22-6h) (DOUBLE) + + * HGV_SPD_D HGV_SPD_E HGV_SPD_N : Hourly average heavy duty vehicles speed (6-18h)(18-22h)(22-6h) (DOUBLE) + + * WAV_SPD_D WAV_SPD_E WAV_SPD_N : Hourly average mopeds, tricycles or quads ≤ 50 cc speed (6-18h)(18-22h)(22-6h) (DOUBLE) + + * WBV_SPD_D WBV_SPD_E WBV_SPD_N : Hourly average motorcycles, tricycles or quads > 50 cc speed (6-18h)(18-22h)(22-6h) (DOUBLE) + + * PVMT : CNOSSOS road pavement identifier (ex: NL05)(default NL08) (VARCHAR) + + * TS_STUD : A limited period Ts (in months) over the year where a average proportion pm of light vehicles are equipped with studded tyres (0-12) (DOUBLE) + + * PM_STUD : Average proportion of vehicles equipped with studded tyres during TS_STUD period (0-1) (DOUBLE) + + * JUNC_DIST : Distance to junction in meters (DOUBLE) + + * JUNC_TYPE : Type of junction (k=0 none, k = 1 for a crossing with traffic lights ; k = 2 for a roundabout) (INTEGER) + + * SLOPE : Slope (in %) of the road section. If the field is not filled in, the LINESTRING z-values will be used to calculate the slope and the traffic direction (way field) will be force to 3 (bidirectional). (DOUBLE) + + * WAY : Define the way of the road section. 1 = one way road section and the traffic goes in the same way that the slope definition you have used, 2 = one way road section and the traffic goes in the inverse way that the slope definition you have used, 3 = bi-directional traffic flow, the flow is split into two components and correct half for uphill and half for downhill (INTEGER) + + This table can be generated from the WPS Block 'Import_OSM'. . + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``coefficientVersion`` — *Coefficient version* + 🌧 Cnossos coefficient version (1 = 2015, 2 = 2020) + + Type: ``Double`` + + Default: ``2`` + +Output +------ + +``result`` — *Result output string* + This type of result does not allow the blocks to be linked together. + + Type: ``String`` + diff --git a/Docs/functions/NoiseModelling/acoustics_parameters_confFavorableOccurrences.png b/Docs/functions/NoiseModelling/acoustics_parameters_confFavorableOccurrences.png new file mode 100644 index 000000000..e9a03ab29 Binary files /dev/null and b/Docs/functions/NoiseModelling/acoustics_parameters_confFavorableOccurrences.png differ diff --git a/Docs/functions/NoiseModelling/acoustics_parameters_confMaxReflDist.png b/Docs/functions/NoiseModelling/acoustics_parameters_confMaxReflDist.png new file mode 100644 index 000000000..dee0101f4 Binary files /dev/null and b/Docs/functions/NoiseModelling/acoustics_parameters_confMaxReflDist.png differ diff --git a/Docs/functions/NoiseModelling/acoustics_parameters_confMaxSrcDist.png b/Docs/functions/NoiseModelling/acoustics_parameters_confMaxSrcDist.png new file mode 100644 index 000000000..4a274f322 Binary files /dev/null and b/Docs/functions/NoiseModelling/acoustics_parameters_confMaxSrcDist.png differ diff --git a/Docs/functions/Receivers/Building_Grid.rst b/Docs/functions/Receivers/Building_Grid.rst new file mode 100644 index 000000000..839a61432 --- /dev/null +++ b/Docs/functions/Receivers/Building_Grid.rst @@ -0,0 +1,93 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Building Grid +============= + +Buildings Grid + +Overview +-------- + +➡️ Generates receivers, 2m around the building facades, at a given height. +✅ The output table is called RECEIVERS and contain a field build_pk corresponding to the primary key of the buildings table + +.. figure:: building_grid_output.png + :align: center + :alt: Building grid output + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableBuilding`` — *Buildings table name* + Name of the Buildings table. + The table must contain: + + * THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON) + + * HEIGHT : the height of the building (in meter) (FLOAT) + + * POP : (optional field) building population to add in the receiver attribute (FLOAT) + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``delta`` — *Distance between receivers* + Distance between receivers (in the Cartesian plane - in meter) (FLOAT) + + Type: ``Double`` + + Default: ``10`` + +``distance`` — *Distance from wall* + Distance between the receivers and the wall, in metres (FLOAT) + + Type: ``Double`` + + Default: ``2`` + +``fence`` — *Extent filter* + Create receivers only in the provided polygon (fence) + + Type: ``Geometry`` + +``fenceTableName`` — *Filter using table bounding box* + Filter receivers, using the bounding box of the given table name: + + * Extract the bounding box of the specified table, + + * then create only receivers on the table bounding box. + + The given table must contain: + + * THE_GEOM : any geometry type. + + Type: ``String`` + +``height`` — *Height* + Height of receivers (in meter) (FLOAT) + + Type: ``Double`` + + Default: ``4`` + +``sourcesTableName`` — *Sources table name* + Keep only receivers that are at least 1 meter from the provided source geometries.The source geometries table must contain: + + * THE_GEOM : any geometry type. + + Type: ``String`` + +Output +------ + +``result`` — *Created table* + Name of the table containing the results of the computation. Can be used as input for another process. + + Type: ``String`` + diff --git a/wpsbuilder/wps_images/Building_Grid3D.png b/Docs/functions/Receivers/Building_Grid3D.png similarity index 100% rename from wpsbuilder/wps_images/Building_Grid3D.png rename to Docs/functions/Receivers/Building_Grid3D.png diff --git a/Docs/functions/Receivers/Building_Grid3D.rst b/Docs/functions/Receivers/Building_Grid3D.rst new file mode 100644 index 000000000..d0933b33f --- /dev/null +++ b/Docs/functions/Receivers/Building_Grid3D.rst @@ -0,0 +1,101 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Building Grid3D +=============== + +Buildings Grid + +Overview +-------- + +➡️ Generates 3D receivers around the buildings and at different levels. +Main parameters: + +* "Height between levels": coupled with the building height, allows to determine the number of levels, + +* "Distance from wall": set the distance between the receivers and the building facades, + +* "Distance between receivers": set the number of receivers around the buildings. + +✅ The output table is called RECEIVERS + +.. figure:: Building_Grid3D.png + :align: center + :alt: Building grid output + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``tableBuilding`` — *Buildings table name* + Name of the Buildings table. + The table must contain: + + * THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON) + + * HEIGHT : the height of the building (in meter) (FLOAT) + + * POP : building population to add in the receiver attribute (FLOAT) (Optional) + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``delta`` — *Distance between receivers* + Distance between receivers (in the Cartesian plane - in meters) (FLOAT) + + Type: ``Double`` + + Default: ``10`` + +``distance`` — *Distance from wall* + Distance between the receivers and the wall, in metres (FLOAT) + + Type: ``Double`` + + Default: ``2`` + +``fence`` — *Extent filter* + Create receivers only in the provided polygon (fence) + + Type: ``Geometry`` + +``fenceTableName`` — *Filter using table bounding box* + Filter receivers, using the bounding box of the given table name: + + * Extract the bounding box of the specified table, + + * then create only receivers on the table bounding box. + + The given table must contain: + + * THE_GEOM : any geometry type. + + Type: ``String`` + +``heightLevels`` — *Height between levels* + Height between each level of receivers, in meters (FLOAT) + + Type: ``Double`` + + Default: ``2.5`` + +``sourcesTableName`` — *Sources table name* + Keep only receivers that are at least 1 meter from the provided source geometries.The source geometries table must contain: + + * THE_GEOM : any geometry type + + Type: ``String`` + +Output +------ + +``result`` — *Created table* + Name of the table containing the results of the computation. Can be used as input for another process. + + Type: ``String`` + diff --git a/Docs/functions/Receivers/Delaunay_Grid.rst b/Docs/functions/Receivers/Delaunay_Grid.rst new file mode 100644 index 000000000..b003aa137 --- /dev/null +++ b/Docs/functions/Receivers/Delaunay_Grid.rst @@ -0,0 +1,136 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Delaunay Grid +============= + +Overview +-------- + +➡️ Computes a Delaunay grid of receivers. +The grid will be based on: + +* the BUILDINGS table extent (option by default) + +* OR a single Geometry "fence" (Extent filter). + +✅ Two tables are returned: + +* RECEIVERS + +* TRIANGLES + +.. figure:: delaunay_grid_output.png + :align: center + :alt: Delaunay grid output + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``sourcesTableName`` — *Sources table name* + Name of the Road table. + Receivers will not be created on the specified road width + + Type: ``String`` + +``tableBuilding`` — *Buildings table name* + Name of the Buildings table. + The table must contain: + + * THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON) + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``buildingBuffer`` — *Minimum distance to buildings (m)* + Do not add receivers closer than this distance to buildings (in meters) + + Type: ``Double`` + + Default: ``2`` + +``exportTrianglesGeometries`` — *In the triangles table, export triangles geometries* + If enabled, the TRIANGLES table will contain the geometry of each triangle + + Type: ``Boolean`` + + Default: ``false`` + +``fence`` — *Extent filter* + Create receivers only in the provided polygon (fence) + + Type: ``Geometry`` + +``fenceNegativeBuffer`` — *Negative buffer* + Reduce the fence(parameter, or sound sources and buildings extent) used to generate receivers positions. You should set here the maximum propagation distance (in meters) (FLOAT) + + Type: ``Double`` + + Default: ``0`` + +``fenceTableName`` — *Fence table name* + Use the extent of a geometry table (e.g., from a shapefile) to limit receiver area + + Type: ``String`` + +``height`` — *Height* + Receiver height relative to the ground (in meters) (FLOAT) + + Type: ``Double`` + + Default: ``4`` + +``isoSurfaceInBuildings`` — *Create IsoSurfaces over buildings* + If enabled, isosurfaces will be visible at the location of buildings + + Type: ``Boolean`` + + Default: ``false`` + +``maxArea`` — *Maximum Area* + Set Maximum Area (in m2) (FLOAT). No triangles larger than provided area will be created.Smaller area will create more receivers + + Type: ``Double`` + + Default: ``2500`` + +``maxCellDist`` — *Maximum cell size* + Maximum distance used to split the domain into sub-domains (in meters) (FLOAT). + In a logic of optimization of processing times, it allows to limit the number of objects (buildings, roads, …) stored in memory during the Delaunay triangulation + + Type: ``Double`` + + Default: ``600`` + +``outputTableName`` — *Name of output table* + Name of the output table. Do not write the name of a table that contains a space + + Type: ``String`` + + Default: ``RECEIVERS`` + +``roadWidth`` — *Road width* + Set Road Width (in meters) (FLOAT). No receivers closer than road width distance will be created. You can set 0 m if you don't want to insert roads in the output but still want to skip cells without sources using the 'Skip cell no sources minimal distance' parameter + + Type: ``Double`` + + Default: ``2`` + +``skipCellNoSourcesMinimalDistance`` — *Skip cell no sources minimal distance* + If provided, a sub-domain will not be computed if no sources geometries are near x meters from the sub-domain area + + Type: ``Double`` + +Output +------ + +``result`` — *Created table* + Name of the table containing the results of the computation. Can be used as input for another process. + + Type: ``String`` + diff --git a/Docs/functions/Receivers/Random_Grid.rst b/Docs/functions/Receivers/Random_Grid.rst new file mode 100644 index 000000000..3cf95e1f4 --- /dev/null +++ b/Docs/functions/Receivers/Random_Grid.rst @@ -0,0 +1,79 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Random Grid +=========== + +Overview +-------- + +➡️ Computes a random grid of receivers. +✅ The output table is called RECEIVERS + +.. figure:: receivers_random_output.png + :align: center + :alt: Random grid output + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``buildingTableName`` — *Buildings table name* + Name of the Buildings table The table must contain: + + * THE_GEOM: the 2D geometry of the building (POLYGON or MULTIPOLYGON) + + * HEIGHT: the height of the building (FLOAT) + + Type: ``String`` + +``sourcesTableName`` — *Sources table name* + Keep only receivers at least at 1 meters of provided sources geometries The table must contain : + + * THE_GEOM: any geometry type. + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``fence`` — *Extent filter* + Create receivers only in the provided polygon. Must be in the WGS84 (EPSG:4326) projection system + + Type: ``Geometry`` + +``fenceTableName`` — *Filter using table bounding box* + Extract the bounding box of the specified table then create only receivers on the table bounding box. The table must contain : + + * THE_GEOM: any geometry type. + + Type: ``String`` + +``height`` — *Height* + Height of receivers (in meters) (FLOAT) + + Type: ``Double`` + + Default: ``4`` + +``nReceivers`` — *Number of receivers* + Number of receivers to return + + .. figure:: receivers_random_nReceivers.png + :align: center + :alt: Number of receivers + + Type: ``Integer`` + + Default: ``100`` + +Output +------ + +``result`` — *Created table* + Name of the table containing the results of the computation. Can be used as input for another process. + + Type: ``String`` + diff --git a/Docs/functions/Receivers/Regular_Grid.rst b/Docs/functions/Receivers/Regular_Grid.rst new file mode 100644 index 000000000..2ae2e8037 --- /dev/null +++ b/Docs/functions/Receivers/Regular_Grid.rst @@ -0,0 +1,97 @@ +.. DO NOT UPDATE THIS FILE!! +.. This document has been automatically generated with noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java + +Regular Grid +============ + +Overview +-------- + +➡️ Computes a regular grid of receivers. +The receivers are spaced at a distance "delta" (Offset) in the Cartesian plane in meters. The grid will be based on: + +* the BUILDINGS table extent (option by default) + +* OR a single Geometry "fence" (see "Extent filter" parameter). + +✅ The output table is called RECEIVERS + +.. figure:: regular_grid_output.png + :align: center + :alt: Regular grid output + +Arguments +--------- + +Mandatory inputs +~~~~~~~~~~~~~~~~ + +``fenceTableName`` — *Table bounding box name* + Using the bounding box of the given table name, define the envelope of the output grid: + + * Extract the bounding box of the specified table, + + * then create only receivers on the table bounding box. + + The given table must contain: + + * THE_GEOM : any geometry type with the appropriate SRID + + Type: ``String`` + +Optional inputs +~~~~~~~~~~~~~~~ + +``buildingTableName`` — *Buildings table name* + Name of the Buildings table. Receivers inside buildings will be removed.The table must contain: + + * THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON) + + Type: ``String`` + +``delta`` — *Offset* + Offset in the Cartesian plane (in meters) + + Type: ``Double`` + + Default: ``10`` + +``fence`` — *Extent filter* + Create receivers only in the provided polygon (fence) + + Type: ``Geometry`` + +``height`` — *Height* + Height of receivers (in meter) (FLOAT) + + Type: ``Double`` + + Default: ``4`` + +``outputTriangleTable`` — *Output triangle table* + Output a triangle table in order to be used to generate iso contours with Create_Isosurface + + Type: ``Boolean`` + +``receiverstablename`` — *Name of receivers table* + Name of the output table. Do not write the name of a table that contains a space + + Type: ``String`` + + Default: ``RECEIVERS`` + +``sourcesTableName`` — *Sources table name* + Keep only receivers at least at 1 meters of provided sources geometries The given table must contain: + + * THE_GEOM : any geometry type. + + Type: ``String`` + +Output +------ + +``result`` — *Created table* + Name of the table containing the results of the computation. Can be used as input for another process. + + Type: ``String`` + diff --git a/wpsbuilder/wps_images/building_grid_output.png b/Docs/functions/Receivers/building_grid_output.png similarity index 100% rename from wpsbuilder/wps_images/building_grid_output.png rename to Docs/functions/Receivers/building_grid_output.png diff --git a/wpsbuilder/wps_images/delaunay_grid_output.png b/Docs/functions/Receivers/delaunay_grid_output.png similarity index 100% rename from wpsbuilder/wps_images/delaunay_grid_output.png rename to Docs/functions/Receivers/delaunay_grid_output.png diff --git a/wpsbuilder/wps_images/receivers_random_nReceivers.png b/Docs/functions/Receivers/receivers_random_nReceivers.png similarity index 100% rename from wpsbuilder/wps_images/receivers_random_nReceivers.png rename to Docs/functions/Receivers/receivers_random_nReceivers.png diff --git a/wpsbuilder/wps_images/receivers_random_output.png b/Docs/functions/Receivers/receivers_random_output.png similarity index 100% rename from wpsbuilder/wps_images/receivers_random_output.png rename to Docs/functions/Receivers/receivers_random_output.png diff --git a/wpsbuilder/wps_images/regular_grid_output.png b/Docs/functions/Receivers/regular_grid_output.png similarity index 100% rename from wpsbuilder/wps_images/regular_grid_output.png rename to Docs/functions/Receivers/regular_grid_output.png diff --git a/Docs/images/Architecture/NM_UI.PNG b/Docs/images/Architecture/NM_UI.PNG index a2d282f2d..8e2388872 100644 Binary files a/Docs/images/Architecture/NM_UI.PNG and b/Docs/images/Architecture/NM_UI.PNG differ diff --git a/Docs/images/Architecture/architecture.png b/Docs/images/Architecture/architecture.png index 143d2536d..50e7c73d3 100644 Binary files a/Docs/images/Architecture/architecture.png and b/Docs/images/Architecture/architecture.png differ diff --git a/Docs/images/Architecture/architecture.svg b/Docs/images/Architecture/architecture.svg index 7a06c0064..6677b1f19 100644 --- a/Docs/images/Architecture/architecture.svg +++ b/Docs/images/Architecture/architecture.svg @@ -2,21 +2,35 @@ + inkscape:export-ydpi="140.02032"> + + + + image/svg+xml + + + + @@ -410,36 +424,37 @@ inkscape:groupmode="layer" id="layer1"> + inkscape:export-ydpi="140.72421" + inkscape:connector-curvature="0" /> NoiseModelling with Docker + inkscape:export-ydpi="140.72421" + inkscape:connector-curvature="0" /> NoiseModelling Emission - - - NoiseModelling + + NoiseModelling JDBC - + id="tspan10048" + y="79.929276" + x="186.88881" + style="text-align:start;text-anchor:start;stroke-width:0.22409828">JDBC NoiseModelling Pathfinder NoiseModelling Propagation @@ -760,430 +775,78 @@ inkscape:connector-type="polyline" inkscape:connector-curvature="0" inkscape:connection-start="#g113936" - inkscape:connection-end="#g113946" inkscape:export-filename="/home/gpetit/codes/NoiseModelling/Docs/images/Architecture/architecture.png" inkscape:export-xdpi="140.72421" inkscape:export-ydpi="140.72421" /> NoiseModelling with a GUI NoiseModelling libraries - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Web client + Web client - + id="flowRoot4608" + style="fill:black;fill-opacity:1;stroke:none;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;letter-spacing:0px;word-spacing:0px"> WPS Groovy scripts via HTTP requests Database @@ -1452,55 +1117,42 @@ inkscape:connector-type="polyline" inkscape:connector-curvature="0" inkscape:connection-start="#g113936" - inkscape:connection-end="#g113946" inkscape:export-filename="/home/gpetit/codes/NoiseModelling/Docs/images/Architecture/architecture.png" inkscape:export-xdpi="140.72421" inkscape:export-ydpi="140.72421" /> - - - - NoiseModelling with command line - + + NoiseModelling with command line + y="27.133562" /> + + API REST + + diff --git a/Docs/images/Data_Assimilation/ASSIMILATED_MAPS_200m.png b/Docs/images/Data_Assimilation/ASSIMILATED_MAPS_200m.png deleted file mode 100644 index 92dd0cba1..000000000 Binary files a/Docs/images/Data_Assimilation/ASSIMILATED_MAPS_200m.png and /dev/null differ diff --git a/Docs/images/Data_Assimilation/BUILDINGS.png b/Docs/images/Data_Assimilation/BUILDINGS.png deleted file mode 100644 index 9d723fff7..000000000 Binary files a/Docs/images/Data_Assimilation/BUILDINGS.png and /dev/null differ diff --git a/Docs/images/Data_Assimilation/BUILDINGS_ROADS.png b/Docs/images/Data_Assimilation/BUILDINGS_ROADS.png deleted file mode 100644 index b9c7bde07..000000000 Binary files a/Docs/images/Data_Assimilation/BUILDINGS_ROADS.png and /dev/null differ diff --git a/Docs/images/Data_Assimilation/BUILDINGS_ROADS.svg b/Docs/images/Data_Assimilation/BUILDINGS_ROADS.svg deleted file mode 100644 index f166256af..000000000 --- a/Docs/images/Data_Assimilation/BUILDINGS_ROADS.svg +++ /dev/null @@ -1,63 +0,0 @@ - - - - diff --git a/Docs/images/Data_Assimilation/NM_GUI_wps_list.png b/Docs/images/Data_Assimilation/NM_GUI_wps_list.png deleted file mode 100644 index 2e3217e94..000000000 Binary files a/Docs/images/Data_Assimilation/NM_GUI_wps_list.png and /dev/null differ diff --git a/Docs/images/Data_Assimilation/RECEIVERS.png b/Docs/images/Data_Assimilation/RECEIVERS.png deleted file mode 100644 index 39c4bb0c7..000000000 Binary files a/Docs/images/Data_Assimilation/RECEIVERS.png and /dev/null differ diff --git a/Docs/images/Data_Assimilation/RECEIVERS_and_SENSORS.png b/Docs/images/Data_Assimilation/RECEIVERS_and_SENSORS.png deleted file mode 100644 index 37ba01b26..000000000 Binary files a/Docs/images/Data_Assimilation/RECEIVERS_and_SENSORS.png and /dev/null differ diff --git a/Docs/images/Data_Assimilation/ROADS.png b/Docs/images/Data_Assimilation/ROADS.png deleted file mode 100644 index 046255a7b..000000000 Binary files a/Docs/images/Data_Assimilation/ROADS.png and /dev/null differ diff --git a/Docs/images/Data_Assimilation/all_possible_configuration_all.png b/Docs/images/Data_Assimilation/all_possible_configuration_all.png deleted file mode 100644 index d6131d19e..000000000 Binary files a/Docs/images/Data_Assimilation/all_possible_configuration_all.png and /dev/null differ diff --git a/Docs/images/Input_tables/acoustics_parameters_confMaxReflDist.png b/Docs/images/Input_tables/acoustics_parameters_confMaxReflDist.png index bf5092528..dee0101f4 100644 Binary files a/Docs/images/Input_tables/acoustics_parameters_confMaxReflDist.png and b/Docs/images/Input_tables/acoustics_parameters_confMaxReflDist.png differ diff --git a/Docs/images/Input_tables/acoustics_parameters_confMaxReflDist.svg b/Docs/images/Input_tables/acoustics_parameters_confMaxReflDist.svg index a0c81d6b3..b338fde34 100644 --- a/Docs/images/Input_tables/acoustics_parameters_confMaxReflDist.svg +++ b/Docs/images/Input_tables/acoustics_parameters_confMaxReflDist.svg @@ -2,13 +2,16 @@ @@ -76,17 +79,27 @@ + id="layer1" + transform="translate(-54.530991,-74.872513)"> + confMaxReflDist + id="tspan1">confMaxReflDist - - S + id="tspan3">S R + id="tspan5">R + + + + diff --git a/Docs/images/Noise_Map_From_Point_Source/change_parameters.png b/Docs/images/Noise_Map_From_Point_Source/change_parameters.png deleted file mode 100644 index 24103aab1..000000000 Binary files a/Docs/images/Noise_Map_From_Point_Source/change_parameters.png and /dev/null differ diff --git a/Docs/images/Noise_Map_From_Point_Source/table_list_NM.png b/Docs/images/Noise_Map_From_Point_Source/table_list_NM.png deleted file mode 100644 index 0a87018d2..000000000 Binary files a/Docs/images/Noise_Map_From_Point_Source/table_list_NM.png and /dev/null differ diff --git a/Docs/images/Noise_Map_From_Point_Source/table_list_NM.svg b/Docs/images/Noise_Map_From_Point_Source/table_list_NM.svg deleted file mode 100644 index 8f8315457..000000000 --- a/Docs/images/Noise_Map_From_Point_Source/table_list_NM.svg +++ /dev/null @@ -1,1321 +0,0 @@ - - - - diff --git a/Docs/images/Numerical_Model/maximumdberror.png b/Docs/images/Numerical_Model/maximumdberror.png index 21743fc45..60b22fd6d 100644 Binary files a/Docs/images/Numerical_Model/maximumdberror.png and b/Docs/images/Numerical_Model/maximumdberror.png differ diff --git a/Docs/images/Numerical_Model/maximumdberror.svg b/Docs/images/Numerical_Model/maximumdberror.svg new file mode 100644 index 000000000..2dcc7b4dc --- /dev/null +++ b/Docs/images/Numerical_Model/maximumdberror.svg @@ -0,0 +1,246 @@ + + + +Start receiverNew propagation pathEvaluate the maximal expected noise level at receiver for all sound sources +(free field with 3dB gain)maximumExpectedLevel - minimalCurrentLevelAtReceiver < maximumDbError ?NoYes diff --git a/Docs/images/WPS_Builder/wps_demo.png b/Docs/images/WPS_Builder/wps_demo.png new file mode 100644 index 000000000..aed506a8c Binary files /dev/null and b/Docs/images/WPS_Builder/wps_demo.png differ diff --git a/Docs/images/matsim/buildings_table.png b/Docs/images/matsim/buildings_table.png deleted file mode 100644 index b09eecba4..000000000 Binary files a/Docs/images/matsim/buildings_table.png and /dev/null differ diff --git a/Docs/images/matsim/import_activities_wps.png b/Docs/images/matsim/import_activities_wps.png deleted file mode 100644 index cb4b19aca..000000000 Binary files a/Docs/images/matsim/import_activities_wps.png and /dev/null differ diff --git a/Docs/images/matsim/lday_geom_table.png b/Docs/images/matsim/lday_geom_table.png deleted file mode 100644 index e953a07c9..000000000 Binary files a/Docs/images/matsim/lday_geom_table.png and /dev/null differ diff --git a/Docs/images/matsim/noise_from_attenuation_wps.png b/Docs/images/matsim/noise_from_attenuation_wps.png deleted file mode 100644 index c2a4527c9..000000000 Binary files a/Docs/images/matsim/noise_from_attenuation_wps.png and /dev/null differ diff --git a/Docs/images/matsim/noise_from_source_wps.png b/Docs/images/matsim/noise_from_source_wps.png deleted file mode 100644 index 7508bf7f1..000000000 Binary files a/Docs/images/matsim/noise_from_source_wps.png and /dev/null differ diff --git a/Docs/images/matsim/osm_pbf_wps.png b/Docs/images/matsim/osm_pbf_wps.png deleted file mode 100644 index 3125a6567..000000000 Binary files a/Docs/images/matsim/osm_pbf_wps.png and /dev/null differ diff --git a/Docs/images/matsim/receiver_activities_wps.png b/Docs/images/matsim/receiver_activities_wps.png deleted file mode 100644 index 36b78e919..000000000 Binary files a/Docs/images/matsim/receiver_activities_wps.png and /dev/null differ diff --git a/Docs/images/matsim/results_export_wps.png b/Docs/images/matsim/results_export_wps.png deleted file mode 100644 index 5e7d392c7..000000000 Binary files a/Docs/images/matsim/results_export_wps.png and /dev/null differ diff --git a/Docs/images/matsim/traffic_events_wps.png b/Docs/images/matsim/traffic_events_wps.png deleted file mode 100644 index a8165217a..000000000 Binary files a/Docs/images/matsim/traffic_events_wps.png and /dev/null differ diff --git a/Docs/images/Data_Assimilation/ASSIMILATED_MAPS.png b/Docs/images/tutorial/Data_Assimilation/ASSIMILATED_MAPS.png similarity index 100% rename from Docs/images/Data_Assimilation/ASSIMILATED_MAPS.png rename to Docs/images/tutorial/Data_Assimilation/ASSIMILATED_MAPS.png diff --git a/Docs/images/tutorial/Data_Assimilation/ASSIMILATED_MAPS_200m.png b/Docs/images/tutorial/Data_Assimilation/ASSIMILATED_MAPS_200m.png new file mode 100644 index 000000000..fbdb6306a Binary files /dev/null and b/Docs/images/tutorial/Data_Assimilation/ASSIMILATED_MAPS_200m.png differ diff --git a/Docs/images/tutorial/Data_Assimilation/BUILDINGS.png b/Docs/images/tutorial/Data_Assimilation/BUILDINGS.png new file mode 100644 index 000000000..f0c2650fb Binary files /dev/null and b/Docs/images/tutorial/Data_Assimilation/BUILDINGS.png differ diff --git a/Docs/images/tutorial/Data_Assimilation/BUILDINGS_ROADS.png b/Docs/images/tutorial/Data_Assimilation/BUILDINGS_ROADS.png new file mode 100644 index 000000000..edfb6d99c Binary files /dev/null and b/Docs/images/tutorial/Data_Assimilation/BUILDINGS_ROADS.png differ diff --git a/Docs/images/tutorial/Data_Assimilation/BUILDINGS_ROADS.svg b/Docs/images/tutorial/Data_Assimilation/BUILDINGS_ROADS.svg new file mode 100644 index 000000000..bd169418c --- /dev/null +++ b/Docs/images/tutorial/Data_Assimilation/BUILDINGS_ROADS.svg @@ -0,0 +1,66 @@ + + + + diff --git a/Docs/images/tutorial/Data_Assimilation/NM_GUI_wps_list.png b/Docs/images/tutorial/Data_Assimilation/NM_GUI_wps_list.png new file mode 100644 index 000000000..ac07eff25 Binary files /dev/null and b/Docs/images/tutorial/Data_Assimilation/NM_GUI_wps_list.png differ diff --git a/Docs/images/tutorial/Data_Assimilation/RECEIVERS.png b/Docs/images/tutorial/Data_Assimilation/RECEIVERS.png new file mode 100644 index 000000000..b9e2ac7a3 Binary files /dev/null and b/Docs/images/tutorial/Data_Assimilation/RECEIVERS.png differ diff --git a/Docs/images/tutorial/Data_Assimilation/RECEIVERS_and_SENSORS.png b/Docs/images/tutorial/Data_Assimilation/RECEIVERS_and_SENSORS.png new file mode 100644 index 000000000..6770988cf Binary files /dev/null and b/Docs/images/tutorial/Data_Assimilation/RECEIVERS_and_SENSORS.png differ diff --git a/Docs/images/tutorial/Data_Assimilation/ROADS.png b/Docs/images/tutorial/Data_Assimilation/ROADS.png new file mode 100644 index 000000000..b3597d36a Binary files /dev/null and b/Docs/images/tutorial/Data_Assimilation/ROADS.png differ diff --git a/Docs/images/Data_Assimilation/all_possible_configuration.png b/Docs/images/tutorial/Data_Assimilation/all_possible_configuration.png similarity index 100% rename from Docs/images/Data_Assimilation/all_possible_configuration.png rename to Docs/images/tutorial/Data_Assimilation/all_possible_configuration.png diff --git a/Docs/images/tutorial/Data_Assimilation/all_possible_configuration_all.png b/Docs/images/tutorial/Data_Assimilation/all_possible_configuration_all.png new file mode 100644 index 000000000..f63627fee Binary files /dev/null and b/Docs/images/tutorial/Data_Assimilation/all_possible_configuration_all.png differ diff --git a/Docs/images/Data_Assimilation/all_possible_configuration_all.svg b/Docs/images/tutorial/Data_Assimilation/all_possible_configuration_all.svg similarity index 54% rename from Docs/images/Data_Assimilation/all_possible_configuration_all.svg rename to Docs/images/tutorial/Data_Assimilation/all_possible_configuration_all.svg index b0c4a117a..184fe52bd 100644 --- a/Docs/images/Data_Assimilation/all_possible_configuration_all.svg +++ b/Docs/images/tutorial/Data_Assimilation/all_possible_configuration_all.svg @@ -8,7 +8,7 @@ version="1.1" id="svg1" xml:space="preserve" - inkscape:version="1.4 (e7c3feb, 2024-10-09)" + inkscape:version="1.4.2 (f4327f4, 2025-05-13)" sodipodi:docname="all_possible_configuration_all.svg" inkscape:export-filename="all_possible_configuration_all.png" inkscape:export-xdpi="469.36118" @@ -27,13 +27,13 @@ inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" - inkscape:zoom="2.187487" - inkscape:cx="117.71499" - inkscape:cy="129.14363" - inkscape:window-width="1878" - inkscape:window-height="1011" - inkscape:window-x="0" - inkscape:window-y="0" + inkscape:zoom="3.0935738" + inkscape:cx="139.48269" + inkscape:cy="1.777879" + inkscape:window-width="1920" + inkscape:window-height="1009" + inkscape:window-x="-8" + inkscape:window-y="-8" inkscape:window-maximized="1" inkscape:current-layer="layer1" /> + y="56.785084" /> diff --git a/Docs/images/Data_Assimilation/all_possible_configuration_temp.png b/Docs/images/tutorial/Data_Assimilation/all_possible_configuration_temp.png similarity index 100% rename from Docs/images/Data_Assimilation/all_possible_configuration_temp.png rename to Docs/images/tutorial/Data_Assimilation/all_possible_configuration_temp.png diff --git a/Docs/images/Data_Assimilation/all_possible_configuration_traffic.png b/Docs/images/tutorial/Data_Assimilation/all_possible_configuration_traffic.png similarity index 100% rename from Docs/images/Data_Assimilation/all_possible_configuration_traffic.png rename to Docs/images/tutorial/Data_Assimilation/all_possible_configuration_traffic.png diff --git a/Docs/images/Data_Assimilation/data_assimilation_banner.png b/Docs/images/tutorial/Data_Assimilation/data_assimilation_banner.png similarity index 100% rename from Docs/images/Data_Assimilation/data_assimilation_banner.png rename to Docs/images/tutorial/Data_Assimilation/data_assimilation_banner.png diff --git a/Docs/images/Data_Assimilation/geneva_sensors.png b/Docs/images/tutorial/Data_Assimilation/geneva_sensors.png similarity index 100% rename from Docs/images/Data_Assimilation/geneva_sensors.png rename to Docs/images/tutorial/Data_Assimilation/geneva_sensors.png diff --git a/Docs/images/tutorial/Tutorial2_ContouringNoiseMap.png b/Docs/images/tutorial/Noise_Map_From_OSM/Tutorial2_ContouringNoiseMap.png similarity index 100% rename from Docs/images/tutorial/Tutorial2_ContouringNoiseMap.png rename to Docs/images/tutorial/Noise_Map_From_OSM/Tutorial2_ContouringNoiseMap.png diff --git a/Docs/images/tutorial/Tutorial2_Image1.PNG b/Docs/images/tutorial/Noise_Map_From_OSM/Tutorial2_Image1.PNG similarity index 100% rename from Docs/images/tutorial/Tutorial2_Image1.PNG rename to Docs/images/tutorial/Noise_Map_From_OSM/Tutorial2_Image1.PNG diff --git a/Docs/images/tutorial/Noise_Map_From_Point_Source/change_parameters.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/change_parameters.png new file mode 100644 index 000000000..f26a5f214 Binary files /dev/null and b/Docs/images/tutorial/Noise_Map_From_Point_Source/change_parameters.png differ diff --git a/Docs/images/tutorial/Noise_Map_From_Point_Source/change_parameters.svg b/Docs/images/tutorial/Noise_Map_From_Point_Source/change_parameters.svg new file mode 100644 index 000000000..ebdc20595 --- /dev/null +++ b/Docs/images/tutorial/Noise_Map_From_Point_Source/change_parameters.svg @@ -0,0 +1,98 @@ + + + +Here enter the temperature you want diff --git a/Docs/images/Noise_Map_From_Point_Source/contouring.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/contouring.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/contouring.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/contouring.png diff --git a/Docs/images/Noise_Map_From_Point_Source/contouring_directivity_compare.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/contouring_directivity_compare.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/contouring_directivity_compare.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/contouring_directivity_compare.png diff --git a/Docs/images/Noise_Map_From_Point_Source/contouring_directivity_compare.svg b/Docs/images/tutorial/Noise_Map_From_Point_Source/contouring_directivity_compare.svg similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/contouring_directivity_compare.svg rename to Docs/images/tutorial/Noise_Map_From_Point_Source/contouring_directivity_compare.svg diff --git a/Docs/images/Noise_Map_From_Point_Source/contouring_with_directivity.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/contouring_with_directivity.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/contouring_with_directivity.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/contouring_with_directivity.png diff --git a/Docs/images/Noise_Map_From_Point_Source/contouring_without_directivity.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/contouring_without_directivity.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/contouring_without_directivity.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/contouring_without_directivity.png diff --git a/Docs/images/Noise_Map_From_Point_Source/convert_point_source_geojson.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/convert_point_source_geojson.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/convert_point_source_geojson.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/convert_point_source_geojson.png diff --git a/Docs/images/Noise_Map_From_Point_Source/create_source_point_layer.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/create_source_point_layer.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/create_source_point_layer.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/create_source_point_layer.png diff --git a/Docs/images/Noise_Map_From_Point_Source/directivity_rail.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/directivity_rail.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/directivity_rail.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/directivity_rail.png diff --git a/Docs/images/Noise_Map_From_Point_Source/edit_layer.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/edit_layer.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/edit_layer.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/edit_layer.png diff --git a/Docs/images/Noise_Map_From_Point_Source/edit_layer_source.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/edit_layer_source.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/edit_layer_source.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/edit_layer_source.png diff --git a/Docs/images/Noise_Map_From_Point_Source/edit_layer_source.svg b/Docs/images/tutorial/Noise_Map_From_Point_Source/edit_layer_source.svg similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/edit_layer_source.svg rename to Docs/images/tutorial/Noise_Map_From_Point_Source/edit_layer_source.svg diff --git a/Docs/images/Noise_Map_From_Point_Source/fill_attributes.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/fill_attributes.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/fill_attributes.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/fill_attributes.png diff --git a/Docs/images/Noise_Map_From_Point_Source/layer_source.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/layer_source.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/layer_source.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/layer_source.png diff --git a/Docs/images/Noise_Map_From_Point_Source/load_data_qgis.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/load_data_qgis.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/load_data_qgis.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/load_data_qgis.png diff --git a/Docs/images/Noise_Map_From_Point_Source/place_point.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/place_point.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/place_point.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/place_point.png diff --git a/Docs/images/Noise_Map_From_Point_Source/place_point_source.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/place_point_source.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/place_point_source.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/place_point_source.png diff --git a/Docs/images/Noise_Map_From_Point_Source/place_point_source.svg b/Docs/images/tutorial/Noise_Map_From_Point_Source/place_point_source.svg similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/place_point_source.svg rename to Docs/images/tutorial/Noise_Map_From_Point_Source/place_point_source.svg diff --git a/Docs/images/Noise_Map_From_Point_Source/save_geojson.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/save_geojson.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/save_geojson.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/save_geojson.png diff --git a/Docs/images/Noise_Map_From_Point_Source/save_layer.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/save_layer.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/save_layer.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/save_layer.png diff --git a/Docs/images/Noise_Map_From_Point_Source/save_layer_source.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/save_layer_source.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/save_layer_source.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/save_layer_source.png diff --git a/Docs/images/Noise_Map_From_Point_Source/save_layer_source.svg b/Docs/images/tutorial/Noise_Map_From_Point_Source/save_layer_source.svg similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/save_layer_source.svg rename to Docs/images/tutorial/Noise_Map_From_Point_Source/save_layer_source.svg diff --git a/Docs/images/Noise_Map_From_Point_Source/style_map.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/style_map.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/style_map.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/style_map.png diff --git a/Docs/images/Noise_Map_From_Point_Source/style_map.svg b/Docs/images/tutorial/Noise_Map_From_Point_Source/style_map.svg similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/style_map.svg rename to Docs/images/tutorial/Noise_Map_From_Point_Source/style_map.svg diff --git a/Docs/images/Noise_Map_From_Point_Source/style_map1.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/style_map1.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/style_map1.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/style_map1.png diff --git a/Docs/images/Noise_Map_From_Point_Source/style_map2.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/style_map2.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/style_map2.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/style_map2.png diff --git a/Docs/images/Noise_Map_From_Point_Source/style_scale.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/style_scale.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/style_scale.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/style_scale.png diff --git a/Docs/images/Noise_Map_From_Point_Source/style_sld.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/style_sld.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/style_sld.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/style_sld.png diff --git a/Docs/images/Noise_Map_From_Point_Source/style_sld.svg b/Docs/images/tutorial/Noise_Map_From_Point_Source/style_sld.svg similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/style_sld.svg rename to Docs/images/tutorial/Noise_Map_From_Point_Source/style_sld.svg diff --git a/Docs/images/Noise_Map_From_Point_Source/style_sld1.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/style_sld1.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/style_sld1.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/style_sld1.png diff --git a/Docs/images/Noise_Map_From_Point_Source/style_sld2.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/style_sld2.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/style_sld2.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/style_sld2.png diff --git a/Docs/images/Noise_Map_From_Point_Source/style_sld3.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/style_sld3.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/style_sld3.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/style_sld3.png diff --git a/Docs/images/Noise_Map_From_Point_Source/table_contouring.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/table_contouring.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/table_contouring.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/table_contouring.png diff --git a/Docs/images/Noise_Map_From_Point_Source/table_list.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/table_list.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/table_list.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/table_list.png diff --git a/Docs/images/tutorial/Noise_Map_From_Point_Source/table_list_NM.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/table_list_NM.png new file mode 100644 index 000000000..6046c6589 Binary files /dev/null and b/Docs/images/tutorial/Noise_Map_From_Point_Source/table_list_NM.png differ diff --git a/Docs/images/tutorial/Noise_Map_From_Point_Source/table_list_NM.svg b/Docs/images/tutorial/Noise_Map_From_Point_Source/table_list_NM.svg new file mode 100644 index 000000000..53f1ff6ee --- /dev/null +++ b/Docs/images/tutorial/Noise_Map_From_Point_Source/table_list_NM.svg @@ -0,0 +1,70 @@ + + + + diff --git a/Docs/images/Noise_Map_From_Point_Source/table_receivers.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/table_receivers.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/table_receivers.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/table_receivers.png diff --git a/Docs/images/Noise_Map_From_Point_Source/tuto.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/tuto.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/tuto.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/tuto.png diff --git a/Docs/images/Noise_Map_From_Point_Source/yaw_pitch_roll.png b/Docs/images/tutorial/Noise_Map_From_Point_Source/yaw_pitch_roll.png similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/yaw_pitch_roll.png rename to Docs/images/tutorial/Noise_Map_From_Point_Source/yaw_pitch_roll.png diff --git a/Docs/images/Noise_Map_From_Point_Source/yaw_pitch_roll.svg b/Docs/images/tutorial/Noise_Map_From_Point_Source/yaw_pitch_roll.svg similarity index 100% rename from Docs/images/Noise_Map_From_Point_Source/yaw_pitch_roll.svg rename to Docs/images/tutorial/Noise_Map_From_Point_Source/yaw_pitch_roll.svg diff --git a/Docs/images/tutorial/Tutorial1_Image1bis.gif b/Docs/images/tutorial/Tutorial1_Image1bis.gif deleted file mode 100644 index 724966147..000000000 Binary files a/Docs/images/tutorial/Tutorial1_Image1bis.gif and /dev/null differ diff --git a/Docs/images/tutorial/Tutorial1_Image2bis.png b/Docs/images/tutorial/Tutorial1_Image2bis.png deleted file mode 100644 index 6edd6bd2d..000000000 Binary files a/Docs/images/tutorial/Tutorial1_Image2bis.png and /dev/null differ diff --git a/Docs/images/tutorial/Tutorial1_Image3.PNG b/Docs/images/tutorial/Tutorial1_Image3.PNG deleted file mode 100644 index 53251038e..000000000 Binary files a/Docs/images/tutorial/Tutorial1_Image3.PNG and /dev/null differ diff --git a/Docs/images/tutorial/Tutorial1_ImageLast.gif b/Docs/images/tutorial/Tutorial1_ImageLast.gif deleted file mode 100644 index 17437f3b0..000000000 Binary files a/Docs/images/tutorial/Tutorial1_ImageLast.gif and /dev/null differ diff --git a/Docs/images/tutorial/Tutorial1_display_db.png b/Docs/images/tutorial/Tutorial1_display_db.png deleted file mode 100644 index b3cb88011..000000000 Binary files a/Docs/images/tutorial/Tutorial1_display_db.png and /dev/null differ diff --git a/Docs/images/tutorial/Tutorial1_nm_open.png b/Docs/images/tutorial/Tutorial1_nm_open.png deleted file mode 100644 index 56162cb63..000000000 Binary files a/Docs/images/tutorial/Tutorial1_nm_open.png and /dev/null differ diff --git a/Docs/images/tutorial/dynamic/ImportOSM.png b/Docs/images/tutorial/dynamic/ImportOSM.png index 13495d6e9..c60295178 100644 Binary files a/Docs/images/tutorial/dynamic/ImportOSM.png and b/Docs/images/tutorial/dynamic/ImportOSM.png differ diff --git a/Docs/images/tutorial/dynamic/RegularGrid.png b/Docs/images/tutorial/dynamic/RegularGrid.png index f00a91fdb..6911f51b5 100644 Binary files a/Docs/images/tutorial/dynamic/RegularGrid.png and b/Docs/images/tutorial/dynamic/RegularGrid.png differ diff --git a/Docs/images/tutorial/dynamic/temporal_bar_nav.gif b/Docs/images/tutorial/dynamic/temporal_bar_nav.gif new file mode 100644 index 000000000..90362324a Binary files /dev/null and b/Docs/images/tutorial/dynamic/temporal_bar_nav.gif differ diff --git a/Docs/images/tutorial/dynamic/temporal_bar_nav.png b/Docs/images/tutorial/dynamic/temporal_bar_nav.png deleted file mode 100644 index 3b3c3af14..000000000 Binary files a/Docs/images/tutorial/dynamic/temporal_bar_nav.png and /dev/null differ diff --git a/Docs/images/tutorial/Tutorial1_FilterMenu.png b/Docs/images/tutorial/get_started_gui/Tutorial1_FilterMenu.png similarity index 100% rename from Docs/images/tutorial/Tutorial1_FilterMenu.png rename to Docs/images/tutorial/get_started_gui/Tutorial1_FilterMenu.png diff --git a/Docs/images/tutorial/Tutorial1_FilterWindow.png b/Docs/images/tutorial/get_started_gui/Tutorial1_FilterWindow.png similarity index 100% rename from Docs/images/tutorial/Tutorial1_FilterWindow.png rename to Docs/images/tutorial/get_started_gui/Tutorial1_FilterWindow.png diff --git a/Docs/images/tutorial/Tutorial1_Image1.PNG b/Docs/images/tutorial/get_started_gui/Tutorial1_Image1.PNG similarity index 100% rename from Docs/images/tutorial/Tutorial1_Image1.PNG rename to Docs/images/tutorial/get_started_gui/Tutorial1_Image1.PNG diff --git a/Docs/images/tutorial/get_started_gui/Tutorial1_Image1bis.gif b/Docs/images/tutorial/get_started_gui/Tutorial1_Image1bis.gif new file mode 100644 index 000000000..da475d17d Binary files /dev/null and b/Docs/images/tutorial/get_started_gui/Tutorial1_Image1bis.gif differ diff --git a/Docs/images/tutorial/Tutorial1_Image2.PNG b/Docs/images/tutorial/get_started_gui/Tutorial1_Image2.PNG similarity index 100% rename from Docs/images/tutorial/Tutorial1_Image2.PNG rename to Docs/images/tutorial/get_started_gui/Tutorial1_Image2.PNG diff --git a/Docs/images/tutorial/get_started_gui/Tutorial1_Image2bis.png b/Docs/images/tutorial/get_started_gui/Tutorial1_Image2bis.png new file mode 100644 index 000000000..176612732 Binary files /dev/null and b/Docs/images/tutorial/get_started_gui/Tutorial1_Image2bis.png differ diff --git a/Docs/images/tutorial/get_started_gui/Tutorial1_Image3.PNG b/Docs/images/tutorial/get_started_gui/Tutorial1_Image3.PNG new file mode 100644 index 000000000..3c4918b11 Binary files /dev/null and b/Docs/images/tutorial/get_started_gui/Tutorial1_Image3.PNG differ diff --git a/Docs/images/tutorial/Tutorial1_Image4.PNG b/Docs/images/tutorial/get_started_gui/Tutorial1_Image4.PNG similarity index 100% rename from Docs/images/tutorial/Tutorial1_Image4.PNG rename to Docs/images/tutorial/get_started_gui/Tutorial1_Image4.PNG diff --git a/Docs/images/tutorial/get_started_gui/Tutorial1_ImageLast.gif b/Docs/images/tutorial/get_started_gui/Tutorial1_ImageLast.gif new file mode 100644 index 000000000..3dd4120b6 Binary files /dev/null and b/Docs/images/tutorial/get_started_gui/Tutorial1_ImageLast.gif differ diff --git a/Docs/images/tutorial/get_started_gui/Tutorial1_display_db.png b/Docs/images/tutorial/get_started_gui/Tutorial1_display_db.png new file mode 100644 index 000000000..a2a782fa4 Binary files /dev/null and b/Docs/images/tutorial/get_started_gui/Tutorial1_display_db.png differ diff --git a/Docs/images/tutorial/get_started_gui/Tutorial1_nm_landing.png b/Docs/images/tutorial/get_started_gui/Tutorial1_nm_landing.png new file mode 100644 index 000000000..c6dcff6e1 Binary files /dev/null and b/Docs/images/tutorial/get_started_gui/Tutorial1_nm_landing.png differ diff --git a/Docs/images/tutorial/get_started_gui/Tutorial1_nm_open.png b/Docs/images/tutorial/get_started_gui/Tutorial1_nm_open.png new file mode 100644 index 000000000..06f1d48b7 Binary files /dev/null and b/Docs/images/tutorial/get_started_gui/Tutorial1_nm_open.png differ diff --git a/Docs/images/matsim/activities_table.png b/Docs/images/tutorial/matsim/activities_table.png similarity index 100% rename from Docs/images/matsim/activities_table.png rename to Docs/images/tutorial/matsim/activities_table.png diff --git a/Docs/images/matsim/activity_receivers_table.png b/Docs/images/tutorial/matsim/activity_receivers_table.png similarity index 100% rename from Docs/images/matsim/activity_receivers_table.png rename to Docs/images/tutorial/matsim/activity_receivers_table.png diff --git a/Docs/images/tutorial/matsim/buildings_table.png b/Docs/images/tutorial/matsim/buildings_table.png new file mode 100644 index 000000000..d22a56145 Binary files /dev/null and b/Docs/images/tutorial/matsim/buildings_table.png differ diff --git a/Docs/images/tutorial/matsim/import_activities_wps.png b/Docs/images/tutorial/matsim/import_activities_wps.png new file mode 100644 index 000000000..1a33568d5 Binary files /dev/null and b/Docs/images/tutorial/matsim/import_activities_wps.png differ diff --git a/Docs/images/matsim/map_10h_qgis.png b/Docs/images/tutorial/matsim/map_10h_qgis.png similarity index 100% rename from Docs/images/matsim/map_10h_qgis.png rename to Docs/images/tutorial/matsim/map_10h_qgis.png diff --git a/Docs/images/tutorial/matsim/noise_from_source_wps.png b/Docs/images/tutorial/matsim/noise_from_source_wps.png new file mode 100644 index 000000000..d010819d7 Binary files /dev/null and b/Docs/images/tutorial/matsim/noise_from_source_wps.png differ diff --git a/Docs/images/tutorial/matsim/osm_pbf_wps.png b/Docs/images/tutorial/matsim/osm_pbf_wps.png new file mode 100644 index 000000000..97baccef0 Binary files /dev/null and b/Docs/images/tutorial/matsim/osm_pbf_wps.png differ diff --git a/Docs/images/tutorial/matsim/receiver_activities_wps.png b/Docs/images/tutorial/matsim/receiver_activities_wps.png new file mode 100644 index 000000000..3808804f9 Binary files /dev/null and b/Docs/images/tutorial/matsim/receiver_activities_wps.png differ diff --git a/Docs/images/matsim/results_10h_qgis.png b/Docs/images/tutorial/matsim/results_10h_qgis.png similarity index 100% rename from Docs/images/matsim/results_10h_qgis.png rename to Docs/images/tutorial/matsim/results_10h_qgis.png diff --git a/Docs/images/tutorial/matsim/results_export_wps.png b/Docs/images/tutorial/matsim/results_export_wps.png new file mode 100644 index 000000000..9d884c80c Binary files /dev/null and b/Docs/images/tutorial/matsim/results_export_wps.png differ diff --git a/Docs/images/matsim/roads_table.png b/Docs/images/tutorial/matsim/roads_table.png similarity index 100% rename from Docs/images/matsim/roads_table.png rename to Docs/images/tutorial/matsim/roads_table.png diff --git a/Docs/images/matsim/symbology_results_qgis.png b/Docs/images/tutorial/matsim/symbology_results_qgis.png similarity index 100% rename from Docs/images/matsim/symbology_results_qgis.png rename to Docs/images/tutorial/matsim/symbology_results_qgis.png diff --git a/Docs/images/tutorial/matsim/traffic_events_wps.png b/Docs/images/tutorial/matsim/traffic_events_wps.png new file mode 100644 index 000000000..fa59c7e69 Binary files /dev/null and b/Docs/images/tutorial/matsim/traffic_events_wps.png differ diff --git a/Docs/images/wps_api.png b/Docs/images/wps_api.png deleted file mode 100644 index c27534172..000000000 Binary files a/Docs/images/wps_api.png and /dev/null differ diff --git a/Docs/images/wps_api.svg b/Docs/images/wps_api.svg deleted file mode 100644 index def06931f..000000000 --- a/Docs/images/wps_api.svg +++ /dev/null @@ -1,930 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - Simple HTTP call with POST Method Your script - - {http..} - GeoServer - - - 1. POST ../geoserver/wps/.. - wps service - - groovy wps block - - 2. run groovy code - - 3. process response - - 4. http response - - - diff --git a/Docs/index.rst b/Docs/index.rst index bafe86f46..dbc151348 100644 --- a/Docs/index.rst +++ b/Docs/index.rst @@ -3,16 +3,18 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -NoiseModelling v5.0 User Guide +NoiseModelling User Guide ========================================== .. figure:: images/home/NoiseModelling_banner.png :align: center -Welcome on the **official NoiseModelling v5.0 User Guide**. +Welcome on the **official NoiseModelling User Guide**. -NoiseModelling is a library capable of producing noise maps. -It can be freely used either for research and education, as well as by experts in a professional use. +NoiseModelling is a free and open-source Java library for producing environmental noise maps from local to national scales, implementing CNOSSOS‑EU road and rail noise emission and propagation methods while linking to H2GIS and PostGIS for spatial analysis. +It responds to the need for robust noise assessment in public health and environmental planning by enabling simulation and prediction of noise propagation for mitigation design and compliance with EU regulations. +The software can be used independently or through a graphical interface and is openly available to the research, education, and professional communities. +It has been widely used for strategic noise mapping, dynamic maps driven by traffic models or sensors, sensitivity studies, and investigations of particular sources such as emergency sirens and drones. A general overview of the model (v3.4.5 - September 2020) can be found in `this video`_. @@ -28,29 +30,28 @@ A general overview of the model (v3.4.5 - September 2020) can be found in `this .. _this video : https://www.youtube.com/watch?v=V1-niMT9cYE&t=1s .. _offical NoiseModelling website : http://noise-planet.org/noisemodelling.html -What's new with the v5.0? ---------------------------- - -Since the release v5.0, **NoiseModelling validate the** `CNOSSOS-EU`_ **standard method** for the noise emission (road and rail (for France)) and with noise propagation (read ":doc:`Numerical_Model`", ":doc:`Validation`" and ":doc:`Cnossos_Report`" pages for more information). - -**Time periods are not limited to Day Evening and Night anymore**. You can provide the sound source emission for any period you want. You can also define a specific atmospheric condition for each time period now. - -The **computation time has been decreased**. The separation between path finding and attenuation has been done in preparation to the implementation of more noise propagation model (ex. Harmonoise). Packaging ************** -On the NoiseModelling latest `release page`_, three packages of NoiseModelling are proposed: +The latest `release page`_ offers three NoiseModelling packages: + +* ``NoiseModelling_X.X.X.zip``: A cross-platform version for Windows, Linux, and macOS. It includes the web GUI and a command-line interface. Please check the :doc:`Tutorial_Requirements` before installing, and refer to :doc:`Tutorial_Get_Started_Script` for CLI usage. +* ``NoiseModelling_X.X.X_install.exe``: A standalone Windows installer that includes the web GUI and a bundled Java Virtual Machine. +* ``NoiseModelling-X.X.X.dmg``: A standalone Mac OS installer that includes the web GUI and a bundled Java Virtual Machine. -* ``NoiseModelling_5.0.0.zip`` : cross-platform version, with GUI (Graphic User Interface) -* ``NoiseModelling_5.0.0_install.exe`` : windows installer, with GUI -* ``NoiseModelling_5.0.0_without_gui.zip`` : version without GUI. Usefull to run NoiseModelling using command lines (read ":doc:`Get_Started_Script`" page for more info) +.. warning:: + The Windows and Mac OS installer have not been signed yet. So you may have a security warning when installing and you are invited to follow additional steps to bypass this issue. + +In addition, a Docker image is provided in the `packages page`_. .. _CNOSSOS-EU: https://publications.jrc.ec.europa.eu/repository/handle/JRC72550 .. _release page : https://github.com/Universite-Gustave-Eiffel/NoiseModelling/releases/latest +.. _packages page : https://github.com/Universite-Gustave-Eiffel/NoiseModelling/pkgs/container/noisemodelling + Authors ---------------------------- +************** NoiseModelling project is leaded by acousticians from the *Joint Research Unit in Environmental Acoustics* (`UMRAE`_, Université Gustave Eiffel - Cerema) and Geographic Information Science specialists from `Lab-STICC`_ laboratory (CNRS - DECIDE Team). @@ -60,13 +61,13 @@ The NoiseModelling team owns the majority of the authorship of this application, .. _Lab-STICC: https://labsticc.fr Licence ---------------------------- +************** NoiseModelling and its documentation are distributed for free under GPL v3 :doc:`License`. Publications ---------------------------- +************** NoiseModelling was initially developed in a research context, which has led to numerous scientific publications. For more information, have a look to ":doc:`Scientific_production`" page. To quote this tool, please use the bibliographic reference below: @@ -79,7 +80,7 @@ To quote this tool, please use the bibliographic reference below: Fundings ---------------------------- +************** *Research projects:* @@ -153,16 +154,22 @@ Fundings :maxdepth: 2 :caption: Tutorials - Requirements - Get_Started_GUI - Noise_Map_From_OSM_Tutorial - Noise_Map_From_Point_Source - Matsim_Tutorial - Dynamic_Tutorial - Data_Assimilation_Tutorial - Get_Started_Script + Tutorial_Requirements + Tutorial_Get_Started_GUI + Tutorial_Noise_Map_From_Point_Source + Tutorial_Noise_Map_From_OSM + Tutorial_Matsim + Tutorial_Dynamic + Tutorial_Data_Assimilation + Tutorial_Get_Started_Script Tutorials_FAQ +.. toctree:: + :maxdepth: 2 + :caption: Functions + + Functions + .. toctree:: :maxdepth: 2 :caption: User Interface diff --git a/Docs/requirements.txt b/Docs/requirements.txt index 54ac817fd..8b6331764 100644 --- a/Docs/requirements.txt +++ b/Docs/requirements.txt @@ -26,13 +26,13 @@ markupsafe==2.1.1 # via jinja2 packaging==21.3 # via sphinx -pygments==2.15.0 +pygments==2.20.0 # via sphinx pyparsing==3.0.9 # via packaging pytz==2022.1 # via babel -requests==2.32.4 +requests==2.33.0 # via sphinx snowballstemmer==2.2.0 # via sphinx @@ -54,7 +54,7 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx -urllib3==1.26.19 +urllib3==2.6.3 # via requests sphinx-tabs==3.4.7 sphinxcontrib-bibtex==2.6.3 diff --git a/Docs/scripts/OwsLib_ExecuteProcess.py b/Docs/scripts/OwsLib_ExecuteProcess.py new file mode 100644 index 000000000..be9f99810 --- /dev/null +++ b/Docs/scripts/OwsLib_ExecuteProcess.py @@ -0,0 +1,32 @@ +import logging +import sys +from owslib.wps import WebProcessingService, monitorExecution + +def main(): + # Configure the root logger to output to stdout + logging.basicConfig(stream=sys.stdout, level=logging.INFO) + + url = "http://localhost:8000/builder/ows" + + # use java web token for authentification + jwt_token = "" + wps = WebProcessingService(url, skip_caps=False, headers={"Authorization": jwt_token}) + + target_id = "Database_Manager:Display_Database" + + inputs = [('showColumns', "true")] + + # Execute (sync or async) + execution = wps.execute(target_id, inputs) + + # Monitor progress if it's a long task + monitorExecution(execution, sleepSecs=2) + + if execution.isSucceded(): + for output in execution.processOutputs: + print(f"Result {output.identifier}: {output.data}") + else: + print("Execution failed.") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/Docs/scripts/OwsLib_ListProcess.py b/Docs/scripts/OwsLib_ListProcess.py new file mode 100644 index 000000000..73f98f26e --- /dev/null +++ b/Docs/scripts/OwsLib_ListProcess.py @@ -0,0 +1,40 @@ +import logging +import sys +from owslib.wps import WebProcessingService + +def main(): + # Configure the root logger to output to stdout + logging.basicConfig(stream=sys.stdout, level=logging.INFO) + + url = "http://localhost:8000/builder/ows" + + # use jwt cookie header for authentification + jwt_token = "" + wps = WebProcessingService(url, skip_caps=False, headers={"Authorization": jwt_token}) + + # 2. List all available processes + print(f"\n--- Available Processes ---") + for process in wps.processes: + print(f"ID: {process.identifier}") + print(f" Title: {process.title}") + print(f" Abstract: {process.abstract}\n") + process_details = wps.describeprocess(process.identifier) + print(f" Inputs:") + for data_input in process_details.dataInputs: + print(f" ID: {data_input.identifier}") + if hasattr(data_input, 'title'): + print(f" Title: {data_input.title}") + if hasattr(data_input, 'dataType'): + print(f" Data Type: {data_input.dataType}") + if hasattr(data_input, 'minOccurs') and data_input.minOccurs == 0: + print(f" Optional") + if hasattr(data_input, 'abstract'): + print(f" Abstract: {data_input.abstract}") + if hasattr(data_input, 'allowedValues') and len(data_input.allowedValues) > 0: + print(f" Allowed values: {data_input.allowedValues}") + if hasattr(data_input, 'defaultValue') and data_input.defaultValue is not None: + print(f" Default : {data_input.defaultValue}") + print("") + +if __name__ == "__main__": + main() diff --git a/Docs/scripts/data_assimilation_all_configurations.bash b/Docs/scripts/data_assimilation_all_configurations.bash index 98cfa31c0..91a4afa0c 100644 --- a/Docs/scripts/data_assimilation_all_configurations.bash +++ b/Docs/scripts/data_assimilation_all_configurations.bash @@ -1,3 +1 @@ -cd /home/.../NoiseModelling_5.0.1/ - -./bin/wps_scripts -w ./ -s data_dir/scripts/wps/Data_Assimilation/All_Possible_Configuration.groovy -trafficValues "0.01,1,2" -temperatureValues "10,15,20" \ No newline at end of file +./bin/wps_scripts -w ./ -s scripts/Data_Assimilation/All_Possible_Configuration.groovy -trafficValues "0.01,1,2" -temperatureValues "10,15,20" diff --git a/Docs/scripts/get_started.py b/Docs/scripts/get_started.py deleted file mode 100644 index ae937d9c1..000000000 --- a/Docs/scripts/get_started.py +++ /dev/null @@ -1,61 +0,0 @@ -import urllib.request -from string import Template - -import_file = Template('Import_and_Export:Import_FilepathFile$pathresult') - -get_lday = Template('NoiseModelling' - ':Noise_level_from_traffictableReceivers$table_receiverstableBuilding$table_buildingstableDEM$table_demtableRoads$table_roadsresult') - -export_table = Template('Import_and_Export:Export_TabletableToExport$table_to_exportexportPath$export_pathresult') - - -def call_geoserver(data): - req = urllib.request.Request(url='http://localhost:9580/geoserver/ows', data=bytes(data, encoding="utf8"), - method='POST') - req.add_header('Content-Type', 'application/xml; charset=utf-8') - - with urllib.request.urlopen(req) as f: - print(f.status) - print(f.reason) - if f.status == 200: - print(str(f.read(), encoding="utf8")) - - -call_geoserver(import_file.substitute({"path": "data_dir/data/wpsdata/buildings.shp"})) -call_geoserver(import_file.substitute({"path": "data_dir/data/wpsdata/ground_type.shp"})) -call_geoserver(import_file.substitute({"path": "data_dir/data/wpsdata/receivers.shp"})) -call_geoserver(import_file.substitute({"path": "data_dir/data/wpsdata/roads.shp"})) -call_geoserver(import_file.substitute({"path": "data_dir/data/wpsdata/dem.geojson"})) - -call_geoserver(get_lday.substitute({"table_receivers": "RECEIVERS", "table_buildings": "BUILDINGS" - , "table_roads": "ROADS", "table_dem": "DEM"})) - -call_geoserver(export_table.substitute({"table_to_export": "RECEIVERS_LEVEL", "export_path" : "RECEIVERS_LEVEL.shp"})) diff --git a/Docs/scripts/get_started_tutorial_complex.groovy b/Docs/scripts/get_started_tutorial_complex.groovy deleted file mode 100644 index 9a59f0b56..000000000 --- a/Docs/scripts/get_started_tutorial_complex.groovy +++ /dev/null @@ -1,70 +0,0 @@ -/** - * NoiseModelling is an open-source tool designed to produce environmental noise maps - * on very large urban areas. It can be used as a Java library or be controlled through - * a user friendly web interface. - * - * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the - * Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). - * - * - * NoiseModelling is distributed under GPL 3 license. You can read a copy of this - * License in the file LICENCE provided with this software. - * - * Contact: contact@noise-planet.org - */ - -/** - * @Author Pierre Aumond, Université Gustave Eiffel - * @Author Nicolas Fortin, Université Gustave Eiffel - */ - -import org.h2gis.api.ProgressVisitor -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import java.sql.Connection - -title = 'Tutorial script' -description = 'Long description of tutorial script' - -inputs = [] - -outputs = [result: [name: 'Result output string', title: 'Result output string', description: 'This type of result does not allow the blocks to be linked together.', type: String.class]] - - -def runScript(connection, scriptFile, arguments) { - Logger logger = LoggerFactory.getLogger("script") - GroovyShell shell = new GroovyShell() - Script scriptInstance = shell.parse(new File(scriptFile)) - Object result = scriptInstance.invokeMethod("exec", [connection, arguments]) - if(result != null) { - logger.info(result.toString()) - } -} - -def exec(Connection connection, input) { - - // Step 4: Upload files to database - runScript(connection, "noisemodelling/wps/Import_and_Export/Import_File.groovy", - ["pathFile":"resources/org/noise_planet/noisemodelling/wps/ground_type.shp"]) - - runScript(connection, "noisemodelling/wps/Import_and_Export/Import_File.groovy", - ["pathFile":"resources/org/noise_planet/noisemodelling/wps/buildings.shp"]) - - runScript(connection, "noisemodelling/wps/Import_and_Export/Import_File.groovy", - ["pathFile":"resources/org/noise_planet/noisemodelling/wps/receivers.shp"]) - - runScript(connection, "noisemodelling/wps/Import_and_Export/Import_File.groovy", - ["pathFile":"resources/org/noise_planet/noisemodelling/wps/ROADS2.shp"]) - - runScript(connection, "noisemodelling/wps/Import_and_Export/Import_File.groovy", - ["pathFile":"resources/org/noise_planet/noisemodelling/wps/dem.geojson"]) - - // Step 5: Run Calculation - runScript(connection, "noisemodelling/wps/NoiseModelling/Noise_level_from_traffic.groovy", - ["tableBuilding":"BUILDINGS", "tableRoads":"ROADS2", "tableReceivers":"RECEIVERS", - "tableDEM":"DEM", "tableGroundAbs":"GROUND_TYPE"]) - - // Step 6: Export (& see) the results - runScript(connection, "noisemodelling/wps/Import_and_Export/Export_Table.groovy", - ["exportPath":"RECEIVERS_LEVEL.shp", "tableToExport":"RECEIVERS_LEVEL"]) -} \ No newline at end of file diff --git a/Docs/scripts/get_started_tutorial_simple.bash b/Docs/scripts/get_started_tutorial_simple.bash index 47d185bb2..758babc3b 100644 --- a/Docs/scripts/get_started_tutorial_simple.bash +++ b/Docs/scripts/get_started_tutorial_simple.bash @@ -5,15 +5,15 @@ # Step 4: Upload files to database # create (or load existing) database and load a shape file into the database -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/ground_type.shp -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/buildings.shp -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/receivers.shp -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/ROADS2.shp -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/dem.geojson +./bin/ScriptRunner -w ./ -s scripts/Import_and_Export/Import_File.groovy --pathFile resources/ground_type.shp +./bin/ScriptRunner -w ./ -s scripts/Import_and_Export/Import_File.groovy --pathFile resources/buildings.shp +./bin/ScriptRunner -w ./ -s scripts/Import_and_Export/Import_File.groovy --pathFile resources/receivers.shp +./bin/ScriptRunner -w ./ -s scripts/Import_and_Export/Import_File.groovy --pathFile resources/ROADS2.shp +./bin/ScriptRunner -w ./ -s scripts/Import_and_Export/Import_File.groovy --pathFile resources/dem.geojson # Step 5: Run Calculation -./bin/wps_scripts -w ./ -s noisemodelling/wps/NoiseModelling/Noise_level_from_traffic.groovy -tableBuilding BUILDINGS -tableRoads ROADS2 -tableReceivers RECEIVERS -tableDEM DEM -tableGroundAbs GROUND_TYPE +./bin/ScriptRunner -w ./ -s scripts/NoiseModelling/Noise_level_from_sources.groovy --tableBuilding BUILDINGS --tableSources ROADS2 --tableReceivers RECEIVERS --tableDEM DEM --tableGroundAbs GROUND_TYPE # Step 6: Export (& see) the results -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Export_Table.groovy -exportPath RECEIVERS_LEVEL.shp -tableToExport RECEIVERS_LEVEL +./bin/ScriptRunner -w ./ -s scripts/Import_and_Export/Export_Table.groovy --exportPath RECEIVERS_LEVEL.shp --tableToExport RECEIVERS_LEVEL diff --git a/Docs/scripts/nm_terminal.bash b/Docs/scripts/nm_terminal.bash index f5a01e176..b57dfbefe 100644 --- a/Docs/scripts/nm_terminal.bash +++ b/Docs/scripts/nm_terminal.bash @@ -1,3 +1,3 @@ -cd /home/user/NoiseModelling_5.0.0_without_gui/ +cd /home/user/NoiseModelling/ -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/ground_type.shp +./bin/ScriptRunner -w ./ -s scripts/Import_and_Export/Import_File.groovy --pathFile resources/ground_type.shp diff --git a/Docs/scripts/run_get_started_tutorial_complex.bash b/Docs/scripts/run_get_started_tutorial_complex.bash new file mode 100644 index 000000000..74e7dfaaa --- /dev/null +++ b/Docs/scripts/run_get_started_tutorial_complex.bash @@ -0,0 +1 @@ +./bin/ScriptRunner -w ./ -s get_started_tutorial_complex.groovy diff --git a/README.md b/README.md index 1db13487d..ea6bffdd7 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,110 @@ -[![CI](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/actions/workflows/CI.yml/badge.svg?branch=4.X)](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/actions/workflows/CI.yml) +[![CI](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/actions/workflows/CI.yml) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Documentation Status](https://readthedocs.org/projects/noisemodelling/badge/?version=latest)](https://noisemodelling.readthedocs.io/en/latest/?badge=latest) [![GitHub release](https://img.shields.io/github/release/Universite-Gustave-Eiffel/NoiseModelling)](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/releases/) +[![LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/company/noise-planet/) + NoiseModelling =============== -NoiseModelling is a library capable of producing noise maps. -It can be freely used either for research and education, as well as by experts in a professional use. +NoiseModelling is a free and open-source Java library for producing environmental noise maps from local to national scales, implementing CNOSSOS‑EU road and rail noise emission and propagation methods while linking to H2GIS and PostGIS for spatial analysis. + +It responds to the need for robust noise assessment in public health and environmental planning by enabling simulation and prediction of noise propagation for mitigation design and compliance with EU regulations. + +The software can be used independently or through a graphical interface and is openly available to the research, education, and professional communities. + +It has been widely used for strategic noise mapping, dynamic maps driven by traffic models or sensors, sensitivity studies, and investigations of particular sources such as emergency sirens and drones. + +## Features + +* **CNOSSOS-EU Implementation:** Fully implements the European standard method (Commission Directive 2015/996) for road traffic and railway noise. +* **Advanced Propagation Physics:** + * **Geometrical Attenuation:** Geometric dispersion of sound wave from point and line sources. + * **Atmospheric Absorption:** Frequency-dependent attenuation. + * **Ground Effect:** Impact of ground porosity (hard/soft) and terrain. + * **Diffraction:** Support for diffraction over and around obstacles (vertical and horizontal edges). + * **Specular Reflections:** Calculations for reflections on vertical surfaces like buildings and noise barriers with customizable order of reflection. +* **Meteorological Conditions:** Support for both homogeneous and favorable propagation scenarios. +* **Full Spectral Analysis:** Calculations performed across standard third/full octave bands (50 Hz to 10000 Hz). +* **Emission Models:** Calculate noise emissions based on traffic flow, vehicle speed, and pavement type. +* **Performance:** Optimized for large-scale urban areas using an embedded spatial database (H2GIS). The support for PostGIS is currently available but in progress. + +### GIS & Data Integration +* **Direct OSM Import:** Built-in tools to import and process OpenStreetMap data for buildings, road networks and ground absorption. +* **Format Support:** Compatible with major GIS formats and database manager (DBeaver) through its spatial database library, including Shapefiles, GeoJSON, FlatGeobuf, Esri ASCII Grid etc. +* **Topography Support:** Ability to integrate Digital Elevation Models (DEM) to account for terrain effects (Points and/or Lines). +* **Spatial Analysis:** Advanced spatial queries to match noise levels with population data for exposure impact studies. + +### Automation & Scripting +* **Groovy Scripting:** Create and automate complex workflows using dynamic Groovy scripts. +* **WPS Interface:** Exposes noise calculation processes as OGC Web Processing Services (WPS), allowing integration with WPS compatible tools. +* **Java API:** Can be integrated as a library into existing Java applications for custom environmental modeling tools. +* **Headless Mode:** Run simulations using the NoiseModelling Command Line Interface instead of using the user graphical interface. + +### Deployment & Accessibility +* **Web Interface:** User-friendly web-based GUI for configuring simulations and visualizing results. +* **Docker Support:** Ready-to-use Docker images for quick deployment across different operating systems. +* **Cross-Platform:** Runs on Windows, Linux, and macOS thanks to the Java runtime environment. +* **Open Source:** Transparent algorithms and open-source license (GPLv3) ensuring reproducibility in scientific and regulatory contexts. + +### Output & Visualization +* **Noise Indicators:** Calculate standard indicators such as $L_{eq}$, $LA_{eq}$, $L_{den}$, $L_{day}$, $L_{evening}$, and $L_{night}$. +* **Grid & Receiver Maps:** Generate noise maps on a regular grid, smooth adaptative Delaunay or at specific receiver points (e.g., building facades). +* **Population Exposure:** Produce statistical reports on the number of people exposed to different noise levels. +* **Seamless Export:** Export results directly to GIS software (like QGIS) for professional cartographic rendering. + +### Dynamic Noise Mapping +* **Time-Varying Simulations:** Go beyond static maps by generating noise levels at regular time intervals (e.g., every 15 minutes or hourly) +* **Moving Source Integration:** Import spatio-temporal trajectories from traffic simulators like **SUMO**, **Symuvia**, or **MATSim**, as well as custom paths for moving sources like drones. +* **Advanced Statistics:** Calculate dynamic indicators such as percentile levels ($L_{A10}$, $L_{A50}$, $L_{A90}$) and event-based metrics (e.g., number of exceedances). +* **Stochastic Traffic Modeling:** Supports both Probabilistic and Poisson distribution methods to realistically simulate vehicle placement and flow on road networks. +* **Temporal Visualization:** Compatible with the QGIS Temporal Controller for creating animated noise maps over time. + +![QGIS Temporal Controller interface showing a timeline for noise map playback](Docs/images/tutorial/dynamic/temporal_bar_nav.gif) +*Example: Navigating through a dynamic noise map using the QGIS Temporal Controller.* + +![The NoiseModelling WPS Builder interface](Docs/images/WPS_Builder/wps_demo.png) +*Example: The WPS Builder allows users to visually configure simulation parameters and execute spatial tasks.* + + +Documentation +--------------------------- + +An online documentation is available : [NOISEMODELLING DOCUMENTATION](https://noisemodelling.readthedocs.io/en/latest/). + +Here you'll find a wealth of useful information, including many step-by-step tutorials on how to use NoiseModelling. -* for **more information** on NoiseModelling, [visit the online documentation](https://noisemodelling.readthedocs.io/en/latest/) -* to **contribute to NoiseModelling** source code, follow the ["Get Started Dev"](https://noisemodelling.readthedocs.io/en/latest/Get_Started_Dev.html) page -* to **contact the support / development team**, - - open an issue : https://github.com/Universite-Gustave-Eiffel/NoiseModelling/issues or a write a message : https://github.com/Universite-Gustave-Eiffel/NoiseModelling/discussions *(we prefer these two options)* - - send us an email at ``contact@noise-planet.org`` -* follow us on [LinkedIn](https://www.linkedin.com/company/noise-planet/) Stable release --------------------------- -The current stable version is v5.0.0 (see [latest release](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/releases/latest) page) +The current stable version of NoiseModelling can be found here: [latest release](https://github.com/Universite-Gustave-Eiffel/NoiseModelling/releases/latest) + +Deployment on a public server +--------------------------- + +**Containerized Environment:** Fully compatible with **Docker** and **Podman** for rapid, reproducible deployment across Linux, Windows, and macOS. +> [!TIP] +> For detailed setup procedures, including environment variables and configuration, visit the **[Docker Setup & Architecture Guide](https://noisemodelling.readthedocs.io/en/latest/Architecture.html#docker-setup)**. -Documentation +Contribute --------------------------- -An online documentation is available [here](https://noisemodelling.readthedocs.io/en/latest/). Here you'll find a wealth of useful information, including numerous step-by-step tutorials on how to use NoiseModelling. +To **contribute to NoiseModelling** source code, please read our [CONTRIBUTING](CONTRIBUTING.md) guide and the ["Get Started Dev"](https://noisemodelling.readthedocs.io/en/latest/Get_Started_Dev.html) page + + +Help & Support +--------------------------- + +To ask for help or contact the development team, you can either: + +- open an issue : https://github.com/Universite-Gustave-Eiffel/NoiseModelling/issues or a write a message : https://github.com/Universite-Gustave-Eiffel/NoiseModelling/discussions *(we prefer these two options)* +- send us an email at ``contact@noise-planet.org`` + Authors --------------------------- @@ -36,13 +113,15 @@ NoiseModelling project is leaded by acousticians from the *Joint Research Unit i The NoiseModelling team owns the majority of the authorship of this application, but any external contributions are warmly welcomed. + Licence --------------------------- -NoiseModelling and its documentation are distributed for free and under the open-source [GPL v3](https://noisemodelling.readthedocs.io/en/latest/License.html) licence. +NoiseModelling and its documentation are distributed for free and under the open-source [GPL v3](https://noisemodelling.readthedocs.io/en/latest/License.html) licence. + Publications & Fundings -------------------------------------- -* [Scientific production](https://noisemodelling.readthedocs.io/en/latest/Scientific_production.html) +* [Scientific production](https://noisemodelling.readthedocs.io/en/latest/Scientific_production.html) * [Fundings](https://noisemodelling.readthedocs.io/en/latest/index.html#fundings) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..7acd8c214 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +volumes: + noisemodelling-db: + driver: local + +services: + noisemodelling: + image: ghcr.io/universite-gustave-eiffel/noisemodelling:main + restart: unless-stopped + ports: + - "8000:8000" + environment: + PROXY_BASE_URL: "http://localhost:8000" # Replace with your domain name + JAVA_OPTS: "-Xmx2g" # Maximal memory usage + ROOT_URL: "" # You can host it on a subpath ex: /noisemodelling/ by default + DB_ENCRYPTION_SECRET: "changeme" # Main database encryption password to protect the totp tokens + volumes: + - noisemodelling-db:/srv/noisemodelling/workspace + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000"] + interval: 15s + timeout: 5s + retries: 3 + start_period: 10s \ No newline at end of file diff --git a/installer/Logo_noisemodelling_square.icns b/installer/Logo_noisemodelling_square.icns new file mode 100644 index 000000000..95a076cf5 Binary files /dev/null and b/installer/Logo_noisemodelling_square.icns differ diff --git a/installer/Logo_noisemodelling_square.svg b/installer/Logo_noisemodelling_square.svg new file mode 100644 index 000000000..244372f23 --- /dev/null +++ b/installer/Logo_noisemodelling_square.svg @@ -0,0 +1,186 @@ + + + + diff --git a/installer/installer.nsi b/installer/installer.nsi new file mode 100644 index 000000000..7b610e85c --- /dev/null +++ b/installer/installer.nsi @@ -0,0 +1,102 @@ + + +!define APP_NAME "NoiseModelling" +!define APP_PUBLISHER "Noise-Planet" +!define APP_URL "https://noise-planet.org" +!define EXE_NAME "NoiseModelling.exe" +!ifndef MAVEN_VERSION + !define MAVEN_VERSION "dev" +!endif +!define INSTALLER_NAME "NoiseModelling-${MAVEN_VERSION}-Setup.exe" +!define INSTALL_DIR "$PROGRAMFILES64\${APP_NAME}" +!define UNINSTALL_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" + + +!ifndef APP_VERSION + !define APP_VERSION "0.0.0" +!endif + + +Name "${APP_NAME} ${MAVEN_VERSION}" +OutFile "${INSTALLER_NAME}" +InstallDir "${INSTALL_DIR}" +InstallDirRegKey HKLM "${UNINSTALL_KEY}" "InstallLocation" +RequestExecutionLevel admin +SetCompressor /SOLID lzma +Unicode True + + +!include "MUI2.nsh" + +!define MUI_ABORTWARNING +!define MUI_ICON "noisemodelling.ico" +!define MUI_UNICON "noisemodelling.ico" + +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE "..\LICENSE" +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH + +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +!insertmacro MUI_LANGUAGE "French" +!insertmacro MUI_LANGUAGE "English" + +Section "NoiseModelling" SecMain + SectionIn RO + + SetOutPath "$INSTDIR" + File /r "app\*" + File "NoiseModelling.exe" + File "noisemodelling.ico" + + + SetOutPath "$INSTDIR\jre" + File /r "jre\*.*" + + + CreateShortcut "$DESKTOP\${APP_NAME}.lnk" \ + "$INSTDIR\${EXE_NAME}" \ + "" \ + "$INSTDIR\noisemodelling.ico" 0 + + + CreateDirectory "$SMPROGRAMS\${APP_NAME}" + CreateShortcut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" \ + "$INSTDIR\${EXE_NAME}" \ + "" \ + "$INSTDIR\noisemodelling.ico" 0 + CreateShortcut "$SMPROGRAMS\${APP_NAME}\Uninstall ${APP_NAME}.lnk" \ + "$INSTDIR\Uninstall.exe" + + WriteUninstaller "$INSTDIR\Uninstall.exe" + + WriteRegStr HKLM "${UNINSTALL_KEY}" "DisplayName" "${APP_NAME} ${MAVEN_VERSION}" + WriteRegStr HKLM "${UNINSTALL_KEY}" "DisplayVersion" "${MAVEN_VERSION}" + WriteRegStr HKLM "${UNINSTALL_KEY}" "Publisher" "${APP_PUBLISHER}" + WriteRegStr HKLM "${UNINSTALL_KEY}" "URLInfoAbout" "${APP_URL}" + WriteRegStr HKLM "${UNINSTALL_KEY}" "InstallLocation" "$INSTDIR" + WriteRegStr HKLM "${UNINSTALL_KEY}" "UninstallString" "$INSTDIR\Uninstall.exe" + WriteRegDWORD HKLM "${UNINSTALL_KEY}" "NoModify" 1 + WriteRegDWORD HKLM "${UNINSTALL_KEY}" "NoRepair" 1 + +SectionEnd + +Section "Uninstall" + + Delete "$INSTDIR\${EXE_NAME}" + Delete "$INSTDIR\noisemodelling.ico" + Delete "$INSTDIR\Uninstall.exe" + RMDir /r "$INSTDIR" + + + Delete "$DESKTOP\${APP_NAME}.lnk" + Delete "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" + Delete "$SMPROGRAMS\${APP_NAME}\Uninstall ${APP_NAME}.lnk" + RMDir "$SMPROGRAMS\${APP_NAME}" + + DeleteRegKey HKLM "${UNINSTALL_KEY}" + +SectionEnd diff --git a/installer/launch4j-config.xml b/installer/launch4j-config.xml new file mode 100644 index 000000000..e591cac1d --- /dev/null +++ b/installer/launch4j-config.xml @@ -0,0 +1,37 @@ + + console + + true + + NoiseModelling.exe + + noisemodelling.ico + + . + + + org.noise_planet.noisemodelling.webserver.NoiseModellingServer + lib/*.jar + + + -u -s scripts + + + jre + 11 + + + APP_VERSION_PLACEHOLDER + APP_VERSION_PLACEHOLDER + + APP_VERSION_TXT_PLACEHOLDER + APP_VERSION_TXT_PLACEHOLDER + + NoiseModelling + NoiseModelling + NoiseModelling.exe + © 2026 Noise-Planet + NoiseModelling + + + diff --git a/installer/noisemodelling.ico b/installer/noisemodelling.ico new file mode 100644 index 000000000..b3c2a2c82 Binary files /dev/null and b/installer/noisemodelling.ico differ diff --git a/nbactions.xml b/nbactions.xml deleted file mode 100644 index 40d520b1e..000000000 --- a/nbactions.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - build-with-dependencies - . - also-make - - install - - - - run - - process-classes - org.codehaus.mojo:exec-maven-plugin:1.1.1:exec - - - /media/projects_/module_bruit/data_computed/2011_07_25 - runtime - -Xms1024m -classpath %classpath org.noisemap.run.trigrid -ib bati_in_fence.gdms -is expline_source.gdms -o trilvl.gdms - java - - - - debug - - process-classes - org.codehaus.mojo:exec-maven-plugin:1.1.1:exec - - - /media/projects_/module_bruit/data_computed/2011_07_25 - runtime - -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -Xms1024m -classpath %classpath org.noisemap.run.trigrid -ib bati_in_fence.gdms -is expline_source.gdms -o trilvl.gdms - true - java - - - diff --git a/noisemodelling-emission/pom.xml b/noisemodelling-emission/pom.xml index 52ccfd22d..e3fa86f11 100644 --- a/noisemodelling-emission/pom.xml +++ b/noisemodelling-emission/pom.xml @@ -10,7 +10,7 @@ org.noise-planet noisemodelling-parent - 5.0.2-SNAPSHOT + 6.0.1-SNAPSHOT ../pom.xml Computes sound emission levels from sound source characteristics (vehicle flow, vehicle type, sound diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/RailWayParametersvar.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/RailWayParametersvar.java new file mode 100644 index 000000000..ab2961374 --- /dev/null +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/RailWayParametersvar.java @@ -0,0 +1,76 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

+ * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

+ * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + +package org.noise_planet.noisemodelling.emission.railway; +/** + * Railway noise evaluation from Cnossos reference : COMMISSION DIRECTIVE (EU) 2015/996 + * of 19 May 2015 establishing common noise assessment methods according to Directive 2002/49/EC + * of the European Parliament and of the Council + * + * amending, for the purposes of adapting to scientific and technical progress, Annex II to + * Directive 2002/49/EC of the European Parliament and of the Council as regards + * common noise assessment methods + * + * part 2.3. Railway noise + * + * Return the dB value corresponding to the parameters + * @author Adrien Le Bellec, Université Gustave Eiffel + * @author Olivier Chiello, Université Gustave Eiffel + */ + +import org.noise_planet.noisemodelling.emission.LineSource; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static org.noise_planet.noisemodelling.emission.utils.Utils.sumDbArray; + +/** + * Data result stockage + */ +public class RailWayParametersvar { + public Map railwaySourceList = new HashMap<>(); + + + public Map getRailwaySourceList() { + return railwaySourceList; + } + + public void setRailwaySourceList(Map railwaySourceList) { + this.railwaySourceList = railwaySourceList; + } + + /** + * method adds a railway source to the list of railway sources, associating it with a specified ID. + * @param ID + * @param lineSource + */ + public void addRailwaySource(String ID, LineSource lineSource) { + this.railwaySourceList.put(ID, lineSource); + } + + /** + * + * @param lineSource1 + * @param lineSource2 + * @return an instance of RailWayParameters + */ + public RailWayParametersvar sumRailwaySource(RailWayParametersvar lineSource1, RailWayParametersvar lineSource2) { + if (!lineSource2.getRailwaySourceList().isEmpty()){ + for (Map.Entry railwaySourceEntry : lineSource1.getRailwaySourceList().entrySet()) { + double[] lW1 = railwaySourceEntry.getValue().getlW(); + double[] lW2 = lineSource2.getRailwaySourceList().get(railwaySourceEntry.getKey()).getlW(); + lineSource1.getRailwaySourceList().get(railwaySourceEntry.getKey()).setlW(sumDbArray(lW1, lW2)); + } + } + return lineSource1; + } + +} diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/Railway.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/Railway.java index 692eb403f..9c7bd1d6a 100644 --- a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/Railway.java +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/Railway.java @@ -13,9 +13,13 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.NullNode; +import org.noise_planet.noisemodelling.emission.utils.UriUtils; import java.io.IOException; import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; import java.util.Iterator; import java.util.Map; @@ -50,14 +54,42 @@ public static Iterable iteratorToIterable(Iterator iterator) { return () -> iterator; } - public void setVehicleDataFile(String VehicleData) { - this.vehicleData = parse(Railway.class.getResourceAsStream(VehicleData)); + /** + * Retrieves an InputStream from a resource string, which can either be a URI or a classpath resource. + * If the resource string represents a valid URI, the input stream is opened from the URI. + * Otherwise, the input stream is retrieved from the classpath using the resource string. + * + * @param resource the resource string, which can be a URI or a classpath resource + * @return the InputStream corresponding to the resource + * @throws IOException if the resource cannot be found or accessed + */ + private static InputStream getStreamFromResourceString(String resource) throws IOException { + if (UriUtils.isValidUri(resource)) { + return UriUtils.openSafeStream(resource); + } else { + InputStream stream = Railway.class.getResourceAsStream(resource); + if (stream == null) { + throw new IOException("Resource not found: " + resource); + } + return stream; + } } - public void setTrainSetDataFile(String TrainsetData) { - this.trainsetData = parse(Railway.class.getResourceAsStream(TrainsetData)); + + public void setVehicleDataFile(String VehicleData) throws IOException { + try (InputStream stream = getStreamFromResourceString(VehicleData)) { + this.vehicleData = parse(stream); + } + } + + public void setTrainSetDataFile(String trainsetResource) throws IOException { + try (InputStream stream = getStreamFromResourceString(trainsetResource)) { + this.trainsetData = parse(stream); + } } - public void setRailwayDataFile(String RailWayData) { - this.railWayData = parse(Railway.class.getResourceAsStream(RailWayData)); + public void setRailwayDataFile(String railwayResource) throws IOException { + try (InputStream stream = getStreamFromResourceString(railwayResource)) { + this.railWayData = parse(stream); + } } public JsonNode getVehicleNode(String typeVehicle) { diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/RailwayVehicleParametersvar.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/RailwayVehicleParametersvar.java new file mode 100644 index 000000000..9dc241885 --- /dev/null +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/RailwayVehicleParametersvar.java @@ -0,0 +1,60 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

+ * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

+ * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + +package org.noise_planet.noisemodelling.emission.railway; + +/** + * Railway noise evaluation from Cnossos reference : COMMISSION DIRECTIVE (EU) 2015/996 + * of 19 May 2015 establishing common noise assessment methods according to Directive 2002/49/EC + * of the European Parliament and of the Council + * + * amending, for the purposes of adapting to scientific and technical progress, Annex II to + * Directive 2002/49/EC of the European Parliament and of the Council as regards + * common noise assessment methods + * + * part 2.3. Railway noise + * + * @author Adrien Le Bellec, Université Gustave Eiffel + * @author Olivier Chiello, Université Gustave Eiffel + */ + +/** + * Parameters Vehicule + */ + +public class RailwayVehicleParametersvar { + + // set default value + private String typeVehicle = ""; // name of the vehicles + private double speedVehicle; // speed of the vehicles (km/h) + + + public RailwayVehicleParametersvar() { + + setTypeVehicle(typeVehicle); + setSpeedVehicle(speedVehicle); + } + + public String getTypeVehicle() { + return typeVehicle; + } + + public void setTypeVehicle(String typeVehicle) { + this.typeVehicle = typeVehicle; + } + + public double getSpeedVehicle() { + return speedVehicle; + } + + public void setSpeedVehicle(double speedVehicle) { + this.speedVehicle = speedVehicle; + } + +} diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailwayCnossos.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailwayCnossos.java index 941313f4b..abb021906 100644 --- a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailwayCnossos.java +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailwayCnossos.java @@ -13,9 +13,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.NullNode; import org.noise_planet.noisemodelling.emission.LineSource; +import org.noise_planet.noisemodelling.emission.railway.Railway; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import java.util.Iterator; import java.util.Locale; @@ -38,34 +40,24 @@ * @author Olivier Chiello, Université Gustave Eiffel */ -public class RailwayCnossos extends org.noise_planet.noisemodelling.emission.railway.Railway { +public class RailwayCnossos extends Railway { public RailwayCnossos() { } - /** - * - * @param inputStream - * @return + * Helper to read a Ref field from a vehicle JSON node. + * Supports both string (new merged file) and integer (legacy files) JSON values. + * @param vehicleNode the JSON node of the vehicle + * @param fieldName the Ref field name (e.g. "RefRoughness") + * @return the string value of the reference */ - private static JsonNode parse(InputStream inputStream) { - try { - ObjectMapper mapper = new ObjectMapper(); - return mapper.readTree(inputStream); - } catch (IOException ex) { - return NullNode.getInstance(); + private static String getRefValue(JsonNode vehicleNode, String fieldName) { + JsonNode value = vehicleNode.get(fieldName); + if (value.isTextual()) { + return value.textValue(); } - } - - /** - * - * @param iterator - * @return an iterator - * @param - */ - public static Iterable iteratorToIterable(Iterator iterator) { - return () -> iterator; + return String.valueOf(value.intValue()); } /** @@ -76,8 +68,8 @@ public static Iterable iteratorToIterable(Iterator iterator) { * @return */ public Double getWheelRoughness(String typeVehicle, String fileVersion, int lambdaId) { // - int refId = getVehicleNode(typeVehicle).get("RefRoughness").intValue(); - return getRailWayData().get("Vehicle").get("WheelRoughness").get(String.valueOf(refId)).get("Values").get(lambdaId).doubleValue(); + String refId = getRefValue(getVehicleNode(typeVehicle), "RefRoughness"); + return getRailWayData().get("Vehicle").get("WheelRoughness").get(refId).get("Values").get(lambdaId).doubleValue(); } /** @@ -87,8 +79,8 @@ public Double getWheelRoughness(String typeVehicle, String fileVersion, int lamb * @return contact filter */ public Double getContactFilter(String typeVehicle, int lambdaId) { // - int refId = getVehicleNode(typeVehicle).get("RefContact").intValue(); - return getRailWayData().get("Vehicle").get("ContactFilter").get(String.valueOf(refId)).get("Values").get(lambdaId).doubleValue(); + String refId = getRefValue(getVehicleNode(typeVehicle), "RefContact"); + return getRailWayData().get("Vehicle").get("ContactFilter").get(refId).get("Values").get(lambdaId).doubleValue(); } /** @@ -97,8 +89,8 @@ public Double getContactFilter(String typeVehicle, int lambdaId) { // * @param lambdaId * @return */ - public Double getTrackRoughness(int trackRoughnessId, int lambdaId) { // - return getRailWayData().get("Track").get("RailRoughness").get(String.valueOf(trackRoughnessId)).get("Values").get(lambdaId).doubleValue(); + public Double getTrackRoughness(String trackRoughnessId, int lambdaId) { // + return getRailWayData().get("Track").get("RailRoughness").get(trackRoughnessId).get("Values").get(lambdaId).doubleValue(); } /** @@ -136,11 +128,11 @@ public int getNbCoach(String typeVehicle) { // * @return */ public double getTractionNoise(String typeVehicle, int runningCondition, String sourceHeightId, String fileVersion, int freqId) { // - int refId = getVehicleNode(typeVehicle).get("RefTraction").intValue(); - double tractionSpectre =0; + String refId = getRefValue(getVehicleNode(typeVehicle), "RefTraction"); + double tractionSpectrum = 0; - String condition = "ConstantSpeed"; - if (refId != 0) { + if (refId != null && !refId.isEmpty()) { + String condition = "ConstantSpeed"; switch (runningCondition) { case 0: condition = "ConstantSpeed"; @@ -155,15 +147,19 @@ public double getTractionNoise(String typeVehicle, int runningCondition, String condition = "IdlingSpeed"; break; } - try { - tractionSpectre = getRailWayData().get("Vehicle").get(condition).get(String.valueOf(refId)).get("Values").get(sourceHeightId).get(freqId).doubleValue(); - } catch (NullPointerException ex) { - throw new IllegalArgumentException(String.format(Locale.ROOT, "Could not find traction spectrum for the following parameters " + - "getRailWayData(%d).get(\"Vehicle\").get(%s).get(String.valueOf" + - "(%d)).get(\"Values\").get(%s).get(%d)", fileVersion, condition, refId, sourceHeightId, freqId)); + // Resolve traction node dynamically from JSON data + JsonNode tractionNode = getRailWayData().get("Vehicle").get(condition).get(refId); + if (tractionNode != null) { + try { + tractionSpectrum = tractionNode.get("Values").get(sourceHeightId).get(freqId).doubleValue(); + } catch (NullPointerException ex) { + throw new IllegalArgumentException(String.format(Locale.ROOT, "Could not find traction spectrum for the following parameters " + + "getRailWayData(%s).get(\"Vehicle\").get(%s).get" + + "(%s).get(\"Values\").get(%s).get(%d)", fileVersion, condition, refId, sourceHeightId, freqId)); + } } } - return tractionSpectre; + return tractionSpectrum; } /** @@ -176,8 +172,8 @@ public double getTractionNoise(String typeVehicle, int runningCondition, String * @return */ public double getAerodynamicNoise(String typeVehicle, String sourceHeightId, String fileVersion, int freqId) { // - int refId = getVehicleNode(typeVehicle).get("RefAerodynamic").intValue(); - return getRailWayData().get("Vehicle").get("AerodynamicNoise").get(String.valueOf(refId)).get("Values").get(sourceHeightId).get(freqId).doubleValue(); + String refId = getRefValue(getVehicleNode(typeVehicle), "RefAerodynamic"); + return getRailWayData().get("Vehicle").get("AerodynamicNoise").get(refId).get("Values").get(sourceHeightId).get(freqId).doubleValue(); } /** @@ -187,8 +183,8 @@ public double getAerodynamicNoise(String typeVehicle, String sourceHeightId, Str * @param freqId * @return */ - public Double getBridgeStructural(int bridgeId, int freqId) { - return getRailWayData().get("Track").get("BridgeConstant").get(String.valueOf(bridgeId)).get("Values").get(freqId).doubleValue(); + public Double getBridgeStructural(String bridgeId, int freqId) { + return getRailWayData().get("Track").get("BridgeConstant").get(bridgeId).get("Values").get(freqId).doubleValue(); } @@ -198,8 +194,8 @@ public Double getBridgeStructural(int bridgeId, int freqId) { * @param freqId * @return */ - public Double getTrackTransfer(int trackTransferId, int freqId) { // - return getRailWayData().get("Track").get("TrackTransfer").get(String.valueOf(trackTransferId)).get("Spectre").get(freqId).doubleValue(); + public Double getTrackTransfer(String trackTransferId, int freqId) { // + return getRailWayData().get("Track").get("TrackTransfer").get(trackTransferId).get("Spectre").get(freqId).doubleValue(); } /** @@ -208,8 +204,8 @@ public Double getTrackTransfer(int trackTransferId, int freqId) { // * @param freqId * @return */ - public Double getImpactNoise(int impactNoiseId, int freqId) { // - return getRailWayData().get("Track").get("ImpactNoise").get(String.valueOf(impactNoiseId)).get("Values").get(freqId).doubleValue(); + public Double getImpactNoise(String impactNoiseId, int freqId) { // + return getRailWayData().get("Track").get("ImpactNoise").get(impactNoiseId).get("Values").get(freqId).doubleValue(); } /** @@ -219,8 +215,8 @@ public Double getImpactNoise(int impactNoiseId, int freqId) { // * @return */ public Double getVehTransfer(String typeVehicle, int freqId) { - int RefTransfer = getVehicleNode(typeVehicle).get("RefTransfer").intValue(); - return getRailWayData().get("Vehicle").get("Transfer").get(String.valueOf(RefTransfer)).get("Spectre").get(freqId).doubleValue(); + String refTransfer = getRefValue(getVehicleNode(typeVehicle), "RefTransfer"); + return getRailWayData().get("Vehicle").get("Transfer").get(refTransfer).get("Spectre").get(freqId).doubleValue(); } @@ -234,7 +230,7 @@ public Double getVehTransfer(String typeVehicle, int freqId) { * @param idLambda * @return */ - public Double getLRoughness(String typeVehicle, int trackRoughnessId, String vehicleFileVersion, int idLambda) { // + public Double getLRoughness(String typeVehicle, String trackRoughnessId, String vehicleFileVersion, int idLambda) { // double wheelRoughness = getWheelRoughness(typeVehicle, vehicleFileVersion, idLambda); double trackRoughness = getTrackRoughness(trackRoughnessId, idLambda); return 10 * Math.log10(Math.pow(10, wheelRoughness / 10) + Math.pow(10, trackRoughness / 10)); @@ -280,10 +276,10 @@ public RailWayCnossosParameters evaluate(RailwayVehicleCnossosParameters vehicle double speedTrack = trackParameters.getSpeedTrack(); double speedCommercial = trackParameters.getSpeedCommercial(); - int trackRoughnessId = trackParameters.getRailRoughness(); - int trackTransferId = trackParameters.getTrackTransfer(); - int impactId = trackParameters.getImpactNoise(); - int bridgeId = trackParameters.getBridgeTransfert(); + String trackRoughnessId = trackParameters.getRailRoughness(); + String trackTransferId = trackParameters.getTrackTransfer(); + String impactId = trackParameters.getImpactNoise(); + String bridgeId = trackParameters.getBridgeTransfert(); int curvature = trackParameters.getCurvature(); // get speed of the vehicle @@ -341,16 +337,26 @@ private double[] getLWTraction(String typeVehicle, int runningCondition, String private double[] getLWAero(String typeVehicle, double speed, String height, String fileVersion) { double[] lWSpectre = new double[24]; - for (int idFreq = 0; idFreq < 24; idFreq++) { + String refId = getRefValue(getVehicleNode(typeVehicle), "RefAerodynamic"); - int refId = getVehicleNode(typeVehicle).get("RefAerodynamic").intValue(); - if (speed < 200 || refId == 0) { - lWSpectre[idFreq] = -99; - } else { - lWSpectre[idFreq] = getAerodynamicNoise(typeVehicle, height, fileVersion, idFreq); - double v0Aero = Double.parseDouble(getRailWayData().get("Vehicle").get("AerodynamicNoise").get(String.valueOf(refId)).get("V0").asText()); - double alphaAero = Double.parseDouble(getRailWayData().get("Vehicle").get("AerodynamicNoise").get(String.valueOf(refId)).get("Alpha").asText()); - lWSpectre[idFreq] = lWSpectre[idFreq] + alphaAero * Math.log10(speed / v0Aero); + // Resolve the aerodynamic noise node from JSON data + JsonNode aeroNode = (refId != null && !refId.isEmpty()) ? + getRailWayData().get("Vehicle").get("AerodynamicNoise").get(refId) : null; + + // Check V0 value from JSON - if 0 or node not found, no aerodynamic noise + double v0Aero = 0; + double alphaAero = 0; + if (aeroNode != null) { + v0Aero = Double.parseDouble(aeroNode.get("V0").asText()); + alphaAero = Double.parseDouble(aeroNode.get("Alpha").asText()); + } + + if (speed < 200 || aeroNode == null || v0Aero == 0) { + Arrays.fill(lWSpectre, -99); + } else { + for (int idFreq = 0; idFreq < 24; idFreq++) { + lWSpectre[idFreq] = getAerodynamicNoise(typeVehicle, height, fileVersion, idFreq) + + alphaAero * Math.log10(speed / v0Aero); } } @@ -376,7 +382,7 @@ private double[] getLWAero(String typeVehicle, double speed, String height, Stri **/ - private double[] getLWRolling(String typeVehicle, int trackRoughnessId, int impactId, int curvature, double speed, int trackTransferId, String trackFileVersion, double axlesPerVeh) { + private double[] getLWRolling(String typeVehicle, String trackRoughnessId, String impactId, int curvature, double speed, String trackTransferId, String trackFileVersion, double axlesPerVeh) { double[] trackTransfer = new double[24]; double[] lWTr = new double[24]; @@ -422,22 +428,39 @@ private double[] getLWRolling(String typeVehicle, int trackRoughnessId, int impa * @param axlesPerVeh * @return */ - private double[] getLWBridge(String typeVehicle, int trackRoughnessId, int impactId, int bridgeId, double speed, String trackFileVersion, double axlesPerVeh) { + private double[] getLWBridge(String typeVehicle, String trackRoughnessId, String impactId, String bridgeId, double speed, String trackFileVersion, double axlesPerVeh) { double[] lW = new double[24]; // roughnessLtot = CNOSSOS p.19 (2.3.7) double[] roughnessLtot = checkNanValue(getLWRoughness(typeVehicle, trackRoughnessId, impactId, speed, trackFileVersion)); - double[] lWBridge = new double[24]; for (int idFreq = 0; idFreq < 24; idFreq++) { lW[idFreq] = -99; } - if (trackFileVersion == "EU") { - if (bridgeId == 3 || bridgeId == 4) { - for (int idFreq = 0; idFreq < 24; idFreq++) { - lWBridge[idFreq] = getBridgeStructural(bridgeId, idFreq); - lW[idFreq] = roughnessLtot[idFreq] + lWBridge[idFreq] + 10 * Math.log10(axlesPerVeh); + + // Resolve bridge node dynamically from JSON data + JsonNode bridgeNode = (bridgeId != null && !bridgeId.isEmpty()) ? + getRailWayData().get("Track").get("BridgeConstant").get(bridgeId) : null; + + if (bridgeNode != null) { + // Check "Values" first, then "Value" (singular) + JsonNode valuesNode = bridgeNode.get("Values"); + if (valuesNode == null) { + valuesNode = bridgeNode.get("Value"); + } + if (valuesNode != null) { + if (valuesNode.isArray() && valuesNode.size() >= 24) { + // Frequency-dependent bridge structural spectrum (e.g. EU3, EU4) + for (int idFreq = 0; idFreq < 24; idFreq++) { + lW[idFreq] = roughnessLtot[idFreq] + valuesNode.get(idFreq).doubleValue() + 10 * Math.log10(axlesPerVeh); + } + } else if (valuesNode.isNumber() && valuesNode.doubleValue() != 0) { + // Uniform bridge constant (e.g. EU2, SNCF2) + double bridgeConstant = valuesNode.doubleValue(); + for (int idFreq = 0; idFreq < 24; idFreq++) { + lW[idFreq] = roughnessLtot[idFreq] + bridgeConstant + 10 * Math.log10(axlesPerVeh); + } } } } @@ -456,7 +479,7 @@ private double[] getLWBridge(String typeVehicle, int trackRoughnessId, int impac * @param speed impact reference * @return Lroughness(freq) **/ - private double[] getLWRoughness(String typeVehicle, int trackRoughnessId, int impactId, double speed, String trackFileVersion) { + private double[] getLWRoughness(String typeVehicle, String trackRoughnessId, String impactId, double speed, String trackFileVersion) { double[] roughnessTotLambda = new double[35]; double[] roughnessLtot = new double[35]; @@ -465,6 +488,17 @@ private double[] getLWRoughness(String typeVehicle, int trackRoughnessId, int im double[] freqMedLog = new double[24]; double[] Lambda = new double[35]; + // Resolve impact noise node once before the loop + boolean hasImpactNoise = false; + if (impactId != null && !impactId.isEmpty()) { + JsonNode impactNode = getRailWayData().get("Track").get("ImpactNoise").get(impactId); + if (impactNode != null) { + // Check JoinDensity: if present and null, this is an empty sentinel entry + JsonNode joinDensity = impactNode.get("JoinDensity"); + hasImpactNoise = joinDensity == null || !joinDensity.isNull(); + } + } + double m = 33; for (int idLambda = 0; idLambda < 35; idLambda++) { Lambda[idLambda] = Math.pow(10, m / 10); @@ -473,9 +507,10 @@ private double[] getLWRoughness(String typeVehicle, int trackRoughnessId, int im roughnessTotLambda[idLambda] = Math.pow(10, getLRoughness(typeVehicle, trackRoughnessId, trackFileVersion, idLambda) / 10); contactFilter[idLambda] = getContactFilter(typeVehicle, idLambda); - roughnessLtot[idLambda] = 10 * Math.log10(roughnessTotLambda[idLambda]) + contactFilter[idLambda]; - if (impactId != 0) { - roughnessLtot[idLambda] = 10 * Math.log10(Math.pow(10,roughnessLtot[idLambda]/ 10) + Math.pow(10, getImpactNoise(impactId, idLambda) / 10)); + if (hasImpactNoise) { + roughnessLtot[idLambda] = 10 * Math.log10(roughnessTotLambda[idLambda]+ Math.pow(10, getImpactNoise(impactId, idLambda) / 10))+ contactFilter[idLambda]; + } else { + roughnessLtot[idLambda] = 10 * Math.log10(roughnessTotLambda[idLambda]) + contactFilter[idLambda]; } roughnessLtot[idLambda] = Math.pow(10, roughnessLtot[idLambda] / 10); m--; diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailwayTrackCnossosParameters.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailwayTrackCnossosParameters.java index 647da6e4f..b4b50a468 100644 --- a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailwayTrackCnossosParameters.java +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossos/RailwayTrackCnossosParameters.java @@ -32,15 +32,15 @@ public class RailwayTrackCnossosParameters extends RailwayTrackParameters { //set default value - private int trackTransfer; - private int railRoughness; + private String trackTransfer; + private String railRoughness; private int curvature; - private int impactNoise; - private int bridgeTransfert; + private String impactNoise; + private String bridgeTransfert; private String fileVersion = "FR"; // version of cnossos coefficient, if 2 == amendments 2019 - public RailwayTrackCnossosParameters(double speedTrack, int trackTransfer, int railRoughness, int impactNoise, - int bridgeTransfert, int curvature, double speedCommercial, boolean isTunnel, int nTrack) { + public RailwayTrackCnossosParameters(double speedTrack, String trackTransfer, String railRoughness, String impactNoise, + String bridgeTransfert, int curvature, double speedCommercial, boolean isTunnel, int nTrack) { setSpeedTrack(speedTrack); setSpeedCommercial(speedCommercial); @@ -64,35 +64,35 @@ public void setFileVersion(String fileVersion) { } - public int getTrackTransfer() { + public String getTrackTransfer() { return trackTransfer; } - public void setTrackTransfer(int trackTransfer) { + public void setTrackTransfer(String trackTransfer) { this.trackTransfer = trackTransfer; } - public int getRailRoughness() { + public String getRailRoughness() { return railRoughness; } - public void setRailRoughness(int railRoughness) { + public void setRailRoughness(String railRoughness) { this.railRoughness = railRoughness; } - public int getImpactNoise() { + public String getImpactNoise() { return impactNoise; } - public void setImpactNoise(int impactNoise) { + public void setImpactNoise(String impactNoise) { this.impactNoise = impactNoise; } - public int getBridgeTransfert() { + public String getBridgeTransfert() { return bridgeTransfert; } - public void setBridgeTransfert(int bridgeTransfert) { + public void setBridgeTransfert(String bridgeTransfert) { this.bridgeTransfert = bridgeTransfert; } diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossosvar/RailwayCnossosvar.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossosvar/RailwayCnossosvar.java new file mode 100644 index 000000000..4b610aa59 --- /dev/null +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossosvar/RailwayCnossosvar.java @@ -0,0 +1,555 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

+ * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

+ * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + +package org.noise_planet.noisemodelling.emission.railway.cnossosvar; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.NullNode; +import org.noise_planet.noisemodelling.emission.LineSource; +import org.noise_planet.noisemodelling.emission.railway.cnossos.RailWayCnossosParameters; +import org.noise_planet.noisemodelling.emission.railway.cnossos.RailwayTrackCnossosParameters; +import org.noise_planet.noisemodelling.emission.railway.cnossosvar.RailwayVehicleCnossosParametersvar; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Locale; + +import static java.lang.Math.min; +import static org.noise_planet.noisemodelling.emission.utils.interpLinear.interpLinear; + +/** + * Railway noise evaluation from Cnossos reference : COMMISSION DIRECTIVE (EU) 2015/996 + * of 19 May 2015 establishing common noise assessment methods according to Directive 2002/49/EC + * of the European Parliament and of the Council + * + * amending, for the purposes of adapting to scientific and technical progress, Annex II to + * Directive 2002/49/EC of the European Parliament and of the Council as regards + * common noise assessment methods + * + * part 2.3. Railway noise + * + * Return the dB value corresponding to the parameters + * @author Adrien Le Bellec, Université Gustave Eiffel + * @author Olivier Chiello, Université Gustave Eiffel + */ + +public class RailwayCnossosvar extends org.noise_planet.noisemodelling.emission.railway.Railway { + + public RailwayCnossosvar() { + } + + + /** + * + * @param inputStream + * @return + */ + private static JsonNode parse(InputStream inputStream) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readTree(inputStream); + } catch (IOException ex) { + return NullNode.getInstance(); + } + } + + /** + * + * @param iterator + * @return an iterator + * @param + */ + public static Iterable iteratorToIterable(Iterator iterator) { + return () -> iterator; + } + + /** + * Helper to read a Ref field from a vehicle JSON node. + * Supports both string (new merged file) and integer (legacy files) JSON values. + * @param vehicleNode the JSON node of the vehicle + * @param fieldName the Ref field name (e.g. "RefRoughness") + * @return the string value of the reference + */ + private static String getRefValue(JsonNode vehicleNode, String fieldName) { + JsonNode value = vehicleNode.get(fieldName); + if (value.isTextual()) { + return value.textValue(); + } + return String.valueOf(value.intValue()); + } + + /** + * get Wheel Roughness by wavenumber - Only CNOSSOS + * @param typeVehicle + * @param fileVersion + * @param lambdaId + * @return + */ + public Double getWheelRoughness(String typeVehicle, String fileVersion, int lambdaId) { // + String refId = getRefValue(getVehicleNode(typeVehicle), "RefRoughness"); + return getRailWayData().get("Vehicle").get("WheelRoughness").get(refId).get("Values").get(lambdaId).doubleValue(); + } + + /** + * get Contact Filter by wavenumber - Only CNOSSOS + * @param typeVehicle type of a vehicle, for example : SNCF2 + * @param lambdaId wavenumber (between 1 and 34 corresponding the normalised third octave bands from 2000mm to 0.8mm). + * @return contact filter + */ + public Double getContactFilter(String typeVehicle, int lambdaId) { // + String refId = getRefValue(getVehicleNode(typeVehicle), "RefContact"); + return getRailWayData().get("Vehicle").get("ContactFilter").get(refId).get("Values").get(lambdaId).doubleValue(); + } + + /** + * get Track Roughness Filter by wavenumber - Only CNOSSOS + * @param trackRoughnessId + * @param lambdaId + * @return + */ + public Double getTrackRoughness(String trackRoughnessId, int lambdaId) { // + return getRailWayData().get("Track").get("RailRoughness").get(trackRoughnessId).get("Values").get(lambdaId).doubleValue(); + } + + /** + * Axles number by vehicles + * @param typeVehicle + * @return + */ + public double getAxlesPerVeh(String typeVehicle) { // + return getVehicleNode(typeVehicle).get("NbAxlePerVeh").doubleValue(); + } + + /** + * get Nb of coach by vehicle + * @param typeVehicle + * @return + */ + public int getNbCoach(String typeVehicle) { // + int nbCoach; + try { + nbCoach = getVehicleData().get(typeVehicle).get("NbCoach").intValue(); + } catch (Exception e) { + nbCoach = 1; + } + + return nbCoach; + } + + /** + * + * @param typeVehicle + * @param runningCondition + * @param sourceHeightId + * @param fileVersion + * @param freqId + * @return + */ + public double getTractionNoise(String typeVehicle, int runningCondition, String sourceHeightId, String fileVersion, int freqId) { // + String refId = getRefValue(getVehicleNode(typeVehicle), "RefTraction"); + double tractionSpectrum = 0; + + if (refId != null && !refId.isEmpty()) { + String condition = "ConstantSpeed"; + switch (runningCondition) { + case 0: + condition = "ConstantSpeed"; + break; + case 1: + condition = "AccelerationSpeed"; + break; + case 3: + condition = "DecelerationSpeed"; + break; + case 4: + condition = "IdlingSpeed"; + break; + } + // Resolve traction node dynamically from JSON data + JsonNode tractionNode = getRailWayData().get("Vehicle").get(condition).get(refId); + if (tractionNode != null) { + try { + tractionSpectrum = tractionNode.get("Values").get(sourceHeightId).get(freqId).doubleValue(); + } catch (NullPointerException ex) { + throw new IllegalArgumentException(String.format(Locale.ROOT, "Could not find traction spectrum for the following parameters " + + "getRailWayData(%s).get(\"Vehicle\").get(%s).get" + + "(%s).get(\"Values\").get(%s).get(%d)", fileVersion, condition, refId, sourceHeightId, freqId)); + } + } + } + return tractionSpectrum; + } + + /** + * retrieve the aerodynamic noise value for a specific type of vehicle, source height, file version, and frequency ID + * by accessing the corresponding data from the vehicle node, railway data, and noise values. + * @param typeVehicle + * @param sourceHeightId + * @param fileVersion + * @param freqId + * @return + */ + public double getAerodynamicNoise(String typeVehicle, String sourceHeightId, String fileVersion, int freqId) { // + String refId = getRefValue(getVehicleNode(typeVehicle), "RefAerodynamic"); + return getRailWayData().get("Vehicle").get("AerodynamicNoise").get(refId).get("Values").get(sourceHeightId).get(freqId).doubleValue(); + } + + /** + * retrieves the structural constant for a specific bridge and frequency ID + * by accessing the corresponding data from the railway track's bridge constants. + * @param bridgeId + * @param freqId + * @return + */ + public Double getBridgeStructural(String bridgeId, int freqId) { + return getRailWayData().get("Track").get("BridgeConstant").get(bridgeId).get("Values").get(freqId).doubleValue(); + } + + + /** + * fetches and returns the transfer value from the railway data for a specific track transfer ID and frequency ID. + * @param trackTransferId + * @param freqId + * @return + */ + public Double getTrackTransfer(String trackTransferId, int freqId) { // + return getRailWayData().get("Track").get("TrackTransfer").get(trackTransferId).get("Spectre").get(freqId).doubleValue(); + } + + /** + * fetches and returns the impact noise value from the railway data for a specific impact noise ID and frequency ID. + * @param impactNoiseId + * @param freqId + * @return + */ + public Double getImpactNoise(String impactNoiseId, int freqId) { // + return getRailWayData().get("Track").get("ImpactNoise").get(impactNoiseId).get("Values").get(freqId).doubleValue(); + } + + /** + * retrieve and return the transfer value associated with a given vehicle type and a specific frequency ID. + * @param typeVehicle + * @param freqId + * @return + */ + public Double getVehTransfer(String typeVehicle, int freqId) { + String refTransfer = getRefValue(getVehicleNode(typeVehicle), "RefTransfer"); + return getRailWayData().get("Vehicle").get("Transfer").get(refTransfer).get("Spectre").get(freqId).doubleValue(); + + } + + + /** + * calculates the total roughness level for a specific type of vehicle, + * track roughness, vehicle file version, and lambda ID by retrieving the wheel roughness and track roughness + * @param typeVehicle + * @param trackRoughnessId + * @param vehicleFileVersion + * @param idLambda + * @return + */ + public Double getLRoughness(String typeVehicle, String trackRoughnessId, String vehicleFileVersion, int idLambda) { // + double wheelRoughness = getWheelRoughness(typeVehicle, vehicleFileVersion, idLambda); + double trackRoughness = getTrackRoughness(trackRoughnessId, idLambda); + return 10 * Math.log10(Math.pow(10, wheelRoughness / 10) + Math.pow(10, trackRoughness / 10)); + } + + /** + * Check if it exists some NaN values in the Roughness sound level. + * They appear when calculating the roughness in the frequency domain by interpolating the roughness in the wavelength domain + * @param roughnessLtot + * @return + */ + private double[] checkNanValue(double[] roughnessLtot) { + int indice_NaN = 0; + for (int i = 0; i < roughnessLtot.length-2; i++) { + if (Double.isNaN(roughnessLtot[i])) { + indice_NaN++; + } + } + for (int i = 0; i < indice_NaN; i++) { + roughnessLtot[i] = roughnessLtot[indice_NaN + 1]; + } + return roughnessLtot; + } + + /** + * Evaluate the sound level for one Vehicle + * @param vehicleParameters Vehicle Noise emission parameters + * @param trackParameters Track Noise emission parameters + * constant speed + * + * @return LWRoll / LWTraction A and B / LWAerodynamic A and B / LWBridge level in dB + **/ + public RailWayCnossosParameters evaluate(RailwayVehicleCnossosParametersvar vehicleParameters, RailwayTrackCnossosParameters trackParameters) throws IOException { + + String vehicleFileVersion = vehicleParameters.getFileVersion(); + String trackFileVersion = trackParameters.getFileVersion(); + String typeVehicle = vehicleParameters.getTypeVehicle(); + + double speedVehicle = vehicleParameters.getSpeedVehicle(); + double axlesPerVeh = getAxlesPerVeh(typeVehicle); + int runningCondition = vehicleParameters.getRunningCondition(); + + double speedTrack = trackParameters.getSpeedTrack(); + double speedCommercial = trackParameters.getSpeedCommercial(); + String trackRoughnessId = trackParameters.getRailRoughness(); + String trackTransferId = trackParameters.getTrackTransfer(); + String impactId = trackParameters.getImpactNoise(); + String bridgeId = trackParameters.getBridgeTransfert(); + int curvature = trackParameters.getCurvature(); + + // get speed of the vehicle + double speed = min(speedVehicle, min(speedTrack, speedCommercial)); + + boolean isTunnel = trackParameters.getIsTunnel(); + // %% Take into account the number of coach and the number of units + // 10*log10(NbUnit*NbCoach); + + RailWayCnossosParameters railWayParameters = new RailWayCnossosParameters(); + + if (isTunnel) { + return railWayParameters; + } else { + // Rolling noise calcul + double[] lW = getLWRolling(typeVehicle, trackRoughnessId, impactId, curvature, speed, trackTransferId, trackFileVersion, axlesPerVeh); + railWayParameters.addRailwaySource("ROLLING", new LineSource(lW,0.5, "ROLLING")); + lW = getLWTraction(typeVehicle, runningCondition, "A", vehicleFileVersion); + railWayParameters.addRailwaySource("TRACTIONA", new LineSource(lW,0.05, "TRACTIONA")); + lW = getLWTraction(typeVehicle, runningCondition, "B", vehicleFileVersion); + railWayParameters.addRailwaySource("TRACTIONB", new LineSource(lW,4, "TRACTIONB")); + lW = getLWAero(typeVehicle, speed, "A", vehicleFileVersion); + railWayParameters.addRailwaySource("AERODYNAMICA", new LineSource(lW,0.05, "AERODYNAMICA")); + lW = getLWAero(typeVehicle, speed, "B", vehicleFileVersion); + railWayParameters.addRailwaySource("AERODYNAMICB", new LineSource(lW,4, "AERODYNAMICB")); + lW = getLWBridge(typeVehicle, trackRoughnessId, impactId, bridgeId, speed, trackFileVersion,axlesPerVeh); + railWayParameters.addRailwaySource("BRIDGE", new LineSource(lW,0.5, "BRIDGE")); + + return railWayParameters; + } + } + + /** + * traction or Aerodynamic Level. + * @param typeVehicle vehicle data base + * @param height height source + * @return lWSpectre(freq) (Traction or Aerodynamic) + **/ + private double[] getLWTraction(String typeVehicle, int runningCondition, String height, String fileVersion) { + double[] lWSpectre = new double[24]; + for (int idFreq = 0; idFreq < 24; idFreq++) { + lWSpectre[idFreq] = getTractionNoise(typeVehicle, runningCondition, height, fileVersion, idFreq); + } + return lWSpectre; + } + + /** + * traction or Aerodynamic Level. + * @param typeVehicle vehicle data base + * @param speed min speed between vehicle and track + * @param height height source + * @return lWSpectre(freq) (Traction or Aerodynamic) + **/ + private double[] getLWAero(String typeVehicle, double speed, String height, String fileVersion) { + double[] lWSpectre = new double[24]; + + String refId = getRefValue(getVehicleNode(typeVehicle), "RefAerodynamic"); + + // Resolve the aerodynamic noise node from JSON data + JsonNode aeroNode = (refId != null && !refId.isEmpty()) ? + getRailWayData().get("Vehicle").get("AerodynamicNoise").get(refId) : null; + + // Check V0 value from JSON - if 0 or node not found, no aerodynamic noise + double v0Aero = 0; + double alphaAero = 0; + if (aeroNode != null) { + v0Aero = Double.parseDouble(aeroNode.get("V0").asText()); + alphaAero = Double.parseDouble(aeroNode.get("Alpha").asText()); + } + + if (speed < 200 || aeroNode == null || v0Aero == 0) { + Arrays.fill(lWSpectre, -99); + } else { + for (int idFreq = 0; idFreq < 24; idFreq++) { + lWSpectre[idFreq] = getAerodynamicNoise(typeVehicle, height, fileVersion, idFreq) + + alphaAero * Math.log10(speed / v0Aero); + } + } + + return lWSpectre; + } + + + /** + * Rolling Level. + * @param typeVehicle vehicle data base + * @param trackRoughnessId track Roughness reference + * @param impactId impact reference + * @param speed min speed between vehicle and track + * + * Step 1 + * wavelength to frequecy (evaluateRoughnessLtotFreq) + * Step 2 + * calcul sound power of wheel and bogie emission + * calcul sound power of rail sleeper and ballast/slab emission + * todo add sound power of superstructure emission ? + * + * @return lWRoll(freq) + **/ + + + private double[] getLWRolling(String typeVehicle, String trackRoughnessId, String impactId, int curvature, double speed, String trackTransferId, String trackFileVersion, double axlesPerVeh) { + + double[] trackTransfer = new double[24]; + double[] lWTr = new double[24]; + double[] vehTransfer = new double[24]; + double[] lWVeh = new double[24]; + double[] lW = new double[24]; + + // roughnessLtot = CNOSSOS p.19 (2.3.7) + double[] roughnessLtot = checkNanValue(getLWRoughness(typeVehicle, trackRoughnessId, impactId, speed, trackFileVersion)); + + for (int idFreq = 0; idFreq < 24; idFreq++) { + // lWTr = CNOSSOS p.20 (2.3.8) + trackTransfer[idFreq] = getTrackTransfer(trackTransferId, idFreq); + lWTr[idFreq] = roughnessLtot[idFreq] + trackTransfer[idFreq] + 10 * Math.log10(axlesPerVeh); + + // lWVeh = CNOSSOS p.20 (2.3.9) + vehTransfer[idFreq] = getVehTransfer(typeVehicle, idFreq); + lWVeh[idFreq] = roughnessLtot[idFreq] + vehTransfer[idFreq] + 10 * Math.log10(axlesPerVeh); + // lWRoll = CNOSSOS p.19 (2.3.7) + lW[idFreq] = 10 * Math.log10(Math.pow(10, lWTr[idFreq] / 10) + Math.pow(10, lWVeh[idFreq] / 10)); + if (curvature == 1) { + lW[idFreq] = lW[idFreq] + 5; + } else if (curvature == 2) { + lW[idFreq] = lW[idFreq] + 8; + } else if (curvature == 3) { + lW[idFreq] = lW[idFreq] + 8; + } + } + + return lW; + } + + + /** + * method calculates the overall sound power level for a specific type of vehicle, track roughness, + * impact ID, bridge ID, speed, track file version, and number of axles per vehicle + * @param typeVehicle + * @param trackRoughnessId + * @param impactId + * @param bridgeId + * @param speed + * @param trackFileVersion + * @param axlesPerVeh + * @return + */ + private double[] getLWBridge(String typeVehicle, String trackRoughnessId, String impactId, String bridgeId, double speed, String trackFileVersion, double axlesPerVeh) { + + double[] lW = new double[24]; + + // roughnessLtot = CNOSSOS p.19 (2.3.7) + double[] roughnessLtot = checkNanValue(getLWRoughness(typeVehicle, trackRoughnessId, impactId, speed, trackFileVersion)); + + for (int idFreq = 0; idFreq < 24; idFreq++) { + lW[idFreq] = -99; + } + + // Resolve bridge node dynamically from JSON data + JsonNode bridgeNode = (bridgeId != null && !bridgeId.isEmpty()) ? + getRailWayData().get("Track").get("BridgeConstant").get(bridgeId) : null; + + if (bridgeNode != null) { + // Check "Values" first, then "Value" (singular) + JsonNode valuesNode = bridgeNode.get("Values"); + if (valuesNode == null) { + valuesNode = bridgeNode.get("Value"); + } + if (valuesNode != null) { + if (valuesNode.isArray() && valuesNode.size() >= 24) { + // Frequency-dependent bridge structural spectrum (e.g. EU3, EU4) + for (int idFreq = 0; idFreq < 24; idFreq++) { + lW[idFreq] = roughnessLtot[idFreq] + valuesNode.get(idFreq).doubleValue() + 10 * Math.log10(axlesPerVeh); + } + } else if (valuesNode.isNumber() && valuesNode.doubleValue() != 0) { + // Uniform bridge constant (e.g. EU2, SNCF2) + double bridgeConstant = valuesNode.doubleValue(); + for (int idFreq = 0; idFreq < 24; idFreq++) { + lW[idFreq] = roughnessLtot[idFreq] + bridgeConstant + 10 * Math.log10(axlesPerVeh); + } + } + } + } + + return lW; + } + + + + /** + * Roughness Level. + * linear interpolation wavelength to frequency + * @param typeVehicle vehicle data base + * @param trackRoughnessId track Roughness reference + * @param impactId impact reference + * @param speed impact reference + * @return Lroughness(freq) + **/ + private double[] getLWRoughness(String typeVehicle, String trackRoughnessId, String impactId, double speed, String trackFileVersion) { + + double[] roughnessTotLambda = new double[35]; + double[] roughnessLtot = new double[35]; + double[] contactFilter = new double[35]; + double[] lambdaToFreqLog = new double[35]; + double[] freqMedLog = new double[24]; + double[] Lambda = new double[35]; + + // Resolve impact noise node once before the loop + boolean hasImpactNoise = false; + if (impactId != null && !impactId.isEmpty()) { + JsonNode impactNode = getRailWayData().get("Track").get("ImpactNoise").get(impactId); + if (impactNode != null) { + // Check JoinDensity: if present and null, this is an empty sentinel entry + JsonNode joinDensity = impactNode.get("JoinDensity"); + hasImpactNoise = joinDensity == null || !joinDensity.isNull(); + } + } + + double m = 33; + for (int idLambda = 0; idLambda < 35; idLambda++) { + Lambda[idLambda] = Math.pow(10, m / 10); + lambdaToFreqLog[idLambda] = Math.log10(speed / Lambda[idLambda] * 1000 / 3.6); + + roughnessTotLambda[idLambda] = Math.pow(10, getLRoughness(typeVehicle, trackRoughnessId, trackFileVersion, idLambda) / 10); + + contactFilter[idLambda] = getContactFilter(typeVehicle, idLambda); + roughnessLtot[idLambda] = 10 * Math.log10(roughnessTotLambda[idLambda]) + contactFilter[idLambda]; + if (hasImpactNoise) { + roughnessLtot[idLambda] = 10 * Math.log10(Math.pow(10,roughnessLtot[idLambda]/ 10) + Math.pow(10, getImpactNoise(impactId, idLambda) / 10)); + } + roughnessLtot[idLambda] = Math.pow(10, roughnessLtot[idLambda] / 10); + m--; + } + for (int idFreqMed = 0; idFreqMed < 24; idFreqMed++) { + freqMedLog[idFreqMed] = Math.log10(Math.pow(10, (17 + Double.valueOf(idFreqMed)) / 10)); + } + + double[] roughnessLtotFreq = interpLinear(lambdaToFreqLog, roughnessLtot, freqMedLog); + + for (int idRoughnessLtotFreq = 0; idRoughnessLtotFreq < 24; idRoughnessLtotFreq++) { + roughnessLtotFreq[idRoughnessLtotFreq] = 10 * Math.log10(roughnessLtotFreq[idRoughnessLtotFreq]); + } + return roughnessLtotFreq; + } + +} + diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossosvar/RailwayVehicleCnossosParametersvar.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossosvar/RailwayVehicleCnossosParametersvar.java new file mode 100644 index 000000000..8b86a000f --- /dev/null +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/cnossosvar/RailwayVehicleCnossosParametersvar.java @@ -0,0 +1,71 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

+ * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

+ * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + +package org.noise_planet.noisemodelling.emission.railway.cnossosvar; + +/** + * Railway noise evaluation from Cnossos reference : COMMISSION DIRECTIVE (EU) 2015/996 + * of 19 May 2015 establishing common noise assessment methods according to Directive 2002/49/EC + * of the European Parliament and of the Council + * + * amending, for the purposes of adapting to scientific and technical progress, Annex II to + * Directive 2002/49/EC of the European Parliament and of the Council as regards + * common noise assessment methods + * + * part 2.3. Railway noise + * + * @author Adrien Le Bellec, Université Gustave Eiffel + * @author Olivier Chiello, Université Gustave Eiffel + */ + +import org.noise_planet.noisemodelling.emission.railway.RailwayVehicleParametersvar; + +/** + * Parameters Vehicule + */ + +public class RailwayVehicleCnossosParametersvar extends RailwayVehicleParametersvar { + + // set default value + private int runningCondition = 0; // 0 = constand speed, 1 = acceleration , 2 =decceleration, 3 = idling + private double idlingTime = 0; // if idling, idling time (seconds) + private String fileVersion = "FR"; // version of cnossos coefficient, if 2 == amendments 2019 + + public RailwayVehicleCnossosParametersvar(String typeVehicle, double speedVehicle, int runningCondition, double idlingTime) { + setTypeVehicle(typeVehicle); + setSpeedVehicle(speedVehicle); + + setRunningCondition(runningCondition); + setIdlingTime(idlingTime); + } + + public String getFileVersion() { + return this.fileVersion; + } + + public void setFileVersion(String fileVersion) { + this.fileVersion = fileVersion; + } + + public int getRunningCondition() { + return runningCondition; + } + + public void setRunningCondition(int runningCondition) { + this.runningCondition = runningCondition; + } + + public double getIdlingTime() { + return idlingTime; + } + + public void setIdlingTime(double idlingTime) { + this.idlingTime = idlingTime; + } +} diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/nmpb/RailwayNMPB.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/nmpb/RailwayNMPB.java index e0b87aab7..10137c2e0 100644 --- a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/nmpb/RailwayNMPB.java +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/railway/nmpb/RailwayNMPB.java @@ -238,7 +238,7 @@ public int getNbCoach(String typeVehicle) { // public double getSpectre(String typeVehicle, String ref, int runningCondition, String sourceHeight, int spectreVer, int freqId) { // int refId = getNMPBVehicleNode(typeVehicle).get(ref).intValue(); if (ref.equals("RefTraction")) { - double tractionSpectre = 0; + double tractionSpectrum = 0; String condition = "ConstantSpeed"; if (refId != 0) { switch (runningCondition) { @@ -256,14 +256,14 @@ public double getSpectre(String typeVehicle, String ref, int runningCondition, S break; } try { - tractionSpectre = getNMPBRailWayData(spectreVer).get("Vehicle").get(condition).get(String.valueOf(refId)).get("Values").get(sourceHeight).get(freqId).doubleValue(); + tractionSpectrum = getNMPBRailWayData(spectreVer).get("Vehicle").get(condition).get(String.valueOf(refId)).get("Values").get(sourceHeight).get(freqId).doubleValue(); } catch (NullPointerException ex) { throw new IllegalArgumentException(String.format(Locale.ROOT, "Could not find traction spectrum for the following parameters " + "getNMPBRailWayData(%d).get(\"Vehicle\").get(%s).get(String.valueOf" + "(%d)).get(\"Values\").get(%s).get(%d)", spectreVer, condition, refId, sourceHeight, freqId)); } } - return tractionSpectre; + return tractionSpectrum; } else if (ref.equals("RefAerodynamic")) { double aerodynamicNoise; aerodynamicNoise = getNMPBRailWayData(spectreVer).get("Vehicle").get("AerodynamicNoise").get(String.valueOf(refId)).get("Values").get(sourceHeight).get(freqId).doubleValue(); diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/road/cnossos/RoadCnossos.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/road/cnossos/RoadCnossos.java index ba491a599..5ade32f6b 100644 --- a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/road/cnossos/RoadCnossos.java +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/road/cnossos/RoadCnossos.java @@ -350,17 +350,19 @@ public static double evaluate(RoadCnossosParameters roadCnossosParameters) throw */ // Effect of the acceleration and deceleration of vehicles // Todo Here, we should get the Junc_dist by another way that we are doing now to be more precise issue #524 - double coefficientJunctionDistance = Math.max(1 - Math.abs(Junc_dist) / 100, 0); - // Effect of the acceleration and deceleration of vehicles - Rolling Noise Eq 2.2.17 - lvRoadLvl = lvRoadLvl + getCr("1", Junc_type, coeffVer) * coefficientJunctionDistance; - medRoadLvl = medRoadLvl + getCr("2", Junc_type, coeffVer) * coefficientJunctionDistance; - hgvRoadLvl = hgvRoadLvl + getCr("3", Junc_type, coeffVer) * coefficientJunctionDistance; - // Effect of the acceleration and deceleration of vehicles - Propulsion Noise Eq 2.2.18 - lvMotorLvl = lvMotorLvl + getCp("1", Junc_type, coeffVer) * coefficientJunctionDistance; - medMotorLvl = medMotorLvl + getCp("2", Junc_type, coeffVer) * coefficientJunctionDistance; - hgvMotorLvl = hgvMotorLvl + getCp("3", Junc_type, coeffVer) * coefficientJunctionDistance; - wheelaMotorLvl = wheelaMotorLvl + getCp("4a", Junc_type, coeffVer) * coefficientJunctionDistance; - wheelbMotorLvl = wheelbMotorLvl + getCp("4b", Junc_type, coeffVer) * coefficientJunctionDistance; + if(Junc_type > 0) { // Junc_type = 0, no junction + double coefficientJunctionDistance = Math.max(1 - Math.abs(Junc_dist) / 100, 0); + // Effect of the acceleration and deceleration of vehicles - Rolling Noise Eq 2.2.17 + lvRoadLvl = lvRoadLvl + getCr("1", Junc_type, coeffVer) * coefficientJunctionDistance; + medRoadLvl = medRoadLvl + getCr("2", Junc_type, coeffVer) * coefficientJunctionDistance; + hgvRoadLvl = hgvRoadLvl + getCr("3", Junc_type, coeffVer) * coefficientJunctionDistance; + // Effect of the acceleration and deceleration of vehicles - Propulsion Noise Eq 2.2.18 + lvMotorLvl = lvMotorLvl + getCp("1", Junc_type, coeffVer) * coefficientJunctionDistance; + medMotorLvl = medMotorLvl + getCp("2", Junc_type, coeffVer) * coefficientJunctionDistance; + hgvMotorLvl = hgvMotorLvl + getCp("3", Junc_type, coeffVer) * coefficientJunctionDistance; + wheelaMotorLvl = wheelaMotorLvl + getCp("4a", Junc_type, coeffVer) * coefficientJunctionDistance; + wheelbMotorLvl = wheelbMotorLvl + getCp("4b", Junc_type, coeffVer) * coefficientJunctionDistance; + } // Effect of the type of road surface - Eq. 2.2.19 lvRoadLvl = lvRoadLvl + getNoiseLvl(getA_RoadSurfaceCoeff(freqParam, "1", roadCnossosParameters.getRoadSurface(), coeffVer), getB_RoadSurfaceCoeff("1", roadSurface, coeffVer), roadCnossosParameters.getSpeedLv(), 70.); diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/road/cnossos/RoadCnossosParameters.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/road/cnossos/RoadCnossosParameters.java index 4ffcbfc6b..f50ca5350 100644 --- a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/road/cnossos/RoadCnossosParameters.java +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/road/cnossos/RoadCnossosParameters.java @@ -35,7 +35,7 @@ public class RoadCnossosParameters { private double Junc_dist = 250; // Distance to junction - private int Junc_type; // Junction type (k=1 traffic lights, k=2 roundabout) + private int Junc_type; // Junction type (k=0 None, k=1 traffic lights, k=2 roundabout) private double slopePercentage = 0; // slope s (in %), In the case of a bi-directional traffic flow, it is necessary to split the flow into two components and correct half for uphill and half for downhill. private int way = 1; // 1 = direct, 2 = inverse, 3 = double @@ -65,14 +65,14 @@ public RoadCnossosParameters() { * * @param lv_speed Average light vehicle speed * @param mv_speed Average medium vehicle speed - * @param hgv_speed Average heavy goods vehicle speed + * @param hgv_speed Average heavy vehicle speed * @param wav_speed Average light 2 wheels vehicle speed * @param wbv_speed Average heavy 2 wheels vehicle speed * @param lvPerHour Average light vehicle per hour - * @param mvPerHour Average heavy vehicle per hour - * @param hgvPerHour Average heavy vehicle per hour - * @param wavPerHour Average heavy vehicle per hour - * @param wbvPerHour Average heavy vehicle per hour + * @param mvPerHour Average medium vehicles per hour + * @param hgvPerHour Average heavy vehicles per hour + * @param wavPerHour Average light 2 wheels vehicles per hour + * @param wbvPerHour Average heavy 2 wheels vehicles per hour * @param frequency Studied Frequency (must be octave band) * @param Temperature Temperature (Celsius) * @param roadSurface roadSurface empty default, NL01 FR01 .. (look at src/main/resources/org/noise_planet/noisemodelling/emission/RoadCnossos_2020.json) diff --git a/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/utils/UriUtils.java b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/utils/UriUtils.java new file mode 100644 index 000000000..25b036315 --- /dev/null +++ b/noisemodelling-emission/src/main/java/org/noise_planet/noisemodelling/emission/utils/UriUtils.java @@ -0,0 +1,79 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

+ * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

+ * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.emission.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.Set; + +public class UriUtils { + + private static final Set ALLOWED_SCHEMES = Set.of("http", "https", "file"); + + private static final HttpClient CLIENT = HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(10)) + .build(); + + /** + * Validates if a string is a well-formed URI and uses an approved scheme + * (http, https, or file). + * + * @param uriString the string to validate; can be null or empty + * @return {@code true} if the string is a valid URI with an allowed scheme, + * {@code false} otherwise + */ + public static boolean isValidUri(String uriString) { + if (uriString == null || uriString.isBlank()) { + return false; + } + + try { + URI uri = new URI(uriString); + String scheme = uri.getScheme(); + return scheme != null && ALLOWED_SCHEMES.contains(scheme.toLowerCase()); + } catch (URISyntaxException e) { + return false; + } + } + + /** + * Fetches a resource as an InputStream using the modern HttpClient API. + * This method validates the HTTP status code before returning the stream. + * + * @param urlString The full URL of the resource. + * @return An InputStream of the response body. + * @throws IOException If a network error occurs, or the server returns a non-200 code or the operation is interrupted. + */ + public static InputStream openSafeStream(String urlString) throws IOException { + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(urlString)) + .timeout(Duration.ofSeconds(30)) + .GET() + .build(); + + try { + HttpResponse response = CLIENT.send(request, HttpResponse.BodyHandlers.ofInputStream()); + + if (response.statusCode() != 200) { + throw new IOException("Failed to fetch " + urlString + ". HTTP Status: " + response.statusCode()); + } + + return response.body(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IOException("Request was interrupted", e); + } + } +} \ No newline at end of file diff --git a/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayEmissionCnossos.json b/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayEmissionCnossos.json new file mode 100644 index 000000000..988d1b075 --- /dev/null +++ b/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayEmissionCnossos.json @@ -0,0 +1,6464 @@ +{ + "Vehicle": { + "Transfer": { + "EU0": { + "Default": "true", + "Reference": "", + "Description": "Empty vehicle transfer function", + "WheelDiameter": null, + "WheelDiameterCode": null, + "Spectre": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "WheelDiameter": null, + "WheelDiameterCode": null, + "Spectre": [ + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60, + 60 + ] + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "WheelDiameter": null, + "WheelDiameterCode": null, + "Spectre": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ] + }, + "EU3": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Wheel with diameter 920 mm, no measure", + "WheelDiameter": 920, + "WheelDiameterCode": null, + "Spectre": [ + 75.4, + 77.3, + 81.1, + 84.1, + 83.3, + 84.3, + 86, + 90.1, + 89.8, + 89, + 88.8, + 90.4, + 92.4, + 94.9, + 100.4, + 104.6, + 109.6, + 114.9, + 115, + 115, + 115.5, + 115.6, + 116, + 116.7 + ] + }, + "EU4": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Wheel with diameter 840 mm, no measure", + "WheelDiameter": 840, + "WheelDiameterCode": null, + "Spectre": [ + 75.4, + 77.3, + 81.1, + 84.1, + 82.8, + 83.3, + 84.1, + 86.9, + 87.9, + 89.9, + 90.9, + 91.5, + 91.5, + 93, + 98.7, + 101.6, + 107.6, + 111.9, + 114.5, + 114.5, + 115, + 115.1, + 115.5, + 116.2 + ] + }, + "EU5": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Wheel with diameter 680 mm, no measure", + "WheelDiameter": 680, + "WheelDiameterCode": null, + "Spectre": [ + 75.4, + 77.3, + 81.1, + 84.1, + 82.8, + 83.3, + 83.9, + 86.3, + 88, + 92.2, + 93.9, + 92.5, + 90.9, + 90.4, + 93.2, + 93.5, + 99.6, + 104.9, + 108, + 111, + 111.5, + 111.6, + 112, + 112.7 + ] + }, + "EU6": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Wheel with diameter 1200 mm, no measure", + "WheelDiameter": 1200, + "WheelDiameterCode": null, + "Spectre": [ + 75.4, + 77.3, + 81.1, + 84.1, + 82.8, + 83.3, + 84.5, + 90.4, + 90.4, + 89.9, + 90.1, + 91.3, + 91.5, + 93.6, + 100.5, + 104.6, + 115.6, + 115.9, + 116, + 116, + 116.5, + 116.6, + 117, + 117.7 + ] + }, + "SNCF1": { + "Description": "Roue-de-diametre-1200-mm", + "Reference": "SNCF Juin 2021", + "Spectre": [ + 66.2, + 70.2, + 78.2, + 90.9, + 89.1, + 91.8, + 93.8, + 96.9, + 97.3, + 100.8, + 106.1, + 112.8, + 119.1, + 121.0, + 121.9, + 123.4, + 126.4, + 128.0, + 128.9, + 130.3, + 131.0, + 126.7, + 124.7, + 122.7 + ] + }, + "SNCF2": { + "Description": "Roue-de-diametre-920-mm", + "Reference": "SNCF Juin 2021", + "Spectre": [ + 66.2, + 68.2, + 72.2, + 79.0, + 80.0, + 82.3, + 84.4, + 87.4, + 89.4, + 92.3, + 94.9, + 101.8, + 108.3, + 112.2, + 113.7, + 115.2, + 119.0, + 122.4, + 124.8, + 125.0, + 124.1, + 120.1, + 121.2, + 122.2 + ] + }, + "SNCF3": { + "Description": "Roue-de-diametre-840-mm", + "Reference": "SNCF Juin 2021", + "Spectre": [ + 65.9, + 67.6, + 73.5, + 73.3, + 78.0, + 81.8, + 86.4, + 86.1, + 86.7, + 90.8, + 96.7, + 103.1, + 107.4, + 111.6, + 115.2, + 112.4, + 116.0, + 118.1, + 119.7, + 120.1, + 119.4, + 116.4, + 116.8, + 117.5 + ] + }, + "SNCF4": { + "Description": "Roue-de-diametre-680-mm", + "Reference": "SNCF Juin 2021", + "Spectre": [ + 64.6, + 66.1, + 72.9, + 73.7, + 77.2, + 78.1, + 85.4, + 85.6, + 86.1, + 90.4, + 96.7, + 102.3, + 105.5, + 108.9, + 113.1, + 107.0, + 107.4, + 104.6, + 106.5, + 106.8, + 104.9, + 102.6, + 103.0, + 103.7 + ] + } + }, + "WheelRoughness": { + "EU0": { + "Default": "true", + "Reference": "", + "Description": "Empty wheel roughness", + "Values": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "Values": [ + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15 + ] + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "Values": [ + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25, + 25 + ] + }, + "EU3": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "cast iron tread", + "Values": [ + 2.168461586134174, + 2.168461586134174, + 2.168461586134174, + 2.168461586134174, + 2.168461586134174, + 2.168461586134174, + 2.168461586134174, + 2.168461586134174, + 2.168461586134174, + 2.168461586134174, + 2.168461586134174, + 2.367004589322595, + 0.614781263900754, + 2.610924413363449, + 5.756528561202869, + 8.778461586134174, + 11.11001151291529, + 10.95837155865965, + 9.791459375057219, + 7.491604590973592, + 5.148695207491488, + 3.022589893365378, + 1.28616199715323, + 0.167997434442427, + -0.702413370803574, + -1.167439464293351, + -1.02041103167661, + 0.271557355244967, + 0.238403459692385, + 1.321311142906995, + 3.097108457482452, + 3.097108457482452, + 3.097108457482452, + 3.097108457482452, + 3.097108457482452 + ] + }, + "EU4": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "composite", + "Values": [ + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -3.95419018689975, + -4.341299537395543, + -4.620974767837635, + -4.897055026064954, + -5.222436281288831, + -6.308578167786185, + -6.798467723797528, + -7.240263355022869, + -7.269624675426479, + -7.271295786579055, + -7.139967758266058, + -6.937736627618217, + -6.6786309297519, + -5.991369963895746, + -3.748676578106019, + -2.376692988528715, + -2.590206897753383, + -2.464430278717203, + -2.464430278717203, + -2.464430278717203, + -2.464430278717203, + -2.464430278717203 + ] + }, + "EU5": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "disc brake", + "Values": [ + -5.93, + -5.93, + -5.93, + -5.93, + -5.93, + -5.93, + -5.93, + -5.93, + -5.93, + 2.32, + 2.82, + 2.56, + 1.22, + 2.06, + 0.92, + -0.25, + -1.57, + -2.85, + -4.94, + -7, + -8.58, + -9.32, + -9.51, + -10.12, + -10.25, + -10.33, + -10.81, + -10.91, + -9.52, + -9.52, + -9.52, + -9.52, + -9.52, + -9.52, + -9.52 + ] + }, + "SNCF1": { + "Description": "Freins-semelles-fonte", + "Reference": "SNCF Juin 2021", + "Values": [ + 1.7, + 1.7, + 1.8, + 2.2, + 2.8, + 3.4, + 3.8, + 4.1, + 4.4, + 4.6, + 4.8, + 5.3, + 5.3, + 5.8, + 6.6, + 7.9, + 7.8, + 7, + 5.7, + 3.9, + 1.3, + -0.9, + -2.5, + -4.4, + -6.5, + -8.8, + -11.4, + -12.7, + -13.6, + -14.2, + -14.6, + -14.8, + -15, + -15, + -15 + ] + }, + "SNCF2": { + "Description": "Freins-semelles-composites", + "Reference": "SNCF Juin 2021", + "Values": [ + 2, + 2, + 2, + 2, + 2.1, + 2.1, + 2.1, + 2.1, + 2.1, + 2.1, + 0.6, + 0, + -0.9, + -1.7, + -2.2, + -3.3, + -4.2, + -5.7, + -7.2, + -8.1, + -9.5, + -10.2, + -10.9, + -11.7, + -12.7, + -13.8, + -15.3, + -17.8, + -17.8, + -17.8, + -17.8, + -17.8, + -17.8, + -17.8, + -17.8 + ] + }, + "SNCF3": { + "Description": "Freins-semelles-composites-+-disque", + "Reference": "SNCF Juin 2021", + "Values": [ + -12.5, + -12.5, + -12.5, + -12.5, + -12.5, + -12.5, + -12.5, + -12.5, + -12.5, + -12.5, + -14.5, + -10.9, + -13.3, + -14.8, + -13.5, + -14.3, + -14.7, + -15, + -14.5, + -15, + -14.5, + -14.5, + -16.7, + -17.5, + -17.5, + -17.9, + -18.9, + -20.7, + -20.7, + -20.7, + -20.6, + -20.6, + -20.6, + -20.5, + -20.5 + ] + }, + "SNCF4": { + "Description": "Freins-a-disque", + "Reference": "SNCF Juin 2021", + "Values": [ + 7, + 7, + 7, + 7, + 6.5, + 1, + 2, + 2.4, + 1, + 0.2, + 1.2, + -1.2, + -2.1, + -2.7, + -3.5, + -4.3, + -5.4, + -6.2, + -6.6, + -7, + -7.6, + -7.7, + -8, + -8.5, + -8.9, + -9.5, + -10.8, + -12.1, + -13.7, + -15.8, + -18.3, + -21, + -23.5, + -25.6, + -28 + ] + } + }, + "ContactFilter": { + "EU0": { + "Default": "true", + "Reference": null, + "Description": "Empty contact filter", + "Load": null, + "WheelDiameter": null, + "WheelDiameterCode": null, + "Values": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "Load": null, + "WheelDiameter": null, + "WheelDiameterCode": null, + "Values": [ + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30, + -30 + ] + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "Load": null, + "WheelDiameter": null, + "WheelDiameterCode": null, + "Values": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "EU3": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Wheel load 50kN wheel diameter 360mm", + "Load": "50", + "WheelDiameter": "360", + "WheelDiameterCode": "small, <500mm", + "Values": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.1, + -0.2, + -0.3, + -0.6, + -1.0, + -1.8, + -3.2, + -5.4, + -8.7, + -12.2, + -16.7, + -17.7, + -17.8, + -20.7, + -22.1, + -22.8, + -24.0, + -24.5, + -24.7, + -27.0, + -27.8 + ] + }, + "EU4": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Wheel load 50kN wheel diameter 680mm", + "Load": "50", + "WheelDiameter": "680", + "WheelDiameterCode": "medium, 500 to 800mm", + "Values": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.1, + -0.2, + -0.3, + -0.7, + -1.2, + -2.0, + -4.1, + -6.0, + -9.2, + -13.8, + -17.2, + -17.7, + -18.6, + -21.5, + -22.3, + -23.1, + -24.4, + -24.5, + -25.0, + -28.0, + -28.8, + -29.6 + ] + }, + "EU5": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Wheel load 25kN wheel diameter 920mm", + "Load": "25", + "WheelDiameter": "920", + "WheelDiameterCode": "large, >800mm", + "Values": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.1, + -0.3, + -0.5, + -1.1, + -1.8, + -3.3, + -5.3, + -7.9, + -12.8, + -16.8, + -17.7, + -18.2, + -20.5, + -22.0, + -22.8, + -24.2, + -24.5, + -25.0, + -27.4, + -28.2, + -29.0 + ] + }, + "EU6": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Wheel load 50kN wheel diameter 920mm", + "Load": "50", + "WheelDiameter": "920", + "WheelDiameterCode": "large, >800mm", + "Values": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.1, + -0.1, + -0.3, + -0.6, + -1.1, + -1.3, + -3.5, + -5.3, + -8.0, + -12.0, + -16.8, + -17.7, + -18.0, + -21.5, + -21.8, + -22.8, + -24.0, + -24.5, + -25.0, + -27.3, + -28.1, + -28.9, + -29.7 + ] + }, + "EU7": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Wheel load 100kN wheel diameter 920mm", + "Load": "100", + "WheelDiameter": "920", + "WheelDiameterCode": "large, >800mm", + "Values": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -0.1, + -0.2, + -0.3, + -0.6, + -1.0, + -1.8, + -3.2, + -5.4, + -8.7, + -12.2, + -16.7, + -17.7, + -17.8, + -20.7, + -22.1, + -22.8, + -24.0, + -24.5, + -24.7, + -27.0, + -27.8, + -28.6, + -29.4, + -30.2 + ] + }, + "SNCF1": { + "Description": "Charge-a-l-es-sieu-50kN-Diametre-de-roue-360mm", + "Reference": "SNCF Juin 2021", + "Values": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.1, + -0.2, + -0.3, + -0.6, + -1, + -1.8, + -3.2, + -5.4, + -8.7, + -12.2, + -16.7, + -17.7, + -17.8, + -20.7, + -22.1, + -22.8, + -24, + -24.5, + -24.7, + -27, + -27.8 + ] + }, + "SNCF2": { + "Description": "Charge-a-l-es-sieu-50kN-Diametre-de-roue-680mm", + "Reference": "SNCF Juin 2021", + "Values": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.1, + -0.2, + -0.3, + -0.7, + -1.2, + -2, + -4.1, + -6, + -9.2, + -13.8, + -17.2, + -17.7, + -18.6, + -21.5, + -22.3, + -23.1, + -24.4, + -24.5, + -25, + -28, + -28.8, + -29.6 + ] + }, + "SNCF3": { + "Description": "Charge-a-l-es-sieu-25kN-Diametre-de-roue-920mm", + "Reference": "SNCF Juin 2021", + "Values": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.1, + -0.3, + -0.5, + -1.1, + -1.8, + -3.3, + -5.3, + -7.9, + -12.8, + -16.8, + -17.7, + -18.2, + -20.5, + -22, + -22.8, + -24.2, + -24.5, + -25, + -27.4, + -28.2, + -29 + ] + }, + "SNCF4": { + "Description": "Charge-a-l-es-sieu-50kN-Diametre-de-roue-920mm", + "Reference": "SNCF Juin 2021", + "Values": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.1, + -0.1, + -0.3, + -0.6, + -1.1, + -1.3, + -3.5, + -5.3, + -8, + -12, + -16.8, + -17.7, + -18, + -21.5, + -21.8, + -22.8, + -24, + -24.5, + -25, + -27.3, + -28.1, + -28.9, + -29.7 + ] + }, + "SNCF5": { + "Description": "Charge-a-l-es-sieu-100kN-Diametre-de-roue-920mm", + "Reference": "SNCF Juin 2021", + "Values": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + -0.1, + -0.2, + -0.3, + -0.6, + -1, + -1.8, + -3.2, + -5.4, + -8.7, + -12.2, + -16.7, + -17.7, + -17.8, + -20.7, + -22.1, + -22.8, + -24, + -24.5, + -24.7, + -27, + -27.8, + -28.6, + -29.4, + -30.2 + ] + } + }, + "ConstantSpeed": { + "EU0": { + "Default": "true", + "Reference": null, + "Description": "Empty traction", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "Values": { + "A": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ], + "B": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ] + } + }, + "EU3": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel locomotive (c. 800kW)", + "Values": { + "A": [ + 98.8613, + 94.7613, + 92.5613, + 94.5613, + 92.7613, + 92.7613, + 92.9613, + 94.7613, + 94.5613, + 95.6613, + 95.5613, + 98.5613, + 95.1613, + 95.0613, + 95.0613, + 94.0613, + 94.0613, + 99.3613, + 92.4613, + 89.4613, + 86.9613, + 84.0613, + 81.4613, + 79.1613 + ], + "B": [ + 103.1613, + 99.9613, + 95.4613, + 93.9613, + 93.2613, + 93.5613, + 92.8613, + 92.6613, + 92.3613, + 92.7613, + 92.7613, + 96.7613, + 92.6613, + 92.9613, + 92.8613, + 93.0613, + 93.1613, + 98.2613, + 91.4613, + 88.6613, + 85.9613, + 83.3613, + 80.8613, + 78.6613 + ] + } + }, + "EU4": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel locomotive (c. 2200kW)", + "Values": { + "A": [ + 99.4103, + 107.3103, + 103.1103, + 102.1103, + 99.3103, + 99.3103, + 99.5103, + 101.3103, + 101.1103, + 102.2103, + 102.1103, + 101.1103, + 101.7103, + 101.6103, + 99.3103, + 96.0103, + 93.7103, + 101.9103, + 89.5103, + 87.1103, + 90.5103, + 31.4103, + 81.2103, + 79.6103 + ], + "B": [ + 103.7103, + 112.5103, + 106.0103, + 101.5103, + 99.8103, + 100.1103, + 99.4103, + 99.2103, + 98.9103, + 99.3103, + 99.3103, + 99.3103, + 99.2103, + 99.5103, + 97.1103, + 95.0103, + 92.8103, + 100.8103, + 88.5103, + 86.3103, + 89.5103, + 30.7103, + 80.6103, + 79.1103 + ] + } + }, + "EU5": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/RENFE Dloco/1155kW", + "Values": { + "A": [ + 99.3003, + 103.2003, + 109.0003, + 114.0003, + 109.2003, + 106.2003, + 103.4003, + 105.2003, + 105.0003, + 106.1003, + 106.0003, + 105.0003, + 105.6003, + 104.5003, + 102.9003, + 99.4003, + 96.8003, + 94.6003, + 92.1003, + 89.6003, + 87.5003, + 85.1003, + 82.9003, + 81.1003 + ], + "B": [ + 103.6003, + 108.4003, + 111.9003, + 113.4003, + 109.7003, + 107.0003, + 103.3003, + 103.1003, + 102.8003, + 103.2003, + 103.2003, + 103.2003, + 103.1003, + 102.4003, + 100.7003, + 98.4003, + 95.9003, + 93.5003, + 91.1003, + 88.8003, + 86.5003, + 84.4003, + 82.3003, + 80.6003 + ] + } + }, + "EU6": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/NS6400 Dloco/1180kW", + "Values": { + "A": [ + 100.9836, + 89.8836, + 92.6836, + 104.6836, + 94.8836, + 87.8836, + 83.0836, + 84.8836, + 84.6836, + 85.7836, + 85.6836, + 84.6836, + 85.2836, + 85.1836, + 85.1836, + 84.1836, + 84.1836, + 84.4836, + 81.5836, + 78.5836, + 76.0836, + 73.1836, + 70.5836, + 68.2836 + ], + "B": [ + 105.2836, + 95.0836, + 95.5836, + 104.0836, + 95.3836, + 88.6836, + 82.9836, + 82.7836, + 82.4836, + 82.8836, + 82.8836, + 82.8836, + 82.7836, + 83.0836, + 82.9836, + 83.1836, + 83.2836, + 83.3836, + 80.5836, + 77.7836, + 75.0836, + 72.4836, + 69.9836, + 67.7836 + ] + } + }, + "EU7": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/TKOJ JT42CWR/Class66/2200kW", + "Values": { + "A": [ + 95.432, + 104.332, + 102.132, + 99.132, + 93.332, + 96.332, + 96.532, + 98.332, + 98.132, + 99.232, + 99.132, + 98.132, + 98.732, + 96.632, + 94.632, + 91.632, + 89.632, + 87.932, + 86.032, + 84.032, + 82.532, + 80.632, + 79.032, + 77.732 + ], + "B": [ + 99.732, + 109.532, + 105.032, + 98.532, + 93.832, + 97.132, + 96.432, + 96.232, + 95.932, + 96.332, + 96.332, + 96.332, + 96.232, + 94.532, + 92.432, + 90.632, + 88.732, + 86.832, + 85.032, + 83.232, + 81.532, + 79.932, + 78.432, + 77.232 + ] + } + }, + "EU8": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel multiple unit", + "Values": { + "A": [ + 82.583, + 82.483, + 89.283, + 90.283, + 93.483, + 99.483, + 98.683, + 95.483, + 90.283, + 91.383, + 91.283, + 90.283, + 90.883, + 91.783, + 92.783, + 92.783, + 90.783, + 88.083, + 85.183, + 83.183, + 81.683, + 78.783, + 76.183, + 73.883 + ], + "B": [ + 86.883, + 87.683, + 92.183, + 89.683, + 93.983, + 100.283, + 98.583, + 93.383, + 88.083, + 88.483, + 88.483, + 88.483, + 88.383, + 89.683, + 90.583, + 91.783, + 89.883, + 86.983, + 84.183, + 82.383, + 80.683, + 78.083, + 75.583, + 73.383 + ] + } + }, + "EU9": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Electric locomotive", + "Values": { + "A": [ + 87.8551, + 90.7551, + 91.5551, + 94.5551, + 94.7551, + 96.7551, + 103.9551, + 100.7551, + 99.5551, + 101.6551, + 98.5551, + 95.5551, + 95.1551, + 96.0551, + 92.0551, + 89.0551, + 87.0551, + 85.3551, + 83.4551, + 81.4551, + 79.9551, + 78.0551, + 76.4551, + 75.1551 + ], + "B": [ + 92.1551, + 95.9551, + 94.4551, + 93.9551, + 95.2551, + 97.5551, + 103.8551, + 98.6551, + 97.3551, + 98.7551, + 95.7551, + 93.7551, + 92.6551, + 93.9551, + 89.8551, + 88.0551, + 86.1551, + 84.2551, + 82.4551, + 80.6551, + 78.9551, + 77.3551, + 75.8551, + 74.6551 + ] + } + }, + "EU10": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Electric multiple unit ", + "Values": { + "A": [ + 80.5497, + 81.4497, + 80.5497, + 82.2497, + 80.0497, + 79.7497, + 79.6497, + 96.4497, + 80.5497, + 81.3497, + 97.2497, + 79.5497, + 79.8497, + 86.7497, + 81.7497, + 82.7497, + 80.7497, + 78.0497, + 75.1497, + 72.1497, + 69.6497, + 66.7497, + 64.1497, + 61.8497 + ], + "B": [ + 84.8497, + 86.6497, + 83.4497, + 81.6497, + 80.5497, + 80.5497, + 79.5497, + 94.3497, + 78.3497, + 78.4497, + 94.4497, + 77.7497, + 77.3497, + 84.6497, + 79.5497, + 81.7497, + 79.8497, + 76.9497, + 74.1497, + 71.3497, + 68.6497, + 66.0497, + 63.5497, + 61.3497 + ] + } + }, + "SNCF1": { + "Description": "Trains-a-grande-vitesse", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 88.9, + 88.8, + 88.7, + 89.2, + 86.1, + 93.2, + 89.8, + 83.3, + 85.9, + 86.1, + 84.7, + 84, + 82.5, + 83.6, + 80.6, + 80.2, + 78, + 76.4, + 75.5, + 74.4, + 70.8, + 66.7, + 61.5, + 59.5 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "SNCF2": { + "Description": "Automoteur-type-A", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 95.2, + 94.8, + 92.1, + 90.3, + 88.9, + 90, + 91.4, + 95.6, + 96.1, + 91, + 95, + 92.5, + 91, + 91.8, + 90.8, + 89.7, + 88.4, + 87.4, + 86.3, + 82.5, + 80.3, + 78.4, + 72.5, + 70.7 + ] + } + }, + "SNCF3": { + "Description": "Automoteur-type-B", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 82.1, + 81.7, + 79.0, + 77.2, + 75.8, + 76.9, + 78.3, + 82.5, + 83.0, + 77.9, + 81.9, + 79.4, + 77.9, + 78.7, + 77.7, + 76.6, + 75.3, + 74.3, + 73.2, + 69.4, + 67.2, + 65.3, + 59.4, + 58.8 + ] + } + }, + "SNCF4": { + "Description": "Automoteur-type-C", + "Reference": "SNCF Juin 2021", + "Values": { + "B": [ + 88, + 87.5, + 85, + 83.5, + 80.2, + 85.2, + 82.5, + 80.8, + 80.9, + 76.6, + 77.5, + 77, + 75.9, + 75.6, + 75.5, + 75.2, + 73.3, + 70.5, + 69.6, + 67.6, + 65.4, + 63.3, + 56.9, + 55.4 + ], + "A": [ + 69.7, + 69.7, + 69.7, + 77.9, + 74.5, + 79.9, + 74.4, + 69.4, + 69, + 67.9, + 67.8, + 66.5, + 65.4, + 64.9, + 64.5, + 63.4, + 62.3, + 60.8, + 67.5, + 65.5, + 59.7, + 58, + 57.9, + 57.8 + ] + } + }, + "SNCF5": { + "Description": "Automoteur-type-D", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 77.5, + 77, + 75.6, + 80.3, + 79, + 78.1, + 79.1, + 78.6, + 76.9, + 75.9, + 73.8, + 74.4, + 73.8, + 75, + 75.3, + 69.1, + 69, + 68.3, + 66.3, + 63.6, + 60.6, + 57.9, + 55.5, + 55.1 + ] + } + }, + "SNCF6": { + "Description": "Automoteur-type-E", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 78.8, + 79.5, + 85.1, + 89.2, + 84.7, + 83.4, + 83.9, + 86.9, + 85.3, + 80.9, + 79.4, + 80.8, + 82.7, + 79.7, + 77.8, + 77.2, + 77.6, + 74.8, + 73.8, + 72.6, + 66.8, + 63.8, + 59, + 58.6 + ] + } + }, + "SNCF7": { + "Description": "Automoteur-type-F", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 93.3, + 94.7, + 100.3, + 104.4, + 99.9, + 98.6, + 99.1, + 102.1, + 100.5, + 96.1, + 94.6, + 96.1, + 97.9, + 95, + 93, + 92.4, + 92.8, + 90, + 89.1, + 87.8, + 82.1, + 79, + 74.2, + 73.7 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "SNCF8": { + "Description": "Automoteur-type-G", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 88.5, + 90.5, + 96.1, + 100.2, + 95.7, + 94.4, + 94.9, + 97.9, + 96.3, + 91.9, + 90.4, + 91.9, + 93.7, + 90.8, + 88.8, + 88.2, + 88.6, + 85.8, + 84.9, + 83.6, + 77.9, + 74.8, + 70, + 68.1 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "SNCF9": { + "Description": "Automoteur-type-H", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 61.4, + 61.8, + 62.6, + 65, + 69.4, + 73.3, + 71.6, + 70.9, + 76.3, + 75.2, + 76, + 75.6, + 83.5, + 76.9, + 72.8, + 73.1, + 73.6, + 68.9, + 66.2, + 64.1, + 62.4, + 54.8, + 43.4, + 39.6 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "SNCF10": { + "Description": "Rames-remorquees", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "SNCF11": { + "Description": "Voitures-remorquees-type-A", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 82.1, + 81.4, + 78.7, + 76.9, + 75.5, + 76.6, + 78, + 82.2, + 82.7, + 77.6, + 81.6, + 79.1, + 77.6, + 78.4, + 77.4, + 76.3, + 75, + 74, + 72.9, + 69.1, + 66.9, + 65, + 59.1, + 57.8 + ] + } + }, + "SNCF12": { + "Description": "Voitures-remorquees-type-B", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 66.7, + 67.2, + 68, + 70.4, + 74.8, + 78.7, + 77, + 76.3, + 81.7, + 80.6, + 81.4, + 81, + 88.9, + 82.3, + 78.2, + 78.5, + 79, + 74.3, + 71.6, + 69.5, + 67.8, + 60.2, + 48.8, + 46.6 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "SNCF13": { + "Description": "Tram-train", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 78.2, + 78, + 77.7, + 78.4, + 75.8, + 80.6, + 82.1, + 82.6, + 80, + 77.2, + 76.2, + 74.8, + 75.1, + 73.9, + 71.4, + 70.9, + 69.6, + 67.5, + 66.5, + 60.1, + 58.2, + 54.7, + 50.7, + 48.6 + ] + } + }, + "SNCF14": { + "Description": "Locomotive-type-A", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 96.4, + 96.7, + 97.2, + 91.5, + 92.1, + 89.9, + 89.2, + 88.6, + 88.6, + 90.2, + 91.8, + 92.3, + 90, + 90.2, + 88.3, + 84.6, + 86.2, + 78.6, + 74.7, + 71, + 70.2, + 70, + 66.8, + 65.7 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "SNCF15": { + "Description": "Locomotive-type-B", + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 90.9, + 90.5, + 89.2, + 87.1, + 87.3, + 84.5, + 88.2, + 92.3, + 96, + 89.6, + 92.8, + 87.9, + 87.1, + 87.7, + 86.4, + 84.6, + 86, + 83.3, + 86.9, + 76.7, + 75, + 71.4, + 66.2, + 64.8 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + } + }, + "AccelerationSpeed": { + "EU0": { + "Default": "true", + "Reference": null, + "Description": "Empty traction", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "Values": { + "A": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ], + "B": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ] + } + }, + "EU3": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel locomotive (c. 800kW)", + "Values": { + "A": [ + 96.8613, + 102.7613, + 100.5613, + 97.5613, + 95.7613, + 95.7613, + 95.9613, + 97.7613, + 97.5613, + 98.6613, + 98.5613, + 102.5613, + 98.1613, + 98.0613, + 98.0613, + 97.0613, + 97.0613, + 97.3613, + 105.4613, + 97.4613, + 94.9613, + 92.0613, + 89.4613, + 87.1613 + ], + "B": [ + 101.1613, + 107.9613, + 103.4613, + 96.9613, + 96.2613, + 96.5613, + 95.8613, + 95.6613, + 95.3613, + 95.7613, + 95.7613, + 100.7613, + 95.6613, + 95.9613, + 95.8613, + 96.0613, + 96.1613, + 96.2613, + 104.4613, + 96.6613, + 93.9613, + 91.3613, + 88.8613, + 86.6613 + ] + } + }, + "EU4": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel locomotive (c. 2200kW)", + "Values": { + "A": [ + 99.4103, + 102.3103, + 113.1103, + 107.1103, + 103.3103, + 102.3103, + 102.5103, + 104.3103, + 104.1103, + 105.2103, + 105.1103, + 104.1103, + 104.7103, + 104.6103, + 102.3103, + 99.0103, + 96.7103, + 94.7103, + 105.0103, + 90.1103, + 88.3103, + 93.6103, + 84.2103, + 82.6103 + ], + "B": [ + 103.7103, + 107.5103, + 116.0103, + 106.5103, + 103.8103, + 103.1103, + 102.4103, + 102.2103, + 101.9103, + 102.3103, + 102.3103, + 102.3103, + 102.2103, + 102.5103, + 100.1103, + 98.0103, + 95.8103, + 93.6103, + 104.0103, + 89.3103, + 87.3103, + 92.9103, + 83.6103, + 82.1103 + ] + } + }, + "EU5": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/RENFE Dloco/1155kW", + "Values": { + "A": [ + 99.3003, + 103.2003, + 109.0003, + 114.0003, + 115.2003, + 112.2003, + 109.4003, + 108.2003, + 108.0003, + 109.1003, + 109.0003, + 108.0003, + 108.6003, + 108.5003, + 107.5003, + 104.9003, + 102.4003, + 100.1003, + 97.7003, + 95.1003, + 93.1003, + 90.6003, + 88.5003, + 86.6003 + ], + "B": [ + 103.6003, + 108.4003, + 111.9003, + 113.4003, + 115.7003, + 113.0003, + 109.3003, + 106.1003, + 105.8003, + 106.2003, + 106.2003, + 106.2003, + 106.1003, + 106.4003, + 105.3003, + 103.9003, + 101.5003, + 99.0003, + 96.7003, + 94.3003, + 92.1003, + 89.9003, + 87.9003, + 86.1003 + ] + } + }, + "EU6": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/NS6400 Dloco/1180kW", + "Values": { + "A": [ + 98.9836, + 104.8836, + 95.6836, + 97.6836, + 105.8836, + 97.8836, + 91.0836, + 87.8836, + 87.6836, + 88.7836, + 88.6836, + 87.6836, + 88.2836, + 88.1836, + 88.1836, + 87.1836, + 87.1836, + 87.4836, + 87.5836, + 84.5836, + 82.0836, + 79.1836, + 76.5836, + 74.2836 + ], + "B": [ + 103.2836, + 110.0836, + 98.5836, + 97.0836, + 106.3836, + 98.6836, + 90.9836, + 85.7836, + 85.4836, + 85.8836, + 85.8836, + 85.8836, + 85.7836, + 86.0836, + 85.9836, + 86.1836, + 86.2836, + 86.3836, + 86.5836, + 83.7836, + 81.0836, + 78.4836, + 75.9836, + 73.7836 + ] + } + }, + "EU7": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/TKOJ JT42CWR/Class66/2200kW", + "Values": { + "A": [ + 91.432, + 99.332, + 110.132, + 107.132, + 100.332, + 96.332, + 99.532, + 101.332, + 101.132, + 102.232, + 102.132, + 101.132, + 101.732, + 101.632, + 99.632, + 96.632, + 94.632, + 92.932, + 91.032, + 89.032, + 87.532, + 85.632, + 84.032, + 82.732 + ], + "B": [ + 95.732, + 104.532, + 113.032, + 106.532, + 100.832, + 97.132, + 99.432, + 99.232, + 98.932, + 99.332, + 99.332, + 99.332, + 99.232, + 99.532, + 97.432, + 95.632, + 93.732, + 91.832, + 90.032, + 88.232, + 86.532, + 84.932, + 83.432, + 82.232 + ] + } + }, + "EU8": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel multiple unit", + "Values": { + "A": [ + 80.583, + 86.483, + 88.283, + 94.283, + 91.483, + 96.483, + 102.683, + 103.483, + 98.283, + 94.383, + 94.283, + 93.283, + 93.883, + 93.783, + 94.783, + 94.783, + 95.783, + 94.083, + 91.183, + 88.183, + 86.683, + 84.783, + 82.183, + 79.883 + ], + "B": [ + 84.883, + 91.683, + 91.183, + 93.683, + 91.983, + 97.283, + 102.583, + 101.383, + 96.083, + 91.483, + 91.483, + 91.483, + 91.383, + 91.683, + 92.583, + 93.783, + 94.883, + 92.983, + 90.183, + 87.383, + 85.683, + 84.083, + 81.583, + 79.383 + ] + } + }, + "EU9": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Electric locomotive", + "Values": { + "A": [ + 87.8551, + 94.7551, + 91.5551, + 94.5551, + 94.7551, + 96.7551, + 107.9551, + 100.7551, + 99.5551, + 105.6551, + 98.5551, + 95.5551, + 95.1551, + 100.0551, + 92.0551, + 89.0551, + 87.0551, + 85.3551, + 83.4551, + 81.4551, + 79.9551, + 78.0551, + 76.4551, + 75.1551 + ], + "B": [ + 92.1551, + 99.9551, + 94.4551, + 93.9551, + 95.2551, + 97.5551, + 107.8551, + 98.6551, + 97.3551, + 102.7551, + 95.7551, + 93.7551, + 92.6551, + 97.9551, + 89.8551, + 88.0551, + 86.1551, + 84.2551, + 82.4551, + 80.6551, + 78.9551, + 77.3551, + 75.8551, + 74.6551 + ] + } + }, + "EU10": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Electric multiple unit ", + "Values": { + "A": [ + 80.5497, + 81.4497, + 80.5497, + 82.2497, + 94.4497, + 79.7497, + 79.6497, + 96.4497, + 80.5497, + 81.3497, + 80.8497, + 79.5497, + 79.8497, + 86.7497, + 81.7497, + 82.7497, + 80.7497, + 78.0497, + 75.1497, + 72.1497, + 69.6497, + 66.7497, + 64.1497, + 61.8497 + ], + "B": [ + 84.8497, + 86.6497, + 83.4497, + 81.6497, + 94.9497, + 80.5497, + 79.5497, + 94.3497, + 78.3497, + 78.4497, + 78.0497, + 77.7497, + 77.3497, + 84.6497, + 79.5497, + 81.7497, + 79.8497, + 76.9497, + 74.1497, + 71.3497, + 68.6497, + 66.0497, + 63.5497, + 61.3497 + ] + } + } + }, + "DecelerationSpeed": { + "EU0": { + "Default": "true", + "Reference": null, + "Description": "Empty traction", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "Values": { + "A": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ], + "B": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ] + } + }, + "EU3": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel locomotive (c. 800kW)", + "Values": { + "A": [ + 87.8613, + 83.7613, + 86.5613, + 88.5613, + 86.7613, + 86.7613, + 86.9613, + 88.7613, + 88.5613, + 89.6613, + 89.5613, + 93.5613, + 89.1613, + 89.0613, + 89.0613, + 88.0613, + 88.0613, + 86.3613, + 83.4613, + 80.4613, + 77.9613, + 75.0613, + 72.4613, + 70.1613 + ], + "B": [ + 92.1613, + 88.9613, + 89.4613, + 87.9613, + 87.2613, + 87.5613, + 86.8613, + 86.6613, + 86.3613, + 86.7613, + 86.7613, + 91.7613, + 86.6613, + 86.9613, + 86.8613, + 87.0613, + 87.1613, + 85.2613, + 82.4613, + 79.6613, + 76.9613, + 74.3613, + 71.8613, + 69.6613 + ] + } + }, + "EU4": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel locomotive (c. 2200kW)", + "Values": { + "A": [ + 89.4103, + 90.3103, + 103.1103, + 95.1103, + 93.3103, + 93.3103, + 93.5103, + 95.3103, + 95.1103, + 96.2103, + 96.1103, + 95.1103, + 95.7103, + 95.6103, + 93.3103, + 96.6103, + 87.7103, + 85.7103, + 87.0103, + 81.1103, + 79.3103, + 77.1103, + 75.2103, + 73.6103 + ], + "B": [ + 93.7103, + 95.5103, + 106.0103, + 94.5103, + 93.8103, + 94.1103, + 93.4103, + 93.2103, + 92.9103, + 93.3103, + 93.3103, + 93.3103, + 93.2103, + 93.5103, + 91.1103, + 95.6103, + 86.8103, + 84.6103, + 86.0103, + 80.3103, + 78.3103, + 76.4103, + 74.6103, + 73.1103 + ] + } + }, + "EU5": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/RENFE Dloco/1155kW", + "Values": { + "A": [ + 99.3003, + 103.2003, + 103.0003, + 102.0003, + 97.2003, + 97.2003, + 97.4003, + 99.2003, + 99.0003, + 100.1003, + 100.0003, + 98.0003, + 97.0003, + 94.4003, + 91.8003, + 88.3003, + 85.7003, + 83.5003, + 81.0003, + 78.5003, + 76.4003, + 74.0003, + 71.9003, + 70.1003 + ], + "B": [ + 103.6003, + 108.4003, + 105.9003, + 101.4003, + 97.7003, + 98.0003, + 97.3003, + 97.1003, + 96.8003, + 97.2003, + 97.2003, + 96.2003, + 94.5003, + 92.3003, + 89.6003, + 87.3003, + 84.8003, + 82.4003, + 80.0003, + 77.7003, + 75.4003, + 73.3003, + 71.3003, + 69.6003 + ] + } + }, + "EU6": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/NS6400 Dloco/1180kW", + "Values": { + "A": [ + 82.9836, + 93.8836, + 88.6836, + 83.6836, + 76.8836, + 76.8836, + 77.0836, + 78.8836, + 78.6836, + 79.7836, + 79.6836, + 78.6836, + 79.2836, + 79.1836, + 79.1836, + 78.1836, + 75.1836, + 72.4836, + 69.5836, + 66.5836, + 64.0836, + 61.1836, + 58.5836, + 56.2836 + ], + "B": [ + 87.2836, + 99.0836, + 91.5836, + 83.0836, + 77.3836, + 77.6836, + 76.9836, + 76.7836, + 76.4836, + 76.8836, + 76.8836, + 76.8836, + 76.7836, + 77.0836, + 76.9836, + 77.1836, + 74.2836, + 71.3836, + 68.5836, + 65.7836, + 63.0836, + 60.4836, + 57.9836, + 55.7836 + ] + } + }, + "EU7": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/TKOJ JT42CWR/Class66/2200kW", + "Values": { + "A": [ + 92.432, + 88.332, + 87.132, + 92.132, + 90.332, + 90.332, + 90.532, + 92.332, + 92.132, + 93.232, + 93.132, + 90.132, + 88.732, + 86.632, + 84.632, + 81.632, + 79.632, + 77.932, + 76.032, + 74.032, + 72.532, + 70.632, + 69.032, + 67.732 + ], + "B": [ + 96.732, + 93.532, + 90.032, + 91.532, + 90.832, + 91.132, + 90.432, + 90.232, + 89.932, + 90.332, + 90.332, + 88.332, + 86.232, + 84.532, + 82.432, + 80.632, + 78.732, + 76.832, + 75.032, + 73.232, + 71.532, + 69.932, + 68.432, + 67.232 + ] + } + }, + "EU8": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel multiple unit", + "Values": { + "A": [ + 78.583, + 79.483, + 88.283, + 84.283, + 82.483, + 82.483, + 88.683, + 84.483, + 84.283, + 85.383, + 85.283, + 84.283, + 90.883, + 84.783, + 84.783, + 83.783, + 83.783, + 84.083, + 82.183, + 79.183, + 75.683, + 71.783, + 68.183, + 64.883 + ], + "B": [ + 82.883, + 84.683, + 91.183, + 83.683, + 82.983, + 83.283, + 88.583, + 82.383, + 82.083, + 82.483, + 82.483, + 82.483, + 88.383, + 82.683, + 82.583, + 82.783, + 82.883, + 82.983, + 81.183, + 78.383, + 74.683, + 71.083, + 67.583, + 64.383 + ] + } + }, + "EU9": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Electric locomotive", + "Values": { + "A": [ + 78.8551, + 84.7551, + 82.5551, + 85.5551, + 85.7551, + 87.7551, + 97.9551, + 91.7551, + 90.5551, + 95.6551, + 89.5551, + 86.5551, + 86.1551, + 90.0551, + 83.0551, + 80.0551, + 78.0551, + 76.3551, + 74.4551, + 72.4551, + 70.9551, + 69.0551, + 67.4551, + 66.1551 + ], + "B": [ + 83.1551, + 89.9551, + 85.4551, + 84.9551, + 86.2551, + 88.5551, + 97.8551, + 89.6551, + 88.3551, + 92.7551, + 86.7551, + 84.7551, + 83.6551, + 87.9551, + 80.8551, + 79.0551, + 77.1551, + 75.2551, + 73.4551, + 71.6551, + 69.9551, + 68.3551, + 66.8551, + 65.6551 + ] + } + }, + "EU10": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Electric multiple unit ", + "Values": { + "A": [ + 80.5497, + 81.4497, + 80.5497, + 82.2497, + 80.0497, + 79.7497, + 79.6497, + 81.0497, + 80.5497, + 81.3497, + 80.8497, + 79.5497, + 79.8497, + 86.7497, + 81.7497, + 82.7497, + 80.7497, + 78.0497, + 75.1497, + 72.1497, + 69.6497, + 66.7497, + 64.1497, + 61.8497 + ], + "B": [ + 84.8497, + 86.6497, + 83.4497, + 81.6497, + 80.5497, + 80.5497, + 79.5497, + 78.9497, + 78.3497, + 78.4497, + 78.0497, + 77.7497, + 77.3497, + 84.6497, + 79.5497, + 81.7497, + 79.8497, + 76.9497, + 74.1497, + 71.3497, + 68.6497, + 66.0497, + 63.5497, + 61.3497 + ] + } + } + }, + "IdlingSpeed": { + "EU0": { + "Default": "true", + "Reference": null, + "Description": "Empty traction", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "Values": { + "A": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ], + "B": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ] + } + }, + "EU3": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel locomotive (c. 800kW)", + "Values": { + "A": [ + 87.8613, + 83.7613, + 86.5613, + 88.5613, + 86.7613, + 86.7613, + 86.9613, + 88.7613, + 88.5613, + 89.6613, + 89.5613, + 93.5613, + 89.1613, + 89.0613, + 89.0613, + 88.0613, + 88.0613, + 86.3613, + 83.4613, + 80.4613, + 77.9613, + 75.0613, + 72.4613, + 70.1613 + ], + "B": [ + 92.1613, + 88.9613, + 89.4613, + 87.9613, + 87.2613, + 87.5613, + 86.8613, + 86.6613, + 86.3613, + 86.7613, + 86.7613, + 91.7613, + 86.6613, + 86.9613, + 86.8613, + 87.0613, + 87.1613, + 85.2613, + 82.4613, + 79.6613, + 76.9613, + 74.3613, + 71.8613, + 69.6613 + ] + } + }, + "EU4": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel locomotive (c. 2200kW)", + "Values": { + "A": [ + 89.4103, + 90.3103, + 103.1103, + 95.1103, + 93.3103, + 93.3103, + 93.5103, + 95.3103, + 95.1103, + 96.2103, + 96.1103, + 95.1103, + 95.7103, + 95.6103, + 93.3103, + 96.6103, + 87.7103, + 85.7103, + 87.0103, + 81.1103, + 79.3103, + 77.1103, + 75.2103, + 73.6103 + ], + "B": [ + 93.7103, + 95.5103, + 106.0103, + 94.5103, + 93.8103, + 94.1103, + 93.4103, + 93.2103, + 92.9103, + 93.3103, + 93.3103, + 93.3103, + 93.2103, + 93.5103, + 91.1103, + 95.6103, + 86.8103, + 84.6103, + 86.0103, + 80.3103, + 78.3103, + 76.4103, + 74.6103, + 73.1103 + ] + } + }, + "EU5": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/RENFE Dloco/1155kW", + "Values": { + "A": [ + 99.3003, + 103.2003, + 103.0003, + 102.0003, + 97.2003, + 97.2003, + 97.4003, + 99.2003, + 99.0003, + 100.1003, + 100.0003, + 98.0003, + 97.0003, + 94.4003, + 91.8003, + 88.3003, + 85.7003, + 83.5003, + 81.0003, + 78.5003, + 76.4003, + 74.0003, + 71.9003, + 70.1003 + ], + "B": [ + 103.6003, + 108.4003, + 105.9003, + 101.4003, + 97.7003, + 98.0003, + 97.3003, + 97.1003, + 96.8003, + 97.2003, + 97.2003, + 96.2003, + 94.5003, + 92.3003, + 89.6003, + 87.3003, + 84.8003, + 82.4003, + 80.0003, + 77.7003, + 75.4003, + 73.3003, + 71.3003, + 69.6003 + ] + } + }, + "EU6": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/NS6400 Dloco/1180kW", + "Values": { + "A": [ + 82.9836, + 93.8836, + 88.6836, + 83.6836, + 76.8836, + 76.8836, + 77.0836, + 78.8836, + 78.6836, + 79.7836, + 79.6836, + 78.6836, + 79.2836, + 79.1836, + 79.1836, + 78.1836, + 75.1836, + 72.4836, + 69.5836, + 66.5836, + 64.0836, + 61.1836, + 58.5836, + 56.2836 + ], + "B": [ + 87.2836, + 99.0836, + 91.5836, + 83.0836, + 77.3836, + 77.6836, + 76.9836, + 76.7836, + 76.4836, + 76.8836, + 76.8836, + 76.8836, + 76.7836, + 77.0836, + 76.9836, + 77.1836, + 74.2836, + 71.3836, + 68.5836, + 65.7836, + 63.0836, + 60.4836, + 57.9836, + 55.7836 + ] + } + }, + "EU7": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel loc/TKOJ JT42CWR/Class66/2200kW", + "Values": { + "A": [ + 92.432, + 88.332, + 87.132, + 92.132, + 90.332, + 90.332, + 90.532, + 92.332, + 92.132, + 93.232, + 93.132, + 90.132, + 88.732, + 86.632, + 84.632, + 81.632, + 79.632, + 77.932, + 76.032, + 74.032, + 72.532, + 70.632, + 69.032, + 67.732 + ], + "B": [ + 96.732, + 93.532, + 90.032, + 91.532, + 90.832, + 91.132, + 90.432, + 90.232, + 89.932, + 90.332, + 90.332, + 88.332, + 86.232, + 84.532, + 82.432, + 80.632, + 78.732, + 76.832, + 75.032, + 73.232, + 71.532, + 69.932, + 68.432, + 67.232 + ] + } + }, + "EU8": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Diesel multiple unit", + "Values": { + "A": [ + 78.583, + 79.483, + 88.283, + 84.283, + 82.483, + 82.483, + 88.683, + 84.483, + 84.283, + 85.383, + 85.283, + 84.283, + 90.883, + 84.783, + 84.783, + 83.783, + 83.783, + 84.083, + 82.183, + 79.183, + 75.683, + 71.783, + 68.183, + 64.883 + ], + "B": [ + 82.883, + 84.683, + 91.183, + 83.683, + 82.983, + 83.283, + 88.583, + 82.383, + 82.083, + 82.483, + 82.483, + 82.483, + 88.383, + 82.683, + 82.583, + 82.783, + 82.883, + 82.983, + 81.183, + 78.383, + 74.683, + 71.083, + 67.583, + 64.383 + ] + } + }, + "EU9": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Electric locomotive", + "Values": { + "A": [ + 78.8551, + 84.7551, + 82.5551, + 85.5551, + 85.7551, + 87.7551, + 97.9551, + 91.7551, + 90.5551, + 95.6551, + 89.5551, + 86.5551, + 86.1551, + 90.0551, + 83.0551, + 80.0551, + 78.0551, + 76.3551, + 74.4551, + 72.4551, + 70.9551, + 69.0551, + 67.4551, + 66.1551 + ], + "B": [ + 83.1551, + 89.9551, + 85.4551, + 84.9551, + 86.2551, + 88.5551, + 97.8551, + 89.6551, + 88.3551, + 92.7551, + 86.7551, + 84.7551, + 83.6551, + 87.9551, + 80.8551, + 79.0551, + 77.1551, + 75.2551, + 73.4551, + 71.6551, + 69.9551, + 68.3551, + 66.8551, + 65.6551 + ] + } + }, + "EU10": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Electric multiple unit ", + "Values": { + "A": [ + 80.5497, + 81.4497, + 80.5497, + 82.2497, + 80.0497, + 79.7497, + 79.6497, + 81.0497, + 80.5497, + 81.3497, + 80.8497, + 79.5497, + 79.8497, + 86.7497, + 81.7497, + 82.7497, + 80.7497, + 78.0497, + 75.1497, + 72.1497, + 69.6497, + 66.7497, + 64.1497, + 61.8497 + ], + "B": [ + 84.8497, + 86.6497, + 83.4497, + 81.6497, + 80.5497, + 80.5497, + 79.5497, + 78.9497, + 78.3497, + 78.4497, + 78.0497, + 77.7497, + 77.3497, + 84.6497, + 79.5497, + 81.7497, + 79.8497, + 76.9497, + 74.1497, + 71.3497, + 68.6497, + 66.0497, + 63.5497, + 61.3497 + ] + } + } + }, + "AerodynamicNoise": { + "EU0": { + "Default": "true", + "Reference": "", + "Description": "Empty aerodynamic noise", + "V0": 0, + "Alpha": 0, + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "V0": 0, + "Alpha": 0, + "Values": { + "A": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "B": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "V0": "400", + "Alpha": "100", + "Values": { + "A": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ], + "B": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ] + } + }, + "EU3": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Aerodynamic noise given at 300 km/h", + "V0": "300", + "Alpha": "50", + "Values": { + "A": [ + 112.5778, + 113.1665, + 115.6758, + 117.385, + 115.2634, + 114.9727, + 114.882, + 116.3808, + 115.8696, + 116.2758, + 116.1758, + 115.1758, + 115.7758, + 115.6758, + 115.6758, + 114.6758, + 114.6758, + 114.9758, + 114.5449, + 113.0912, + 112.0857, + 110.6294, + 109.5758, + 108.8221 + ], + "B": [ + 36.7103, + 38.5103, + 39.0103, + 37.5103, + 36.8103, + 37.1103, + 36.4103, + 36.2103, + 35.9103, + 36.3103, + 36.3103, + 36.3103, + 36.2103, + 36.5103, + 36.4103, + 105.2103, + 110.3103, + 110.4103, + 105.6103, + 37.2103, + 37.5103, + 37.9103, + 38.4103, + 39.2103 + ] + } + }, + "SNCF1": { + "DescriptionA": "LW.0-1", + "DescriptionB": "LW.0-2", + "V0": 300, + "Alpha": 50, + "Reference": "SNCF Juin 2021", + "Values": { + "A": [ + 101.2, + 102.4, + 100.9, + 101.2, + 100.4, + 100.8, + 103.4, + 106.1, + 106.8, + 107.1, + 107.9, + 106.3, + 89.8, + 87.2, + 84.3, + 81.2, + 77.6, + 75, + 68.8, + 29.2, + -14, + -13.9, + -15.7, + -15.8 + ], + "B": [ + 110.2, + 111.3, + 112.6, + 113.7, + 112.7, + 111.1, + 111.1, + 110.2, + 110.8, + 111.1, + 111, + 109.4, + 107.3, + 106.1, + 100.6, + 97.7, + 91.6, + 65.1, + 13.8, + -7.8, + -7.6, + -7, + -13, + -13.7 + ] + } + } + } + }, + "Track": { + "TrackTransfer": { + "EU0": { + "Default": "true", + "Reference": null, + "Description": "Empty track transfer function", + "Sleeper": null, + "Railpad": null, + "Spectre": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "Sleeper": null, + "Railpad": null, + "Spectre": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "Sleeper": null, + "Railpad": null, + "Spectre": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ] + }, + "EU3": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Mono-block sleeper on soft rail pad", + "Sleeper": "Concrete mono-block", + "Railpad": "Soft", + "Spectre": [ + 53.3, + 59.3, + 67.2, + 75.9, + 79.2, + 81.8, + 84.2, + 88.6, + 91, + 94.5, + 97, + 99.2, + 104, + 107.1, + 108.3, + 108.5, + 109.7, + 110, + 110, + 110, + 110.3, + 110, + 110.1, + 110.6 + ] + }, + "EU4": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Mono-block sleeper on medium stiffness rail pad", + "Sleeper": "Concrete mono-block", + "Railpad": "Medium", + "Spectre": [ + 50.9, + 57.8, + 66.5, + 76.8, + 80.9, + 83.3, + 85.8, + 90, + 91.6, + 93.9, + 95.6, + 97.4, + 101.7, + 104.4, + 106, + 106.8, + 108.3, + 108.9, + 109.1, + 109.4, + 109.9, + 109.9, + 110.3, + 111 + ] + }, + "EU5": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Mono-block on hard rail pad", + "Sleeper": "Concrete mono-block", + "Railpad": "Stiff", + "Spectre": [ + 50.1, + 57.2, + 66.3, + 77.2, + 81.6, + 84, + 86.5, + 90.7, + 92.1, + 94.3, + 95.8, + 97, + 100.3, + 102.5, + 104.2, + 105.4, + 107.1, + 107.9, + 108.2, + 108.7, + 109.4, + 109.7, + 110.4, + 111.4 + ] + }, + "EU6": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Bi-block sleeper on soft rail pad", + "Sleeper": "Concrete bi-block", + "Railpad": "Soft", + "Spectre": [ + 50.9, + 56.6, + 64.3, + 72.3, + 75.4, + 78.5, + 81.8, + 86.6, + 89.1, + 91.9, + 94.5, + 97.5, + 104, + 107.9, + 108.9, + 108.8, + 109.8, + 110.2, + 110.1, + 110.1, + 110.3, + 109.9, + 110, + 110.4 + ] + }, + "EU7": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Bi-block sleeper on medium stiffness rail pad", + "Sleeper": "Concrete bi-block", + "Railpad": "Medium", + "Spectre": [ + 50, + 56.1, + 64.1, + 72.5, + 75.8, + 79.1, + 83.6, + 88.7, + 89.6, + 89.7, + 90.6, + 93.8, + 100.6, + 104.7, + 106.3, + 107.1, + 108.8, + 109.3, + 109.4, + 109.7, + 110, + 109.8, + 110, + 110.5 + ] + }, + "EU8": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Bi-block sleeper on hard rail pad", + "Sleeper": "Concrete bi-block", + "Railpad": "Stiff", + "Spectre": [ + 49.8, + 55.9, + 64, + 72.5, + 75.9, + 79.4, + 84.4, + 89.7, + 90.2, + 90.2, + 90.8, + 93.1, + 97.9, + 101.1, + 103.4, + 105.4, + 107.7, + 108.5, + 108.7, + 109.1, + 109.6, + 109.6, + 109.9, + 110.6 + ] + }, + "EU9": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Wooden sleepers", + "Sleeper": "Wood", + "Railpad": null, + "Spectre": [ + 44, + 51, + 59.9, + 70.8, + 75.1, + 76.9, + 77.2, + 80.9, + 85.3, + 92.5, + 97, + 98.7, + 102.8, + 105.4, + 106.5, + 106.4, + 107.5, + 108.1, + 108.4, + 108.7, + 109.1, + 109.1, + 109.5, + 110.2 + ] + }, + "EU10": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Direct fastening on bridges", + "Sleeper": null, + "Railpad": null, + "Spectre": [ + 75.4, + 77.4, + 81.4, + 87.1, + 88.0, + 89.7, + 83.4, + 87.7, + 89.8, + 97.5, + 99.0, + 100.8, + 104.9, + 111.8, + 113.9, + 115.5, + 114.9, + 118.2, + 118.3, + 118.4, + 118.9, + 117.5, + 117.9, + 118.6 + ] + }, + "SNCF1": { + "Description": "Traverse-monobloc-sur-semelle-souple", + "Reference": "SNCF Juin 2021", + "Spectre": [ + 42.1, + 45.3, + 49.4, + 53.9, + 59.3, + 66.1, + 74.5, + 80.6, + 80.7, + 79.6, + 83, + 90.3, + 98.8, + 101.6, + 101.9, + 103.6, + 104.9, + 105.8, + 106.7, + 107.6, + 108.5, + 108.2, + 108.3, + 108.8 + ] + }, + "SNCF2": { + "Description": "Traverse-monobloc-sur-semelle-de-rigite-moyenne", + "Reference": "SNCF Juin 2021", + "Spectre": [ + 34.6, + 40.9, + 47.4, + 52.9, + 58.8, + 65.3, + 72.7, + 77.4, + 81.4, + 83.3, + 83.9, + 88.5, + 97.5, + 101.4, + 103, + 103.8, + 105.3, + 105.9, + 106.1, + 106.4, + 106.9, + 106.9, + 107.3, + 108 + ] + }, + "SNCF3": { + "Description": "Traverse-monobloc-sur-semelle-ri-ge", + "Reference": "SNCF Juin 2021", + "Spectre": [ + 32.5, + 39.4, + 46.6, + 53.2, + 59.1, + 65.5, + 72.3, + 79.1, + 86.2, + 89.3, + 87.9, + 88.5, + 94.4, + 98.4, + 99.1, + 102.6, + 103.8, + 104.6, + 104.9, + 105.4, + 106.1, + 106.4, + 107.1, + 108.1 + ] + }, + "SNCF4": { + "Description": "Traverse-bibloc-sur-semelle-souple", + "Reference": "SNCF Juin 2021", + "Spectre": [ + 29.2, + 37, + 45, + 52.3, + 59.8, + 65.6, + 70.8, + 73.4, + 76.7, + 82, + 85.5, + 90.4, + 99.1, + 102.4, + 103, + 104.7, + 105.3, + 105.3, + 105.3, + 105.3, + 105.3, + 105.3, + 105.3, + 105.3 + ] + }, + "SNCF5": { + "Description": "Traverse-bibloc-sur-semelle-de-rigite-moyenne", + "Reference": "SNCF Juin 2021", + "Spectre": [ + 34.4, + 41, + 47.7, + 53.2, + 59.4, + 64.5, + 70, + 75.7, + 80.3, + 82.6, + 84.7, + 89.1, + 98.1, + 102.5, + 104.3, + 105.1, + 106.8, + 107.3, + 107.4, + 107.7, + 108, + 107.8, + 108, + 108.5 + ] + }, + "SNCF6": { + "Description": "Traverse-bibloc-sur-semelle-ri-ge", + "Reference": "SNCF Juin 2021", + "Spectre": [ + 14.7, + 26.3, + 38.4, + 49.1, + 60.1, + 64.7, + 68.6, + 73.9, + 80.5, + 87, + 88.5, + 85.2, + 90.1, + 97, + 98.5, + 101.1, + 103, + 103.5, + 103.7, + 104.1, + 104.6, + 104.6, + 104.9, + 105.6 + ] + }, + "SNCF7": { + "Description": "Traverse-en-bois", + "Reference": "SNCF Juin 2021", + "Spectre": [ + 44, + 51, + 59.9, + 65.4, + 70.6, + 74.7, + 79.3, + 83.3, + 86.7, + 89.6, + 92.4, + 98.7, + 106.1, + 109.5, + 111.9, + 113.2, + 113, + 112.9, + 112.8, + 112.7, + 112.6, + 112.6, + 112.6, + 112.6 + ] + }, + "SNCF8": { + "Description": "Fixation-directe-sur-les-ponts-métalliques-(pose-ans-ballast)", + "Reference": "SNCF Fevrier 2022", + "Spectre": [ + 91.4, + 92.7, + 95.8, + 101.2, + 100.5, + 101.2, + 101.4, + 102.5, + 102.6, + 103.4, + 103.4, + 107.3, + 111.0, + 111.4, + 109.3, + 107.4, + 107.4, + 107.1, + 106.4, + 104.1, + 100.7, + 94.4, + 93.2, + 91.7 + ] + } + }, + "SuperstructureTransfer": { + "EU0": { + "Default": "true", + "Reference": "", + "Description": "Empty superstructure transfer function", + "Spectre": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "Spectre": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "Spectre": [ + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 140 + ] + }, + "EU3": { + "Default": "true", + "Reference": "CNOSSOS", + "Description": "CNOSSOS-EU Default", + "Spectre": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "RailRoughness": { + "EU0": { + "Default": "true", + "Reference": "", + "Description": "Empty rail roughness", + "RoughnessCode": "", + "Values": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "RoughnessCode": "Well maintained and very smooth", + "Values": [ + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15, + -15 + ] + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "RoughnessCode": "Not maintained and bad condition", + "Values": [ + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22, + 22 + ] + }, + "EU3": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "EN ISO 3095 2013", + "RoughnessCode": "Well maintained and very smooth", + "Values": [ + 17.1, + 17.1, + 17.1, + 17.1, + 17.1, + 17.1, + 17.1, + 17.1, + 15.0, + 13.0, + 11.0, + 9.0, + 7.0, + 4.9, + 2.9, + 0.9, + -1.1, + -3.2, + -5.0, + -5.6, + -6.2, + -6.8, + -7.4, + -8.0, + -8.6, + -9.2, + -9.8, + -10.4, + -11.0, + -11.6, + -12.2, + -12.8, + -13.4, + -14.0, + -14.0 + ] + }, + "EU4": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Average network", + "RoughnessCode": "Normally maintained smooth", + "Values": [ + 35.0, + 31.0, + 28.0, + 25.0, + 23.0, + 20.0, + 17.0, + 13.5, + 10.5, + 9.0, + 6.5, + 5.5, + 5.0, + 3.5, + 2.0, + 0.1, + -0.2, + -0.3, + -0.8, + -3.0, + -5.0, + -7.0, + -8.0, + -9.0, + -10.0, + -12.0, + -13.0, + -14.0, + -15.0, + -16.0, + -17.0, + -18.0, + -19.0, + -19.0, + -19.0 + ] + }, + "SNCF1": { + "Description": "Lignes-Classiques", + "Reference": "SNCF Juin 2021", + "Values": [ + 17.1, + 17.1, + 17.1, + 17.1, + 17.1, + 17.1, + 17.1, + 17.1, + 15, + 13, + 11, + 9, + 5.9, + 4.2, + 2, + -0.4, + -2.6, + -4.8, + -7.1, + -8.4, + -9.5, + -10.6, + -12, + -12.9, + -14, + -15.2, + -16.3, + -17.4, + -20.5, + -22.8, + -24.5, + -25.9, + -27.2, + -27.9, + -28.5 + ] + }, + "SNCF2": { + "Description": "LGV", + "Reference": "SNCF Juin 2021", + "Values": [ + 11.3, + 10.2, + 9.1, + 7.9, + 6.6, + 5.3, + 4, + 2.8, + 1.5, + 0.2, + -1, + -2.3, + -3.9, + -4.9, + -6.1, + -7.1, + -7.6, + -8.1, + -8.6, + -9.1, + -9.6, + -10, + -10.7, + -11.1, + -11.6, + -12.6, + -13.7, + -15.4, + -17.8, + -20, + -22.1, + -24.1, + -26.4, + -28.3, + -30.3 + ] + } + }, + "ImpactNoise": { + "EU0": { + "Default": "true", + "Reference": "", + "Description": "Empty impact noise", + "RoughnessCode": "", + "JoinDensity": null, + "JoinDensityDescription": "", + "Values": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "RoughnessCode": "Normally maintained smooth", + "JoinDensity": 0, + "JoinDensityDescription": "none", + "Values": [ + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40, + -40 + ] + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "RoughnessCode": "Normally maintained smooth", + "JoinDensity": 3, + "JoinDensityDescription": ">2 switches/joints/crossings/100m", + "Values": [ + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30, + 30 + ] + }, + "EU3": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "Single switch/joint/crossing/100m", + "RoughnessCode": "Normally maintained smooth", + "JoinDensity": 1, + "JoinDensityDescription": "single switch/joint/crossing/100m", + "Values": [ + 22.0, + 22.0, + 22.0, + 22.0, + 22.0, + 20.0, + 16.0, + 15.0, + 14.0, + 15.0, + 14.0, + 12.0, + 11.0, + 10.0, + 9.0, + 8.0, + 6.0, + 3.0, + 2.0, + -3.0, + -8.0, + -13.0, + -17.0, + -19.0, + -22.0, + -25.0, + -26.0, + -32.0, + -35.0, + -40.0, + -43.0, + -45.0, + -47.0, + -49.0, + -50.0 + ] + }, + "SNCF1": { + "Description": "Aiguillage/joint/croisement/100m", + "Reference": "SNCF Juin 2021", + "Values": [ + 18.0, + 18.0, + 18.0, + 18.0, + 18.0, + 16.0, + 12.0, + 11.0, + 10.0, + 11.0, + 10.0, + 8.0, + 7.0, + 6.0, + 5.0, + 4.0, + 2.0, + -1.0, + -2.0, + -7.0, + -12.0, + -17.0, + -21.0, + -23.0, + -26.0, + -29.0, + -30.0, + -36.0, + -39.0, + -44.0, + -47.0, + -49.0, + -51.0, + -53.0, + -54.0 + ] + } + }, + "BridgeConstant": { + "EU0": { + "Default": "true", + "Reference": "", + "Description": "Empty bridge constant", + "Value": 0 + }, + "EU1": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "min", + "Value": 0 + }, + "EU2": { + "Default": "true", + "Reference": "IMAGINE", + "Description": "max", + "Value": 9 + }, + "EU3": { + "Default": "true", + "Reference": "CNOSSOS", + "Description": "Predominantly concrete or masonry bridges with any trackform", + "Values": [ + 85.2, + 87.1, + 91.0, + 94.0, + 94.4, + 96.0, + 92.5, + 96.7, + 97.4, + 99.4, + 100.7, + 102.5, + 107.1, + 109.8, + 112.0, + 107.2, + 106.8, + 107.3, + 99.3, + 91.4, + 86.9, + 79.7, + 75.1, + 70.8 + ] + }, + "EU4": { + "Default": "true", + "Reference": "CNOSSOS", + "Description": "Predominantly steel bridges with ballasted track ", + "Values": [ + 90.1, + 92.1, + 96.0, + 99.5, + 99.9, + 101.5, + 99.6, + 103.8, + 104.5, + 106.5, + 107.8, + 109.6, + 116.1, + 118.8, + 120.9, + 109.5, + 109.1, + 109.6, + 102.0, + 94.1, + 89.6, + 83.6, + 79.0, + 74.7 + ] + }, + "SNCF1": { + "Description": "Tout-type-de-pont-hors-ponts-metalliques-avec-voies-non-ballastees", + "Reference": "SNCF Juin 2021", + "Values": 0 + }, + "SNCF2": { + "Description": "Ponts-metalliques-avec-voies-non-ballastees", + "Reference": "SNCF Juin 2021", + "Values": 5 + } + } + } +} \ No newline at end of file diff --git a/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayVehiclesCnossos.json b/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayVehiclesCnossos.json index 728885fd3..647d6102e 100644 --- a/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayVehiclesCnossos.json +++ b/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayVehiclesCnossos.json @@ -1,1621 +1,1621 @@ { - "EU1": { - "Description": "TestTrain EU", - "Reference": "Test 11/2022", - "Vmax": 300, - "Length": 200.19, - "TrailerBogieBraking": "Disques-garniture-frittee", - "MotorBogieBraking": "Semelle-composite", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 10, - "FirstSourcePosition": 10.0095, - "SourceSpacing": 20.019, - "NbAxlePerVeh": 2.6, - "RefAerodynamic": 1, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 1 - }, - "SNCF1": { - "Description": "TGV-00-100-TGV-SE", - "Reference": "SNCF 25/02/2022", - "Vmax": 300, - "Length": 200.19, - "TrailerBogieBraking": "Disques-garniture-frittee", - "MotorBogieBraking": "Semelle-composite", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 10, - "FirstSourcePosition": 10.0095, - "SourceSpacing": 20.019, - "NbAxlePerVeh": 2.6, - "RefAerodynamic": 1, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 1 - }, - "SNCF2": { - "Description": "TGV200-600-700-TGV-Duplex-DASYE-TGV800-4700-TGV-2N2-TGV4300-TGV-Thalys-PBKATGV500-4500-TGV-R-TGV-Thalys-PBA-TGV4400-TGV-POS", - "Reference": "SNCF 25/02/2022", - "Vmax": 320, - "Length": 200.19, - "TrailerBogieBraking": "Disques", - "MotorBogieBraking": "Semelle-composite", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 910, - "ReflectingBarrierEffect": 1, - "NbCoach": 10, - "FirstSourcePosition": 10.0095, - "SourceSpacing": 20.019, - "NbAxlePerVeh": 2.6, - "RefAerodynamic": 1, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 1 - }, - "SNCF3": { - "Description": "TGV300-400-TGV-A", - "Vmax": 300, - "Length": 237.59, - "TrailerBogieBraking": "Disques", - "MotorBogieBraking": "Semelle-composite", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 12, - "FirstSourcePosition": 9.8996, - "SourceSpacing": 19.7992, - "NbAxlePerVeh": 2.5, - "RefAerodynamic": 1, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 1 - }, - "SNCF4": { - "Description": "TGV3200-TGV-TMST-Eurostar", - "Reference": "SNCF 25/02/2022", - "Vmax": 300, - "Length": 393.72, - "TrailerBogieBraking": "Disques", - "MotorBogieBraking": "Semelle-composite", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 20, - "FirstSourcePosition": 9.843, - "SourceSpacing": 19.686, - "NbAxlePerVeh": 2.4, - "RefAerodynamic": 1, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 1 - }, - "SNCF5": { - "Description": "A1A-A1A-68000", - "Reference": "SNCF 25/02/2022", - "Vmax": 130, - "Length": 18.01, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 950, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 9.005, - "SourceSpacing": 0, - "NbAxlePerVeh": 6, - "RefAerodynamic": 0, - "RefRoughness": 1, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 14 - }, - "SNCF6": { - "Description": "BB15000", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 17.48, - "TrailerBogieBraking": "Semelle-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1250, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 8.74, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 15 - }, - "SNCF7": { - "Description": "BB16500-BB16600-BB16700", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 14.4, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1110, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 7.2, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF8": { - "Description": "BB17000-BB17100", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 14.94, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1110, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 7.47, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF9": { - "Description": "BB22200-BB22300-BB22400", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 17.48, - "TrailerBogieBraking": "Semelle-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1250, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 8.74, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 15 - }, - "SNCF10": { - "Description": "BB25200", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 16.7, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1250, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 8.35, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF11": { - "Description": "BB25500-BB25600", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 14.7, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1110, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 7.35, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF12": { - "Description": "BB26000-BB26100-BB26200", - "Reference": "SNCF 25/02/2022", - "Vmax": 200, - "Length": 17.71, - "TrailerBogieBraking": "Semelle-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1250, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 8.855, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 15 - }, - "SNCF13": { - "Description": "BB27000-BB27100", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 19.72, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1150, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 9.86, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 15 - }, - "SNCF14": { - "Description": "BB36000-BB36300", - "Reference": "SNCF 25/02/2022", - "Vmax": 220, - "Length": 19.11, - "TrailerBogieBraking": "Disque-garniture-composite-+-semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1150, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 9.555, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 3, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 15 - }, - "SNCF15": { - "Description": "BB37000", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 19.72, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1150, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 9.86, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 15 - }, - "SNCF16": { - "Description": "BB61000-Vossloh-G-1206-BB", - "Reference": "SNCF 25/02/2022", - "Vmax": 100, - "Length": 14.7, - "TrailerBogieBraking": "Disque+semelles", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1000, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 7.35, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 3, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF17": { - "Description": "BB63500-BB64000-BB64700", - "Reference": "SNCF 25/02/2022", - "Vmax": 90, - "Length": 14.68, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1050, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 7.34, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 1, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 14 - }, - "SNCF18": { - "Description": "BB66000-BB66100-BB66200-BB66300", - "Reference": "SNCF 25/02/2022", - "Vmax": 120, - "Length": 14.89, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1100, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 7.445, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF19": { - "Description": "BB66400-BB66500", - "Reference": "SNCF 25/02/2022", - "Vmax": 120, - "Length": 14.97, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1100, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 7.486, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF20": { - "Description": "BB67000-BB67100-BB67300", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 17.09, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1150, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 8.545, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF21": { - "Description": "BB67200", - "Reference": "SNCF 25/02/2022", - "Vmax": 90, - "Length": 17.09, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1150, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 8.545, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF22": { - "Description": "BB67400-BB67500-BB67600", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 17.09, - "TrailerBogieBraking": "Semelle-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1250, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 8.545, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF23": { - "Description": "BB7200-BB7300-BB7400", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 17.48, - "TrailerBogieBraking": "Semelle-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1250, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 8.74, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 15 - }, - "SNCF24": { - "Description": "BB75000-BB75100-BB75300-BB75400", - "Reference": "SNCF 25/02/2022", - "Vmax": 120, - "Length": 20.28, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1150, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 10.14, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 15 - }, - "SNCF25": { - "Description": "BB8500-BB8600", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 14.9, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1110, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 7.45, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF26": { - "Description": "CC72000-CC72100", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 20.19, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1140, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 10.095, - "SourceSpacing": 0, - "NbAxlePerVeh": 6, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF27": { - "Description": "TBB64800", - "Reference": "SNCF 25/02/2022", - "Vmax": 80, - "Length": 11.39, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1050, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 5.695, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 1, - "RefTraction": 14 - }, - "SNCF28": { - "Description": "B81500-tricaisse-AGC-bimode", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 57.4, - "TrailerBogieBraking": "Disque-garniture-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 3, - "FirstSourcePosition": 9.5667, - "SourceSpacing": 19.1333, - "NbAxlePerVeh": 2.7, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 6 - }, - "SNCF29": { - "Description": "B81500-B82500-quadricaisse-AGC-bimode", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 72.8, - "TrailerBogieBraking": "Disque-garniture-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 9.1, - "SourceSpacing": 18.2, - "NbAxlePerVeh": 2.5, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 6 - }, - "SNCF30": { - "Description": "B83500-B84500-B85900-4-caisses-Regiolis", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 71.82, - "TrailerBogieBraking": "Disque-garniture-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 8.9775, - "SourceSpacing": 17.955, - "NbAxlePerVeh": 2.5, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 6 - }, - "SNCF31": { - "Description": "B83500-B84500-B85000-6-caisses-Regiolis", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 110, - "TrailerBogieBraking": "Disque-garniture-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 6, - "FirstSourcePosition": 9.1667, - "SourceSpacing": 18.3333, - "NbAxlePerVeh": 2.7, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 6 - }, - "SNCF32": { - "Description": "X4500-modernise", - "Reference": "SNCF 25/02/2022", - "Vmax": 120, - "Length": 43.48, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 860, - "TrailerWheelDiameter": 860, - "ReflectingBarrierEffect": 1, - "NbCoach": 2, - "FirstSourcePosition": 10.87, - "SourceSpacing": 21.74, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 1, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 9 - }, - "SNCF33": { - "Description": "X72500-X72600-X72700-bicaisse-X-TER", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 52.9, - "TrailerBogieBraking": "Disque-+-semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 2, - "FirstSourcePosition": 13.225, - "SourceSpacing": 26.45, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 3, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 7 - }, - "SNCF34": { - "Description": "X72500-X72600-X72700-tricaisse-X-TER", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 78.5, - "TrailerBogieBraking": "Disque-+-semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 3, - "FirstSourcePosition": 13.0833, - "SourceSpacing": 26.1667, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 3, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 7 - }, - "SNCF35": { - "Description": "X73500-X73600-X73700-X73800-73900-A-TER", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 28.9, - "TrailerBogieBraking": "Disque", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 14.45, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 3, - "RefTraction": 8 - }, - "SNCF36": { - "Description": "X76500-tricaisse-AGC", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 57.4, - "TrailerBogieBraking": "Disque-garniture-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 3, - "FirstSourcePosition": 9.5667, - "SourceSpacing": 19.1333, - "NbAxlePerVeh": 2.7, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 6 - }, - "SNCF37": { - "Description": "X76500-quadricaisse-AGC", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 72.8, - "TrailerBogieBraking": "Disque-garniture-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 9.1, - "SourceSpacing": 18.2, - "NbAxlePerVeh": 2.5, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 6 - }, - "SNCF38": { - "Description": "Z20500-Z20600-Z20700-Z20800-Z20900-Z21000-quadricaisse-Z2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 103.508, - "TrailerBogieBraking": "Disque-+-semelle-composite", - "MotorBogieBraking": "Semelle-frittee", - "MotorWheelDiameter": 1020, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 12.9385, - "SourceSpacing": 25.877, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 3 - }, - "SNCF39": { - "Description": "Z20500-Z20600-Z20700-Z20800-pentacaisse-Z2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 129.4, - "TrailerBogieBraking": "Disque-+-semelle-composite", - "MotorBogieBraking": "Semelle-frittee", - "MotorWheelDiameter": 1020, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 5, - "FirstSourcePosition": 12.94, - "SourceSpacing": 25.88, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 3 - }, - "SNCF40": { - "Description": "Z21500-Z21600-Z21700-ZTER", - "Reference": "SNCF 25/02/2022", - "Vmax": 200, - "Length": 79.2, - "TrailerBogieBraking": "Disque-garniture-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 3, - "FirstSourcePosition": 13.2, - "SourceSpacing": 26.4, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 4 - }, - "SNCF41": { - "Description": "Z22500-Z22600-pentacaisse-MI2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 112, - "TrailerBogieBraking": "Disque-garniture-composite", - "MotorBogieBraking": "Semelle-composite", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 5, - "FirstSourcePosition": 11.2, - "SourceSpacing": 22.4, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 4 - }, - "SNCF42": { - "Description": "Z23500-TER-2N-PG", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 52.5, - "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1020, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 2, - "FirstSourcePosition": 13.125, - "SourceSpacing": 26.25, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 3, - "RefTraction": 4 - }, - "SNCF43": { - "Description": "Z24500-Z24600-Z24700-Z24800-tricaisse-TER-2N-NG", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 81.1, - "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 3, - "FirstSourcePosition": 13.5167, - "SourceSpacing": 27.0333, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 4 - }, - "SNCF44": { - "Description": "Z26500-Z26600-quadricaisse-TER-2N-NG", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 107.5, - "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 13.4375, - "SourceSpacing": 26.875, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 4 - }, - "SNCF45": { - "Description": "Z26500-Z26600-pentacaisse-TER-2N-NG", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 133.9, - "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 920, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 5, - "FirstSourcePosition": 13.39, - "SourceSpacing": 26.78, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 4 - }, - "SNCF46": { - "Description": "Z27500-Z27600-Z27700-Z27800-Z27900-tricaisse-ZGC", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 57.4, - "TrailerBogieBraking": "Disque-garniture-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 3, - "FirstSourcePosition": 9.5667, - "SourceSpacing": 19.1333, - "NbAxlePerVeh": 2.7, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 3, - "RefTraction": 5 - }, - "SNCF47": { - "Description": "Z27500-Z27600-Z27700-Z27800-Z27900-quadricaisse-ZGC", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 72.8, - "TrailerBogieBraking": "Disque-garniture-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 9.1, - "SourceSpacing": 18.2, - "NbAxlePerVeh": 2.5, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 3, - "RefTraction": 5 - }, - "SNCF48": { - "Description": "Z50000-7-caisses-NAT", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 94.31, - "TrailerBogieBraking": "Disque-garniture-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 7, - "FirstSourcePosition": 6.7364, - "SourceSpacing": 13.4729, - "NbAxlePerVeh": 2.3, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 4 - }, - "SNCF49": { - "Description": "Z50000-8-caisses-NAT", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 112.5, - "TrailerBogieBraking": "Disque-garniture-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 8, - "FirstSourcePosition": 7.0313, - "SourceSpacing": 14.0625, - "NbAxlePerVeh": 2.25, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 4 - }, - "SNCF50": { - "Description": "Z51500-Z54500-Z54900-4-caisses-REGIOLIS", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 71.82, - "TrailerBogieBraking": "Disque-garniture-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 8.9775, - "SourceSpacing": 17.955, - "NbAxlePerVeh": 2.5, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 3, - "RefTraction": 5 - }, - "SNCF51": { - "Description": "Z51500-6-caisses-REGIOLIS", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 110, - "TrailerBogieBraking": "Disque-garniture-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 6, - "FirstSourcePosition": 9.1667, - "SourceSpacing": 18.3333, - "NbAxlePerVeh": 2.7, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 3, - "RefTraction": 5 - }, - "SNCF52": { - "Description": "Z31500-REGIOLIS-LEX", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 71.82, - "TrailerBogieBraking": "Disque-garniture-frittee", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 8.9775, - "SourceSpacing": 17.955, - "NbAxlePerVeh": 2.5, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 3, - "RefTraction": 5 - }, - "SNCF53": { - "Description": "Z55500-Z55600-Z55700-courte�Z56300-REGIO-2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 80.945, - "TrailerBogieBraking": "Disque", - "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 6, - "FirstSourcePosition": 6.7454, - "SourceSpacing": 13.4908, - "NbAxlePerVeh": 2.3, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 4 - }, - "SNCF54": { - "Description": "Z55500-Z55600-Z55700-courte2-REGIO-2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 82.695, - "TrailerBogieBraking": "Disque", - "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 6, - "FirstSourcePosition": 6.8913, - "SourceSpacing": 13.7825, - "NbAxlePerVeh": 2.3, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 4 - }, - "SNCF55": { - "Description": "Z55500-Z55600-Z55700-moyenne-REGIO-2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 94.975, - "TrailerBogieBraking": "Disque", - "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 7, - "FirstSourcePosition": 6.7839, - "SourceSpacing": 13.5679, - "NbAxlePerVeh": 2.3, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 4 - }, - "SNCF56": { - "Description": "Z55500-Z55600-Z55700-Z57000-longue-REGIO-2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 109.91, - "TrailerBogieBraking": "Disque", - "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 8, - "FirstSourcePosition": 6.8694, - "SourceSpacing": 13.7388, - "NbAxlePerVeh": 2.3, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 4 - }, - "SNCF57": { - "Description": "Z56500-Z56700-V200-intervilles-REGIO-2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 200, - "Length": 109.91, - "TrailerBogieBraking": "Disque", - "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 8, - "FirstSourcePosition": 6.8694, - "SourceSpacing": 13.7388, - "NbAxlePerVeh": 2.25, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 4 - }, - "SNCF58": { - "Description": "Z55500-Z55600-Z55700-extra-longue-REGIO-2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 135.375, - "TrailerBogieBraking": "Disque", - "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 10, - "FirstSourcePosition": 6.7688, - "SourceSpacing": 13.5375, - "NbAxlePerVeh": 2.2, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 4 - }, - "SNCF59": { - "Description": "Z56600-extra-longue-REGIO-2N-V200", - "Reference": "SNCF 25/02/2022", - "Vmax": 200, - "Length": 135.375, - "TrailerBogieBraking": "Disque", - "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", - "MotorWheelDiameter": 840, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 10, - "FirstSourcePosition": 6.7688, - "SourceSpacing": 13.5375, - "NbAxlePerVeh": 2.2, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 4 - }, - "SNCF60": { - "Description": "Z5600-Z5700-quadricaisse", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 98.76, - "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", - "MotorBogieBraking": "Semelle-frittee", - "MotorWheelDiameter": 1020, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "RefAerodynamic": 0, - "NbCoach": 4, - "FirstSourcePosition": 12.345, - "SourceSpacing": 24.69, - "NbAxlePerVeh": 4, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 3 - }, - "SNCF61": { - "Description": "Z5600-Z5700-pentacaisse", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 123.04, - "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", - "MotorBogieBraking": "Semelle-frittee", - "MotorWheelDiameter": 1020, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 5, - "FirstSourcePosition": 12.304, - "SourceSpacing": 24.608, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 3 - }, - "SNCF62": { - "Description": "Z5600-Z5700-hexacaisse", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 147.32, - "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", - "MotorBogieBraking": "Semelle-frittee", - "MotorWheelDiameter": 1020, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 6, - "FirstSourcePosition": 12.2767, - "SourceSpacing": 24.5533, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 3 - }, - "SNCF63": { - "Description": "Z6400-Z6500", - "Reference": "SNCF 25/02/2022", - "Vmax": 120, - "Length": 92.43, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1020, - "TrailerWheelDiameter": 800, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 11.5538, - "SourceSpacing": 23.1075, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 4, - "RefTransfer": 3, - "RefTraction": 2 - }, - "SNCF64": { - "Description": "Z7300-Z7500-Z9500-Z9600-Z11500-Z2", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 50.2, - "TrailerBogieBraking": "Disque-garniture-composite", - "MotorBogieBraking": "Semelle-frittee", - "MotorWheelDiameter": 1000, - "TrailerWheelDiameter": 890, - "ReflectingBarrierEffect": 1, - "NbCoach": 2, - "FirstSourcePosition": 12.55, - "SourceSpacing": 25.1, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 1, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 9 - }, - "SNCF65": { - "Description": "Z8100-Z8200-MI79", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 104.05, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 1020, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 13.0063, - "SourceSpacing": 26.0125, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 2 - }, - "SNCF66": { - "Description": "Z8800-Z8900-Z2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 98.76, - "TrailerBogieBraking": "Disque-garniture-composite-+-semelle-composite", - "MotorBogieBraking": "Semelle-frittee", - "MotorWheelDiameter": 1020, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 12.345, - "SourceSpacing": 24.69, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 3 - }, - "SNCF67": { - "Description": "U25500-Tram-Train-Avento", - "Reference": "SNCF 25/02/2022", - "Vmax": 100, - "Length": 36.678, - "TrailerBogieBraking": "Disque-garniture-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 660, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 5, - "FirstSourcePosition": 3.6678, - "SourceSpacing": 7.3356, - "NbAxlePerVeh": 1.6, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 2, - "RefTransfer": 4, - "RefTraction": 13 - }, - "SNCF68": { - "Description": "U52500-U53500-U53600-U53700-Tram-Train-Citadis-Dualis-�-TTNG", - "Reference": "SNCF 25/02/2022", - "Vmax": 100, - "Length": 42, - "TrailerBogieBraking": "Disque-garniture-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": 660, - "TrailerWheelDiameter": null, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 5.25, - "SourceSpacing": 10.5, - "NbAxlePerVeh": 2.5, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 2, - "RefTransfer": 4, - "RefTraction": 13 - }, - "SNCF69": { - "Description": "Voiture-V2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 160, - "Length": 26.4, - "TrailerBogieBraking": "Disque", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 13.2, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 4, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 11 - }, - "SNCF70": { - "Description": "Voiture-VB2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 24.28, - "TrailerBogieBraking": "Disque-+-Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 12.14, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 1, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 11 - }, - "SNCF71": { - "Description": "Voiture-VO2N-Voiture-VR2N", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 24.78, - "TrailerBogieBraking": "Disque-garniture-composite-+-semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 12.39, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 1, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 11 - }, - "SNCF72": { - "Description": "Voiture-freinee-composite-LUNEA-VSOE", - "Reference": "SNCF 25/02/2022", - "Vmax": 200, - "Length": 26.4, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 13.2, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 11 - }, - "SNCF73": { - "Description": "Voiture-freinee-fonte-CORAIL-VU-VTU-VSE", - "Reference": "SNCF 25/02/2022", - "Vmax": 200, - "Length": 26.4, - "TrailerBogieBraking": "Semelle-fonte-disques-garniture-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 13.2, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 1, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 12 - }, - "SNCF74": { - "Description": "Voiture-USI", - "Reference": "SNCF 25/02/2022", - "Vmax": 200, - "Length": 25.094, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 12.547, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 11 - }, - "SNCF75": { - "Description": "Rame-RIB-RIO-RRR", - "Reference": "SNCF 25/02/2022", - "Vmax": 140, - "Length": 99, - "TrailerBogieBraking": "Disque-garniture-composite+-semelle-frittee-ou-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 840, - "ReflectingBarrierEffect": 1, - "NbCoach": 4, - "FirstSourcePosition": 12.375, - "SourceSpacing": 24.75, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 5, - "RefTransfer": 2, - "RefTraction": 10 - }, - "SNCF76": { - "Description": "Wagon-FRET-PLAT-freine-composite-sans-chargement", - "Reference": "SNCF 25/02/2022", - "Vmax": 120, - "Length": 17, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 0, - "NbCoach": 1, - "FirstSourcePosition": 8.5, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 3, - "RefTransfer": 2, - "RefTraction": 10 - }, - "SNCF77": { - "Description": "Wagon-FRET-PLAT-freine-composite-sans-chargement", - "Reference": "SNCF 25/02/2022", - "Vmax": 120, - "Length": 17, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 0, - "NbCoach": 1, - "FirstSourcePosition": 8.5, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 1, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 10 - }, - "SNCF78": { - "Description": "Wagon-FRET-freine-composite", - "Reference": "SNCF 25/02/2022", - "Vmax": 120, - "Length": 17, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 8.5, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 10 - }, - "SNCF79": { - "Description": "Wagon-FRET-freine-fonte", - "Reference": "SNCF 25/02/2022", - "Vmax": 120, - "Length": 17, - "TrailerBogieBraking": "Semelle-fonte", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 8.5, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 1, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 10 - }, - "SNCF80": { - "Description": "Fourgons-&-porte-autos-freine-composite", - "Reference": "SNCF 25/02/2022", - "Vmax": 200, - "Length": 26.4, - "TrailerBogieBraking": "Semelle-composite", - "MotorBogieBraking": "-", - "MotorWheelDiameter": null, - "TrailerWheelDiameter": 920, - "ReflectingBarrierEffect": 1, - "NbCoach": 1, - "FirstSourcePosition": 13.2, - "SourceSpacing": 0, - "NbAxlePerVeh": 4, - "RefAerodynamic": 0, - "RefRoughness": 2, - "RefContact": 4, - "RefTransfer": 2, - "RefTraction": 10 - } + "EU1": { + "Description": "TestTrain EU", + "Reference": "Test 11/2022", + "Vmax": 300, + "Length": 200.19, + "TrailerBogieBraking": "Disques-garniture-frittee", + "MotorBogieBraking": "Semelle-composite", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 10, + "FirstSourcePosition": 10.0095, + "SourceSpacing": 20.019, + "NbAxlePerVeh": 2.6, + "RefAerodynamic": "EU1", + "RefRoughness": "EU4", + "RefContact": "EU5", + "RefTransfer": "EU2", + "RefTraction": "EU1" + }, + "SNCF1": { + "Description": "TGV-00-100-TGV-SE", + "Reference": "SNCF 25/02/2022", + "Vmax": 300, + "Length": 200.19, + "TrailerBogieBraking": "Disques-garniture-frittee", + "MotorBogieBraking": "Semelle-composite", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 10, + "FirstSourcePosition": 10.0095, + "SourceSpacing": 20.019, + "NbAxlePerVeh": 2.6, + "RefAerodynamic": "SNCF1", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF1" + }, + "SNCF2": { + "Description": "TGV200-600-700-TGV-Duplex-DASYE-TGV800-4700-TGV-2N2-TGV4300-TGV-Thalys-PBKATGV500-4500-TGV-R-TGV-Thalys-PBA-TGV4400-TGV-POS", + "Reference": "SNCF 25/02/2022", + "Vmax": 320, + "Length": 200.19, + "TrailerBogieBraking": "Disques", + "MotorBogieBraking": "Semelle-composite", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 910, + "ReflectingBarrierEffect": 1, + "NbCoach": 10, + "FirstSourcePosition": 10.0095, + "SourceSpacing": 20.019, + "NbAxlePerVeh": 2.6, + "RefAerodynamic": "SNCF1", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF1" + }, + "SNCF3": { + "Description": "TGV300-400-TGV-A", + "Vmax": 300, + "Length": 237.59, + "TrailerBogieBraking": "Disques", + "MotorBogieBraking": "Semelle-composite", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 12, + "FirstSourcePosition": 9.8996, + "SourceSpacing": 19.7992, + "NbAxlePerVeh": 2.5, + "RefAerodynamic": "SNCF1", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF1" + }, + "SNCF4": { + "Description": "TGV3200-TGV-TMST-Eurostar", + "Reference": "SNCF 25/02/2022", + "Vmax": 300, + "Length": 393.72, + "TrailerBogieBraking": "Disques", + "MotorBogieBraking": "Semelle-composite", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 20, + "FirstSourcePosition": 9.843, + "SourceSpacing": 19.686, + "NbAxlePerVeh": 2.4, + "RefAerodynamic": "SNCF1", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF1" + }, + "SNCF5": { + "Description": "A1A-A1A-68000", + "Reference": "SNCF 25/02/2022", + "Vmax": 130, + "Length": 18.01, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 950, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 9.005, + "SourceSpacing": 0, + "NbAxlePerVeh": 6, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF1", + "RefContact": "SNCF5", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF14" + }, + "SNCF6": { + "Description": "BB15000", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 17.48, + "TrailerBogieBraking": "Semelle-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1250, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 8.74, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF15" + }, + "SNCF7": { + "Description": "BB16500-BB16600-BB16700", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 14.4, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1110, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 7.2, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF8": { + "Description": "BB17000-BB17100", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 14.94, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1110, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 7.47, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF9": { + "Description": "BB22200-BB22300-BB22400", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 17.48, + "TrailerBogieBraking": "Semelle-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1250, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 8.74, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF15" + }, + "SNCF10": { + "Description": "BB25200", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 16.7, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1250, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 8.35, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF11": { + "Description": "BB25500-BB25600", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 14.7, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1110, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 7.35, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF12": { + "Description": "BB26000-BB26100-BB26200", + "Reference": "SNCF 25/02/2022", + "Vmax": 200, + "Length": 17.71, + "TrailerBogieBraking": "Semelle-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1250, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 8.855, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF15" + }, + "SNCF13": { + "Description": "BB27000-BB27100", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 19.72, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1150, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 9.86, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF15" + }, + "SNCF14": { + "Description": "BB36000-BB36300", + "Reference": "SNCF 25/02/2022", + "Vmax": 220, + "Length": 19.11, + "TrailerBogieBraking": "Disque-garniture-composite-+-semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1150, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 9.555, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF3", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF15" + }, + "SNCF15": { + "Description": "BB37000", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 19.72, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1150, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 9.86, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF15" + }, + "SNCF16": { + "Description": "BB61000-Vossloh-G-1206-BB", + "Reference": "SNCF 25/02/2022", + "Vmax": 100, + "Length": 14.7, + "TrailerBogieBraking": "Disque+semelles", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1000, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 7.35, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF3", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF17": { + "Description": "BB63500-BB64000-BB64700", + "Reference": "SNCF 25/02/2022", + "Vmax": 90, + "Length": 14.68, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1050, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 7.34, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF1", + "RefContact": "SNCF5", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF14" + }, + "SNCF18": { + "Description": "BB66000-BB66100-BB66200-BB66300", + "Reference": "SNCF 25/02/2022", + "Vmax": 120, + "Length": 14.89, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1100, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 7.445, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF19": { + "Description": "BB66400-BB66500", + "Reference": "SNCF 25/02/2022", + "Vmax": 120, + "Length": 14.97, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1100, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 7.486, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF20": { + "Description": "BB67000-BB67100-BB67300", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 17.09, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1150, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 8.545, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF21": { + "Description": "BB67200", + "Reference": "SNCF 25/02/2022", + "Vmax": 90, + "Length": 17.09, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1150, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 8.545, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF22": { + "Description": "BB67400-BB67500-BB67600", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 17.09, + "TrailerBogieBraking": "Semelle-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1250, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 8.545, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF23": { + "Description": "BB7200-BB7300-BB7400", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 17.48, + "TrailerBogieBraking": "Semelle-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1250, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 8.74, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF15" + }, + "SNCF24": { + "Description": "BB75000-BB75100-BB75300-BB75400", + "Reference": "SNCF 25/02/2022", + "Vmax": 120, + "Length": 20.28, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1150, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 10.14, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF15" + }, + "SNCF25": { + "Description": "BB8500-BB8600", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 14.9, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1110, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 7.45, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF26": { + "Description": "CC72000-CC72100", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 20.19, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1140, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 10.095, + "SourceSpacing": 0, + "NbAxlePerVeh": 6, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF27": { + "Description": "TBB64800", + "Reference": "SNCF 25/02/2022", + "Vmax": 80, + "Length": 11.39, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1050, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 5.695, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF1", + "RefTraction": "SNCF14" + }, + "SNCF28": { + "Description": "B81500-tricaisse-AGC-bimode", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 57.4, + "TrailerBogieBraking": "Disque-garniture-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 3, + "FirstSourcePosition": 9.5667, + "SourceSpacing": 19.1333, + "NbAxlePerVeh": 2.7, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF6" + }, + "SNCF29": { + "Description": "B81500-B82500-quadricaisse-AGC-bimode", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 72.8, + "TrailerBogieBraking": "Disque-garniture-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 9.1, + "SourceSpacing": 18.2, + "NbAxlePerVeh": 2.5, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF6" + }, + "SNCF30": { + "Description": "B83500-B84500-B85900-4-caisses-Regiolis", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 71.82, + "TrailerBogieBraking": "Disque-garniture-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 8.9775, + "SourceSpacing": 17.955, + "NbAxlePerVeh": 2.5, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF6" + }, + "SNCF31": { + "Description": "B83500-B84500-B85000-6-caisses-Regiolis", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 110, + "TrailerBogieBraking": "Disque-garniture-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 6, + "FirstSourcePosition": 9.1667, + "SourceSpacing": 18.3333, + "NbAxlePerVeh": 2.7, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF6" + }, + "SNCF32": { + "Description": "X4500-modernise", + "Reference": "SNCF 25/02/2022", + "Vmax": 120, + "Length": 43.48, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 860, + "TrailerWheelDiameter": 860, + "ReflectingBarrierEffect": 1, + "NbCoach": 2, + "FirstSourcePosition": 10.87, + "SourceSpacing": 21.74, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF1", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF9" + }, + "SNCF33": { + "Description": "X72500-X72600-X72700-bicaisse-X-TER", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 52.9, + "TrailerBogieBraking": "Disque-+-semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 2, + "FirstSourcePosition": 13.225, + "SourceSpacing": 26.45, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF3", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF7" + }, + "SNCF34": { + "Description": "X72500-X72600-X72700-tricaisse-X-TER", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 78.5, + "TrailerBogieBraking": "Disque-+-semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 3, + "FirstSourcePosition": 13.0833, + "SourceSpacing": 26.1667, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF3", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF7" + }, + "SNCF35": { + "Description": "X73500-X73600-X73700-X73800-73900-A-TER", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 28.9, + "TrailerBogieBraking": "Disque", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 14.45, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF8" + }, + "SNCF36": { + "Description": "X76500-tricaisse-AGC", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 57.4, + "TrailerBogieBraking": "Disque-garniture-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 3, + "FirstSourcePosition": 9.5667, + "SourceSpacing": 19.1333, + "NbAxlePerVeh": 2.7, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF6" + }, + "SNCF37": { + "Description": "X76500-quadricaisse-AGC", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 72.8, + "TrailerBogieBraking": "Disque-garniture-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 9.1, + "SourceSpacing": 18.2, + "NbAxlePerVeh": 2.5, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF6" + }, + "SNCF38": { + "Description": "Z20500-Z20600-Z20700-Z20800-Z20900-Z21000-quadricaisse-Z2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 103.508, + "TrailerBogieBraking": "Disque-+-semelle-composite", + "MotorBogieBraking": "Semelle-frittee", + "MotorWheelDiameter": 1020, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 12.9385, + "SourceSpacing": 25.877, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF3" + }, + "SNCF39": { + "Description": "Z20500-Z20600-Z20700-Z20800-pentacaisse-Z2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 129.4, + "TrailerBogieBraking": "Disque-+-semelle-composite", + "MotorBogieBraking": "Semelle-frittee", + "MotorWheelDiameter": 1020, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 5, + "FirstSourcePosition": 12.94, + "SourceSpacing": 25.88, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF3" + }, + "SNCF40": { + "Description": "Z21500-Z21600-Z21700-ZTER", + "Reference": "SNCF 25/02/2022", + "Vmax": 200, + "Length": 79.2, + "TrailerBogieBraking": "Disque-garniture-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 3, + "FirstSourcePosition": 13.2, + "SourceSpacing": 26.4, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF4" + }, + "SNCF41": { + "Description": "Z22500-Z22600-pentacaisse-MI2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 112, + "TrailerBogieBraking": "Disque-garniture-composite", + "MotorBogieBraking": "Semelle-composite", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 5, + "FirstSourcePosition": 11.2, + "SourceSpacing": 22.4, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF4" + }, + "SNCF42": { + "Description": "Z23500-TER-2N-PG", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 52.5, + "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1020, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 2, + "FirstSourcePosition": 13.125, + "SourceSpacing": 26.25, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF4" + }, + "SNCF43": { + "Description": "Z24500-Z24600-Z24700-Z24800-tricaisse-TER-2N-NG", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 81.1, + "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 3, + "FirstSourcePosition": 13.5167, + "SourceSpacing": 27.0333, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF4" + }, + "SNCF44": { + "Description": "Z26500-Z26600-quadricaisse-TER-2N-NG", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 107.5, + "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 13.4375, + "SourceSpacing": 26.875, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF4" + }, + "SNCF45": { + "Description": "Z26500-Z26600-pentacaisse-TER-2N-NG", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 133.9, + "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 920, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 5, + "FirstSourcePosition": 13.39, + "SourceSpacing": 26.78, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF4" + }, + "SNCF46": { + "Description": "Z27500-Z27600-Z27700-Z27800-Z27900-tricaisse-ZGC", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 57.4, + "TrailerBogieBraking": "Disque-garniture-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 3, + "FirstSourcePosition": 9.5667, + "SourceSpacing": 19.1333, + "NbAxlePerVeh": 2.7, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF5" + }, + "SNCF47": { + "Description": "Z27500-Z27600-Z27700-Z27800-Z27900-quadricaisse-ZGC", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 72.8, + "TrailerBogieBraking": "Disque-garniture-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 9.1, + "SourceSpacing": 18.2, + "NbAxlePerVeh": 2.5, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF5" + }, + "SNCF48": { + "Description": "Z50000-7-caisses-NAT", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 94.31, + "TrailerBogieBraking": "Disque-garniture-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 7, + "FirstSourcePosition": 6.7364, + "SourceSpacing": 13.4729, + "NbAxlePerVeh": 2.3, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF4" + }, + "SNCF49": { + "Description": "Z50000-8-caisses-NAT", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 112.5, + "TrailerBogieBraking": "Disque-garniture-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 8, + "FirstSourcePosition": 7.0313, + "SourceSpacing": 14.0625, + "NbAxlePerVeh": 2.25, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF4" + }, + "SNCF50": { + "Description": "Z51500-Z54500-Z54900-4-caisses-REGIOLIS", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 71.82, + "TrailerBogieBraking": "Disque-garniture-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 8.9775, + "SourceSpacing": 17.955, + "NbAxlePerVeh": 2.5, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF5" + }, + "SNCF51": { + "Description": "Z51500-6-caisses-REGIOLIS", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 110, + "TrailerBogieBraking": "Disque-garniture-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 6, + "FirstSourcePosition": 9.1667, + "SourceSpacing": 18.3333, + "NbAxlePerVeh": 2.7, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF5" + }, + "SNCF52": { + "Description": "Z31500-REGIOLIS-LEX", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 71.82, + "TrailerBogieBraking": "Disque-garniture-frittee", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 8.9775, + "SourceSpacing": 17.955, + "NbAxlePerVeh": 2.5, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF5" + }, + "SNCF53": { + "Description": "Z55500-Z55600-Z55700-courte�Z56300-REGIO-2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 80.945, + "TrailerBogieBraking": "Disque", + "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 6, + "FirstSourcePosition": 6.7454, + "SourceSpacing": 13.4908, + "NbAxlePerVeh": 2.3, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF4" + }, + "SNCF54": { + "Description": "Z55500-Z55600-Z55700-courte2-REGIO-2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 82.695, + "TrailerBogieBraking": "Disque", + "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 6, + "FirstSourcePosition": 6.8913, + "SourceSpacing": 13.7825, + "NbAxlePerVeh": 2.3, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF4" + }, + "SNCF55": { + "Description": "Z55500-Z55600-Z55700-moyenne-REGIO-2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 94.975, + "TrailerBogieBraking": "Disque", + "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 7, + "FirstSourcePosition": 6.7839, + "SourceSpacing": 13.5679, + "NbAxlePerVeh": 2.3, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF4" + }, + "SNCF56": { + "Description": "Z55500-Z55600-Z55700-Z57000-longue-REGIO-2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 109.91, + "TrailerBogieBraking": "Disque", + "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 8, + "FirstSourcePosition": 6.8694, + "SourceSpacing": 13.7388, + "NbAxlePerVeh": 2.3, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF4" + }, + "SNCF57": { + "Description": "Z56500-Z56700-V200-intervilles-REGIO-2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 200, + "Length": 109.91, + "TrailerBogieBraking": "Disque", + "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 8, + "FirstSourcePosition": 6.8694, + "SourceSpacing": 13.7388, + "NbAxlePerVeh": 2.25, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF4" + }, + "SNCF58": { + "Description": "Z55500-Z55600-Z55700-extra-longue-REGIO-2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 135.375, + "TrailerBogieBraking": "Disque", + "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 10, + "FirstSourcePosition": 6.7688, + "SourceSpacing": 13.5375, + "NbAxlePerVeh": 2.2, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF4" + }, + "SNCF59": { + "Description": "Z56600-extra-longue-REGIO-2N-V200", + "Reference": "SNCF 25/02/2022", + "Vmax": 200, + "Length": 135.375, + "TrailerBogieBraking": "Disque", + "MotorBogieBraking": "2-essieux-fontes-+-semelle-composite", + "MotorWheelDiameter": 840, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 10, + "FirstSourcePosition": 6.7688, + "SourceSpacing": 13.5375, + "NbAxlePerVeh": 2.2, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF4" + }, + "SNCF60": { + "Description": "Z5600-Z5700-quadricaisse", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 98.76, + "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", + "MotorBogieBraking": "Semelle-frittee", + "MotorWheelDiameter": 1020, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "RefAerodynamic": "SNCF0", + "NbCoach": 4, + "FirstSourcePosition": 12.345, + "SourceSpacing": 24.69, + "NbAxlePerVeh": 4, + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF3" + }, + "SNCF61": { + "Description": "Z5600-Z5700-pentacaisse", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 123.04, + "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", + "MotorBogieBraking": "Semelle-frittee", + "MotorWheelDiameter": 1020, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 5, + "FirstSourcePosition": 12.304, + "SourceSpacing": 24.608, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF3" + }, + "SNCF62": { + "Description": "Z5600-Z5700-hexacaisse", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 147.32, + "TrailerBogieBraking": "Disque-garniture-composite-+-Semelle-composite", + "MotorBogieBraking": "Semelle-frittee", + "MotorWheelDiameter": 1020, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 6, + "FirstSourcePosition": 12.2767, + "SourceSpacing": 24.5533, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF3" + }, + "SNCF63": { + "Description": "Z6400-Z6500", + "Reference": "SNCF 25/02/2022", + "Vmax": 120, + "Length": 92.43, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1020, + "TrailerWheelDiameter": 800, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 11.5538, + "SourceSpacing": 23.1075, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF4", + "RefTransfer": "SNCF3", + "RefTraction": "SNCF2" + }, + "SNCF64": { + "Description": "Z7300-Z7500-Z9500-Z9600-Z11500-Z2", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 50.2, + "TrailerBogieBraking": "Disque-garniture-composite", + "MotorBogieBraking": "Semelle-frittee", + "MotorWheelDiameter": 1000, + "TrailerWheelDiameter": 890, + "ReflectingBarrierEffect": 1, + "NbCoach": 2, + "FirstSourcePosition": 12.55, + "SourceSpacing": 25.1, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF1", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF9" + }, + "SNCF65": { + "Description": "Z8100-Z8200-MI79", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 104.05, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 1020, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 13.0063, + "SourceSpacing": 26.0125, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF2" + }, + "SNCF66": { + "Description": "Z8800-Z8900-Z2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 98.76, + "TrailerBogieBraking": "Disque-garniture-composite-+-semelle-composite", + "MotorBogieBraking": "Semelle-frittee", + "MotorWheelDiameter": 1020, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 12.345, + "SourceSpacing": 24.69, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF3" + }, + "SNCF67": { + "Description": "U25500-Tram-Train-Avento", + "Reference": "SNCF 25/02/2022", + "Vmax": 100, + "Length": 36.678, + "TrailerBogieBraking": "Disque-garniture-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 660, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 5, + "FirstSourcePosition": 3.6678, + "SourceSpacing": 7.3356, + "NbAxlePerVeh": 1.6, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF2", + "RefTransfer": "SNCF4", + "RefTraction": "SNCF13" + }, + "SNCF68": { + "Description": "U52500-U53500-U53600-U53700-Tram-Train-Citadis-Dualis-�-TTNG", + "Reference": "SNCF 25/02/2022", + "Vmax": 100, + "Length": 42, + "TrailerBogieBraking": "Disque-garniture-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": 660, + "TrailerWheelDiameter": null, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 5.25, + "SourceSpacing": 10.5, + "NbAxlePerVeh": 2.5, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF2", + "RefTransfer": "SNCF4", + "RefTraction": "SNCF13" + }, + "SNCF69": { + "Description": "Voiture-V2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 160, + "Length": 26.4, + "TrailerBogieBraking": "Disque", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 13.2, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF4", + "RefContact": "SNCF5", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF11" + }, + "SNCF70": { + "Description": "Voiture-VB2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 24.28, + "TrailerBogieBraking": "Disque-+-Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 12.14, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF1", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF11" + }, + "SNCF71": { + "Description": "Voiture-VO2N-Voiture-VR2N", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 24.78, + "TrailerBogieBraking": "Disque-garniture-composite-+-semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 12.39, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF1", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF11" + }, + "SNCF72": { + "Description": "Voiture-freinee-composite-LUNEA-VSOE", + "Reference": "SNCF 25/02/2022", + "Vmax": 200, + "Length": 26.4, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 13.2, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF11" + }, + "SNCF73": { + "Description": "Voiture-freinee-fonte-CORAIL-VU-VTU-VSE", + "Reference": "SNCF 25/02/2022", + "Vmax": 200, + "Length": 26.4, + "TrailerBogieBraking": "Semelle-fonte-disques-garniture-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 13.2, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF1", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF12" + }, + "SNCF74": { + "Description": "Voiture-USI", + "Reference": "SNCF 25/02/2022", + "Vmax": 200, + "Length": 25.094, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 12.547, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF11" + }, + "SNCF75": { + "Description": "Rame-RIB-RIO-RRR", + "Reference": "SNCF 25/02/2022", + "Vmax": 140, + "Length": 99, + "TrailerBogieBraking": "Disque-garniture-composite+-semelle-frittee-ou-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 840, + "ReflectingBarrierEffect": 1, + "NbCoach": 4, + "FirstSourcePosition": 12.375, + "SourceSpacing": 24.75, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF5", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF10" + }, + "SNCF76": { + "Description": "Wagon-FRET-PLAT-freine-composite-sans-chargement", + "Reference": "SNCF 25/02/2022", + "Vmax": 120, + "Length": 17, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 0, + "NbCoach": 1, + "FirstSourcePosition": 8.5, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF3", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF10" + }, + "SNCF77": { + "Description": "Wagon-FRET-PLAT-freine-composite-sans-chargement", + "Reference": "SNCF 25/02/2022", + "Vmax": 120, + "Length": 17, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 0, + "NbCoach": 1, + "FirstSourcePosition": 8.5, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF1", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF10" + }, + "SNCF78": { + "Description": "Wagon-FRET-freine-composite", + "Reference": "SNCF 25/02/2022", + "Vmax": 120, + "Length": 17, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 8.5, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF10" + }, + "SNCF79": { + "Description": "Wagon-FRET-freine-fonte", + "Reference": "SNCF 25/02/2022", + "Vmax": 120, + "Length": 17, + "TrailerBogieBraking": "Semelle-fonte", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 8.5, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF1", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF10" + }, + "SNCF80": { + "Description": "Fourgons-&-porte-autos-freine-composite", + "Reference": "SNCF 25/02/2022", + "Vmax": 200, + "Length": 26.4, + "TrailerBogieBraking": "Semelle-composite", + "MotorBogieBraking": "-", + "MotorWheelDiameter": null, + "TrailerWheelDiameter": 920, + "ReflectingBarrierEffect": 1, + "NbCoach": 1, + "FirstSourcePosition": 13.2, + "SourceSpacing": 0, + "NbAxlePerVeh": 4, + "RefAerodynamic": "SNCF0", + "RefRoughness": "SNCF2", + "RefContact": "SNCF4", + "RefTransfer": "SNCF2", + "RefTraction": "SNCF10" + } } \ No newline at end of file diff --git a/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayCnossosEU_2020.json b/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/outdated/RailwayCnossosEU_2020.json similarity index 100% rename from noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayCnossosEU_2020.json rename to noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/outdated/RailwayCnossosEU_2020.json diff --git a/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayCnossosSNCF_2021.json b/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/outdated/RailwayCnossosSNCF_2021.json similarity index 100% rename from noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayCnossosSNCF_2021.json rename to noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/outdated/RailwayCnossosSNCF_2021.json diff --git a/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayVehiclesCnossos_2015.json b/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/outdated/RailwayVehiclesCnossos_2015.json similarity index 100% rename from noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayVehiclesCnossos_2015.json rename to noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/outdated/RailwayVehiclesCnossos_2015.json diff --git a/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayVehiclesNMPB.json b/noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/outdated/RailwayVehiclesNMPB.json similarity index 100% rename from noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/RailwayVehiclesNMPB.json rename to noisemodelling-emission/src/main/resources/org/noise_planet/noisemodelling/emission/railway/outdated/RailwayVehiclesNMPB.json diff --git a/noisemodelling-emission/src/test/java/org/noise_planet/noisemodelling/emission/railway/RailwayCnossosTest.java b/noisemodelling-emission/src/test/java/org/noise_planet/noisemodelling/emission/railway/RailwayCnossosTest.java index f50efd462..1b1ef97dd 100644 --- a/noisemodelling-emission/src/test/java/org/noise_planet/noisemodelling/emission/railway/RailwayCnossosTest.java +++ b/noisemodelling-emission/src/test/java/org/noise_planet/noisemodelling/emission/railway/RailwayCnossosTest.java @@ -33,9 +33,9 @@ public class RailwayCnossosTest { @Test public void testUnknownVehicle() throws IOException { - railwayCnossos.setVehicleDataFile("RailwayVehiclesNMPB.json"); + railwayCnossos.setVehicleDataFile("RailwayVehiclesCnossos.json"); railwayCnossos.setTrainSetDataFile("RailwayTrainsets.json"); - railwayCnossos.setRailwayDataFile("RailwayCnossosSNCF_2021.json"); + railwayCnossos.setRailwayDataFile("RailwayEmissionCnossos.json"); String vehCat = "notsupported"; @@ -45,10 +45,10 @@ public void testUnknownVehicle() throws IOException { double idlingTime = 0; int nTracks = 2; - int trackTransfer = 7; - int railRoughness = 3; - int impactNoise = 1; - int bridgeTransfert = 0; + String trackTransfer = "7"; + String railRoughness = "3"; + String impactNoise = "1"; + String bridgeTransfert = "0"; int curvature = 0; boolean isTunnel = false; @@ -69,11 +69,11 @@ public void testUnknownVehicle() throws IOException { @Test public void Test_Cnossos_Rail_emission_section_1() throws IOException { - railwayCnossos.setVehicleDataFile("RailwayVehiclesCnossos_2015.json"); + railwayCnossos.setVehicleDataFile("outdated/RailwayVehiclesCnossos_2015.json"); railwayCnossos.setTrainSetDataFile("RailwayTrainsets.json"); - railwayCnossos.setRailwayDataFile("RailwayCnossosEU_2020.json"); + railwayCnossos.setRailwayDataFile("outdated/RailwayCnossosEU_2020.json"); - double[] expectedValuesLWRolling = new double[]{46.6292393707431, 47.5930887825746, 49.4885539543655, 50.8452515062722, 48.2904168235536, 47.5599118826212, 48.3659880536885, 53.6850278385126, 55.1794804329062, 56.4435891375742, 57.3811010252223, 58.0623572653650, 59.8295159717300, 59.4546602463242, 56.5427214224336, 52.1790459841615, 54.5278138699040, 53.2809012600130, 51.1582349752733, 48.8021326510878, 49.2065949846659, 48.6821233578964, 48.6765663190977, 50.2184119171958}; + double[] expectedValuesLWRolling = new double[]{46.62923937074308, 47.5930887825746, 49.48855395436553, 50.84525150627218, 48.290416823553656, 47.55991120199147, 48.36598621415334, 53.685023895294904, 55.17947382327178, 56.44358069598965, 57.381090582936295, 58.06233085323542, 59.82942366487711, 59.45435581560096, 56.541564191934896, 52.173989709214666, 54.51129722944201, 53.2570463370446, 51.118153521942574, 48.73174211849708, 49.13517759611298, 48.60046539576308, 48.58746317902302, 50.14566621392022}; double[] expectedValuesLWTractionA = new double[]{46.8200805302231, 42.7200805302231, 40.5200805302231, 42.5200805302231, 40.7200805302231, 40.7200805302231, 40.9200805302231, 42.7200805302231, 42.5200805302231, 43.6200805302231, 43.5200805302231, 46.5200805302231, 43.1200805302231, 43.0200805302231, 43.0200805302231, 42.0200805302231, 42.0200805302231, 47.3200805302231, 40.4200805302231, 37.4200805302231, 34.9200805302231, 32.0200805302231, 29.4200805302231, 27.1200805302231}; double[] expectedValuesLWTractionB = new double[]{51.1200805302231, 47.9200805302231, 43.4200805302231, 41.9200805302231, 41.2200805302231, 41.5200805302231, 40.8200805302231, 40.6200805302231, 40.3200805302231, 40.7200805302231, 40.7200805302231, 44.7200805302231, 40.6200805302231, 40.9200805302231, 40.8200805302231, 41.0200805302231, 41.1200805302231, 46.2200805302231, 39.4200805302231, 36.6200805302231, 33.9200805302231, 31.3200805302231, 28.8200805302231, 26.6200805302231}; String[] typeNoise = new String[] {"ROLLING", "TRACTIONA", "TRACTIONB"}; @@ -88,10 +88,10 @@ public void Test_Cnossos_Rail_emission_section_1() throws IOException { // Initiate Section Train int nTracks = 2; - int trackTransfer = 7; - int railRoughness = 3; - int impactNoise = 1; - int bridgeTransfert = 0; + String trackTransfer = "7"; + String railRoughness = "3"; + String impactNoise = "1"; + String bridgeTransfert = "0"; int curvature = 0; boolean isTunnel = false; double vMaxInfra = 160; @@ -114,6 +114,7 @@ public void Test_Cnossos_Rail_emission_section_1() throws IOException { RailWayParameters lWRailWay = railwayCnossos.evaluate(vehicleParameters, trackParameters); + for(int i=0;i RoadCnossos.evaluate(rsParameters)); } } + + + + @Test + public void TGlobalBP() throws IOException { + double lv_speed = 50; + int lv_per_hour = 3747; + double mv_speed = 50; + int mv_per_hour = 0; + double hgv_speed = 50; + int hgv_per_hour = 479; + double wav_speed = 50; + int wav_per_hour = 0; + double wbv_speed = 50; + int wbv_per_hour = 0; + + double Temperature = 20; + String RoadSurface = "FR_R2"; + double Pm_stud = 0; + double Ts_stud = 0; + double Junc_dist = 0; + int Junc_type = 0; + double globalLw = 0; + for(int i = 0; i < FREQUENCIES.length; i++){ + RoadCnossosParameters rsParameters = new RoadCnossosParameters(lv_speed, mv_speed, hgv_speed, wav_speed, wbv_speed, lv_per_hour, mv_per_hour, hgv_per_hour, wav_per_hour, wbv_per_hour, FREQUENCIES[i], Temperature, RoadSurface, Ts_stud, Pm_stud, Junc_dist, Junc_type); + rsParameters.setFileVersion(1); + rsParameters.setWay(3); + double lw = RoadCnossos.evaluate(rsParameters); + globalLw += Utils.dbToW(A_WEIGHTING[i]+lw); + } + assertEquals(89.6, Utils.wToDba(globalLw), 0.1); + } } \ No newline at end of file diff --git a/noisemodelling-jdbc/pom.xml b/noisemodelling-jdbc/pom.xml index f02d84752..b4f740da2 100644 --- a/noisemodelling-jdbc/pom.xml +++ b/noisemodelling-jdbc/pom.xml @@ -10,7 +10,7 @@ org.noise-planet noisemodelling-parent - 5.0.2-SNAPSHOT + 6.0.1-SNAPSHOT ../pom.xml Compute sound propagation rays. diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/DelaunayReceiversMaker.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/DelaunayReceiversMaker.java index cf28ddf19..ab14de75e 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/DelaunayReceiversMaker.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/DelaunayReceiversMaker.java @@ -10,7 +10,7 @@ package org.noise_planet.noisemodelling.jdbc; -import org.h2gis.api.EmptyProgressVisitor; +import org.h2gis.api.ProgressVisitor; import org.h2gis.utilities.*; import org.h2gis.utilities.dbtypes.DBTypes; import org.h2gis.utilities.dbtypes.DBUtils; @@ -29,13 +29,11 @@ import org.noise_planet.noisemodelling.pathfinder.profilebuilder.Wall; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.tinfour.common.Vertex; import java.io.IOException; import java.sql.*; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import static org.h2gis.utilities.GeometryTableUtilities.getGeometryColumnNames; @@ -48,10 +46,10 @@ */ public class DelaunayReceiversMaker extends GridMapMaker { private static final int BATCH_MAX_SIZE = 100; - private Logger logger = LoggerFactory.getLogger(DelaunayReceiversMaker.class); + private final Logger logger = LoggerFactory.getLogger(DelaunayReceiversMaker.class); private double roadWidth = 2; private double maximumArea = 75; - private long nbreceivers = 0; + private long receiversCount = 0; private double receiverHeight = 1.6; private double buildingBuffer = 2; private String exceptionDumpFolder = ""; @@ -59,6 +57,13 @@ public class DelaunayReceiversMaker extends GridMapMaker { private double epsilon = 1e-6; private double geometrySimplificationDistance = 1; private boolean isoSurfaceInBuildings = false; + private boolean exportTrianglesGeometries = false; + + /** + * Do not evaluate a computation cell if there is no source geometries at least at x meters from the cell envelope + * It is ignored if it is NaN or if source table name is not provided + */ + private double minimalSourceGeometriesDistanceToComputeCell = Double.NaN; /** * Create constructor DelaunayReceiversMaker @@ -69,6 +74,20 @@ public DelaunayReceiversMaker(String buildingsTableName, String sourcesTableName super(buildingsTableName, sourcesTableName); } + /** + * @return True if triangle geometries are exported + */ + public boolean isExportTrianglesGeometries() { + return exportTrianglesGeometries; + } + + /** + * @param exportTrianglesGeometries Set true in order to export triangle geometries + */ + public void setExportTrianglesGeometries(boolean exportTrianglesGeometries) { + this.exportTrianglesGeometries = exportTrianglesGeometries; + } + /** * @return True if isosurface will be placed into buildings */ @@ -92,15 +111,38 @@ public void setIsoSurfaceInBuildings(boolean isoSurfaceInBuildings) { * @param triangleTableName The name of the database table where the triangles will be stored. * @throws SQLException Thrown if a database access error or other SQL-related error occurs. */ - public void run(Connection connection, String verticesTableName, String triangleTableName) throws SQLException { - initialize(connection, new EmptyProgressVisitor()); - + public void run(Connection connection, String verticesTableName, String triangleTableName, ProgressVisitor progressVisitor) throws SQLException { + initialize(connection); AtomicInteger pk = new AtomicInteger(0); - for(int i=0; i < getGridDim(); i++) { - for(int j=0; j < getGridDim(); j++) { + ProgressVisitor progressVisitorNM = progressVisitor.subProcess(getGridDim() * getGridDim()); + for(int i=0; i < getGridDim() && !progressVisitorNM.isCanceled(); i++) { + for(int j=0; j < getGridDim() && !progressVisitorNM.isCanceled(); j++) { + + if(!Double.isNaN(minimalSourceGeometriesDistanceToComputeCell) && !sourcesTableName.isEmpty()) { + // Check if there is a source near fence + Envelope cellEnvelope = getCellEnv(mainEnvelope, i, + j, getCellWidth(), getCellHeight()); + if(!hasSourcesNearEnvelope(connection, cellEnvelope, minimalSourceGeometriesDistanceToComputeCell)) { + if (verbose) { + int ij = i * gridDim + j + 1; + logger.info("Skip processing of cell {} / {} no source near cell", ij, gridDim * gridDim); + } + progressVisitorNM.endStep(); + continue; + } + } try { + if (verbose) { + int ij = i * gridDim + j + 1; + logger.info("Processing of cell {} / {}", ij, gridDim * gridDim); + } generateReceivers(connection, i, j, verticesTableName, triangleTableName, pk); + if(verbose) { + int ij = i * gridDim + j + 1; + logger.info("End processing of cell {} / {}", ij, gridDim * gridDim); + } + progressVisitorNM.endStep(); } catch (IOException | LayerDelaunayError ex) { throw new SQLException(ex); } @@ -261,7 +303,7 @@ private void feedDelaunay(List buildings, LayerDelaunay delaunayTool, * @param maxSrcDist Maximum propagation distance * @param minRecDist Minimal distance receiver-source * @param maximumArea Maximum area of triangles - * @throws LayerDelaunayError + * @throws LayerDelaunayError if an error occurs during the Delaunay triangulation process. */ public void computeDelaunay(LayerDelaunay cellMesh, Envelope mainEnvelope, int cellI, int cellJ, double maxSrcDist, Collection sources, @@ -307,7 +349,6 @@ public void computeDelaunay(LayerDelaunay cellMesh, minRecDist, buildingBuffer); // Process delaunay - logger.info("Begin delaunay"); cellMesh.setRetrieveNeighbors(false); // Add cell envelope if (maximumArea > 1) { @@ -325,17 +366,16 @@ public void computeDelaunay(LayerDelaunay cellMesh, } } cellMesh.processDelaunay(); - logger.info("End delaunay"); } /** * Retrieves the computation envelope based on data stored in the database tables. * @param connection the database connection. * @return the computation envelope containing the bounding box of the data stored in the specified tables. - * @throws SQLException + * @throws SQLException if a database access error occurs. */ @Override - protected Envelope getComputationEnvelope(Connection connection) throws SQLException { + public Envelope getComputationEnvelope(Connection connection) throws SQLException { Envelope computationEnvelope = new Envelope(); DBTypes dbTypes = DBUtils.getDBType(connection); if(!sourcesTableName.isEmpty() && JDBCUtilities.getRowCount(connection, sourcesTableName) > 0) { @@ -363,15 +403,20 @@ public void setGeometrySimplificationDistance(double geometrySimplificationDista public static void generateResultTable(Connection connection, String receiverTableName, String trianglesTableName, AtomicInteger receiverPK, List vertices, GeometryFactory geometryFactory, List triangles, int cellI, - int cellJ, int gridDim) throws SQLException { + int cellJ, int gridDim, boolean exportTrianglesGeometries) throws SQLException { + int srid = geometryFactory.getSRID(); if(!JDBCUtilities.tableExists(connection, receiverTableName)) { Statement st = connection.createStatement(); - st.execute("CREATE TABLE "+TableLocation.parse(receiverTableName)+"(pk serial NOT NULL, the_geom geometry not null, PRIMARY KEY (PK))"); + st.execute("CREATE TABLE "+TableLocation.parse(receiverTableName)+"(pk serial NOT NULL, the_geom geometry(POINTZ, "+srid+") not null, PRIMARY KEY (PK))"); } if(!JDBCUtilities.tableExists(connection, trianglesTableName)) { Statement st = connection.createStatement(); - st.execute("CREATE TABLE "+TableLocation.parse(trianglesTableName)+"(pk serial NOT NULL, the_geom geometry , PK_1 integer not null, PK_2 integer not null, PK_3 integer not null, cell_id integer not null, PRIMARY KEY (PK))"); + if(exportTrianglesGeometries) { + st.execute("CREATE TABLE " + TableLocation.parse(trianglesTableName) + "(pk serial NOT NULL, the_geom geometry(POLYGONZ, "+srid+") , PK_1 integer not null, PK_2 integer not null, PK_3 integer not null, cell_id integer not null, PRIMARY KEY (PK))"); + } else { + st.execute("CREATE TABLE " + TableLocation.parse(trianglesTableName) + "(pk serial NOT NULL, PK_1 integer not null, PK_2 integer not null, PK_3 integer not null, cell_id integer not null, PRIMARY KEY (PK))"); + } } int receiverPkOffset = receiverPK.get(); // Add vertices to receivers @@ -392,15 +437,22 @@ public static void generateResultTable(Connection connection, String receiverTab ps.executeBatch(); } // Add triangles - ps = connection.prepareStatement("INSERT INTO "+TableLocation.parse(trianglesTableName)+"(the_geom, PK_1, PK_2, PK_3, CELL_ID) VALUES (?, ?, ?, ?, ?);"); + if(exportTrianglesGeometries) { + ps = connection.prepareStatement("INSERT INTO " + TableLocation.parse(trianglesTableName) + "(the_geom, PK_1, PK_2, PK_3, CELL_ID) VALUES (?, ?, ?, ?, ?);"); + } else { + ps = connection.prepareStatement("INSERT INTO " + TableLocation.parse(trianglesTableName) + "(PK_1, PK_2, PK_3, CELL_ID) VALUES (?, ?, ?, ?);"); + } batchSize = 0; for(Triangle t : triangles) { - ps.setObject(1, geometryFactory.createPolygon(new Coordinate[]{vertices.get(t.getA()), - vertices.get(t.getB()), vertices.get(t.getC()), vertices.get(t.getA())})); - ps.setInt(2, t.getA() + receiverPkOffset); - ps.setInt(3, t.getC() + receiverPkOffset); - ps.setInt(4, t.getB() + receiverPkOffset); - ps.setInt(5, cellI * gridDim + cellJ); + int rowIndex = 1; + if(exportTrianglesGeometries) { + ps.setObject(rowIndex++, geometryFactory.createPolygon(new Coordinate[]{vertices.get(t.getA()), + vertices.get(t.getB()), vertices.get(t.getC()), vertices.get(t.getA())})); + } + ps.setInt(rowIndex++, t.getA() + receiverPkOffset); + ps.setInt(rowIndex++, t.getC() + receiverPkOffset); + ps.setInt(rowIndex++, t.getB() + receiverPkOffset); + ps.setInt(rowIndex, cellI * gridDim + cellJ); ps.addBatch(); batchSize++; if (batchSize >= BATCH_MAX_SIZE) { @@ -429,7 +481,7 @@ public void setEpsilon(double epsilon) { * @param fetchEnvelope Fetch envelope * @param doIntersection Truncate geometris * @param sourceGeometries List to feed - * @throws SQLException + * @throws SQLException if a database access error occurs */ public void fetchCellSource(Connection connection, Envelope fetchEnvelope, boolean doIntersection, List sourceGeometries) throws SQLException { @@ -477,12 +529,9 @@ public void fetchCellSource(Connection connection, Envelope fetchEnvelope, boole } } - public void generateReceivers(Connection connection, int cellI, int cellJ, String receiverTableName, String trianglesTableName, AtomicInteger receiverPK) throws SQLException, LayerDelaunayError, IOException { - - int ij = cellI * gridDim + cellJ + 1; - if(verbose) { - logger.info("Begin processing of cell " + ij + " / " + gridDim * gridDim); - } + public void generateReceivers(Connection connection, int cellI, int cellJ, String receiverTableName, + String trianglesTableName, AtomicInteger receiverPK) + throws SQLException, LayerDelaunayError, IOException { // Compute the first pass delaunay mesh // The first pass doesn't take account of additional // vertices of neighbor cells at the borders @@ -494,7 +543,7 @@ public void generateReceivers(Connection connection, int cellI, int cellJ, Strin List sourceDelaunayGeometries = new LinkedList<>(); - if(!sourcesTableName.isEmpty()) { + if(!sourcesTableName.isEmpty() && roadWidth > 0) { fetchCellSource(connection, cellEnvelope, true, sourceDelaunayGeometries); } @@ -506,6 +555,7 @@ public void generateReceivers(Connection connection, int cellI, int cellJ, Strin geometryFactory); LayerTinfour cellMesh = new LayerTinfour(); + cellMesh.setVerbose(verbose); cellMesh.setEpsilon(epsilon); cellMesh.setDumpFolder(exceptionDumpFolder); cellMesh.setMaxArea(maximumArea > 1 ? maximumArea : 0); @@ -538,27 +588,124 @@ public void generateReceivers(Connection connection, int cellI, int cellJ, Strin triangles = new ArrayList<>(cellMesh.getTriangles().size()); for (Triangle triangle : cellMesh.getTriangles()) { if (triangle.getAttribute() == 0) { - // place only triangles not associated to a building + // Keep only triangles that aren't associated with a building triangles.add(triangle); } } + // Keep only referenced vertices + Map verticesIndexCorrespondence = new HashMap<>(); // Tinfour vertex index to our vertex index + List filteredVertices = new ArrayList<>(vertices.size()); + for(Triangle triangle : triangles) { + for(int i = 0; i < 3; i++) { + updateTriangle(triangle, verticesIndexCorrespondence, i, vertices, filteredVertices); + } + } + vertices = filteredVertices; } else { triangles = cellMesh.getTriangles(); } - nbreceivers += vertices.size(); + receiversCount += vertices.size(); generateResultTable(connection, receiverTableName, trianglesTableName, receiverPK, vertices, geometryFactory, - triangles, cellI, cellJ, gridDim); + triangles, cellI, cellJ, gridDim, exportTrianglesGeometries); + } + + /** + * Insert into the new vertice list only vertices referenced in the triangles. If the vertex already exists + * in the mapping, its corresponding index is used; otherwise, the vertex is added to + * the vertices list and mapped to its new index. + * + * @param triangle The triangle to be updated, where vertex indices are modified as needed. + * @param tinFourIndexToListIndex A mapping of original vertex indices to their corresponding + * indices in the updated vertices list. + * @param cornerIndex The corner index of the triangle to update (0, 1, or 2). + * @param oldVerticesList The list of original vertices, from which new vertices are sourced if needed. + * @param vertices The list of updated vertices, where new vertices are added if they do not exist. + */ + private static void updateTriangle(Triangle triangle, Map tinFourIndexToListIndex, + int cornerIndex, List oldVerticesList, List vertices) { + // get the original vertex index + int tinFourVertexIndex = triangle.get(cornerIndex); + // find if this vertex is already in our vertices list + if(tinFourIndexToListIndex.containsKey(tinFourVertexIndex)) { + // use the vertex index inserted by a previous triangle + triangle.set(cornerIndex, tinFourIndexToListIndex.get(tinFourVertexIndex)); + } else { + // Not found, create a new vertex + vertices.add(oldVerticesList.get(tinFourVertexIndex)); + triangle.set(cornerIndex, vertices.size() - 1); + } } public double getRoadWidth() { return roadWidth; } + /** + * Set the buffer around the roads where no receivers will be placed. + * If this value is equal to 0m, the roads will not be integrated into the triangulation + * So you can exclude cells with {@link #setMinimalSourceGeometriesDistanceToComputeCell(double)} and not use the + * road buffer. + * @param roadWidth Road width in meters + */ public void setRoadWidth(double roadWidth) { this.roadWidth = roadWidth; } + /** + * @return Do not evaluate a computation cell if there is no source geometries at least at x meters from the cell envelope + */ + public double getMinimalSourceGeometriesDistanceToComputeCell() { + return minimalSourceGeometriesDistanceToComputeCell; + } + + /** + * Do not evaluate a computation cell if there is no source geometries at least at x meters from the cell envelope. + * Evaluated on {@link #run(Connection, String, String, ProgressVisitor)} + * It is ignored if it is NaN or if source table name is not provided or does not exists + * @param minimalSourceGeometriesDistanceToComputeCell Distance in meters + */ + public void setMinimalSourceGeometriesDistanceToComputeCell(double minimalSourceGeometriesDistanceToComputeCell) { + this.minimalSourceGeometriesDistanceToComputeCell = minimalSourceGeometriesDistanceToComputeCell; + } + + + + /** + * Check if there is at least one source geometry near the envelope + * @param connection Active connection + * @param fetchEnvelope Fetch envelope + * @param minimalDistance Minimal distance from envelope + * @return True if there is at least one source geometry near the envelope + * @throws SQLException if a database access error occurs + */ + public boolean hasSourcesNearEnvelope(Connection connection, Envelope fetchEnvelope, double minimalDistance) + throws SQLException { + DBTypes dbType = DBUtils.getDBType(connection.unwrap(Connection.class)); + TableLocation sourceTableIdentifier = TableLocation.parse(sourcesTableName, dbType); + List geomFields = getGeometryColumnNames(connection, sourceTableIdentifier); + if (geomFields.isEmpty()) { + throw new SQLException(String.format("The table %s does not exists or does not contain a geometry field", sourceTableIdentifier)); + } + String sourceGeomName = TableLocation.quoteIdentifier(geomFields.get(0)); + boolean hasSource = false; + try (PreparedStatement st = connection.prepareStatement( + "SELECT 1 FROM " + sourcesTableName + " WHERE " + + sourceGeomName + " && ST_EXPAND(?::geometry,?) AND ST_DISTANCE(" + sourceGeomName + ", ?::geometry) <= ? LIMIT 1")) { + st.setObject(1, geometryFactory.toGeometry(fetchEnvelope)); + st.setDouble(2, minimalDistance); + st.setObject(3, geometryFactory.toGeometry(fetchEnvelope)); + st.setDouble(4, minimalDistance); + try (ResultSet rs = st.executeQuery()) { + if (rs.next()) { + hasSource = true; + } + } + } + return hasSource; + } + + public double getMaximumArea() { return maximumArea; } @@ -575,7 +722,7 @@ public void setReceiverHeight(double receiverHeight) { this.receiverHeight = receiverHeight; } - public long getNbreceivers() { - return nbreceivers; + public long getReceiversCount() { + return receiversCount; } } diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/EmissionTableGenerator.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/EmissionTableGenerator.java index b61aafcaf..82c02147f 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/EmissionTableGenerator.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/EmissionTableGenerator.java @@ -47,7 +47,7 @@ public enum STANDARD_PERIOD {DAY, EVENING, NIGHT} * Cache table fields in upper case in Map * @param sourceFieldsCache map * @param rs table to load - * @throws SQLException If error + * @throws SQLException If error occurred */ public static void cacheFields(Map sourceFieldsCache, ResultSet rs) throws SQLException { if (sourceFieldsCache.isEmpty()) { @@ -244,13 +244,17 @@ public static double getSlope(Geometry g) { /** * Generate Train emission from train geometry tracks and train traffic - * @param connection - * @param railSectionTableName - * @param railTrafficTableName - * @param outputTable - * @throws SQLException + * @param connection Database connection + * @param railSectionTableName Table name of rail sections + * @param railTrafficTableName Table name of rail traffic + * @param outputTable Output table name + * @param frequencyPrepend Prepend to frequency columns (e.g. "HZ_") + * @param vehicleDataFile File path Url or resource filename (from org.noise_planet.noisemodelling.emission.railway package) for vehicle data configuration. + * @param trainSetDataFile File path Url or resource filename (from org.noise_planet.noisemodelling.emission.railway package) for train set data configuration. + * @param railwayEmissionDataFile File path Url or resource filename (from org.noise_planet.noisemodelling.emission.railway package) for railway metadata configuration. + * @throws SQLException If error occurred */ - public static void makeTrainLWTable(Connection connection, String railSectionTableName, String railTrafficTableName, String outputTable, String frequencyPrepend) throws SQLException { + public static void makeTrainLWTable(Connection connection, String railSectionTableName, String railTrafficTableName, String outputTable, String frequencyPrepend, String vehicleDataFile, String trainSetDataFile, String railwayEmissionDataFile) throws SQLException { // drop table LW_RAILWAY if exists and the create and prepare the table connection.createStatement().execute("drop table if exists " + outputTable); @@ -293,7 +297,12 @@ public static void makeTrainLWTable(Connection connection, String railSectionTab connection.createStatement().execute(createTableQuery.toString()); // Get Class to compute HZ - RailWayLWIterator railWayLWIterator = new RailWayLWIterator(connection,railSectionTableName, railTrafficTableName); + RailWayLWIterator railWayLWIterator; + try { + railWayLWIterator = new RailWayLWIterator(connection,railSectionTableName, railTrafficTableName, vehicleDataFile, trainSetDataFile, railwayEmissionDataFile); + } catch (IOException ex) { + throw new SQLException(ex); + } while (railWayLWIterator.hasNext()) { RailWayLWGeom railWayLWGeom = railWayLWIterator.next(); diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/GridMapMaker.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/GridMapMaker.java index cabdb3169..6ee2941da 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/GridMapMaker.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/GridMapMaker.java @@ -10,15 +10,12 @@ package org.noise_planet.noisemodelling.jdbc; -import org.h2gis.api.ProgressVisitor; import org.h2gis.utilities.TableLocation; import org.h2gis.utilities.dbtypes.DBTypes; import org.h2gis.utilities.dbtypes.DBUtils; import org.locationtech.jts.geom.*; import org.noise_planet.noisemodelling.jdbc.input.DefaultTableLoader; import org.noise_planet.noisemodelling.jdbc.utils.CellIndex; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.sql.*; @@ -38,11 +35,17 @@ public abstract class GridMapMaker { // Digital elevation model table. (Contains points or triangles) protected String demTable = ""; protected String sound_lvl_field = "DB_M"; - // True if Z of sound source and receivers are relative to the ground - protected boolean receiverHasAbsoluteZCoordinates = false; - protected boolean sourceHasAbsoluteZCoordinates = false; + /** True if Z of receivers geometry is the altitude (sea level) or false if Z is relative to the ground (relative to digital elevation model) + * When the propagation area will be prepared. All coordinates will be converted into altitude if necessary. + */ + protected boolean receiverHasSeaLevelZCoordinates = false; + /** True if Z of sources geometry is the altitude (sea level) or false if Z is relative to the ground (relative to digital elevation model) + * When the propagation area will be prepared. All coordinates will be converted into altitude if necessary. + */ + protected boolean sourceHasSeaLevelZCoordinates = false; protected double maximumPropagationDistance = 750; protected double maximumReflectionDistance = 100; + protected double closeReceiverReflectionWallDistance = 0; protected double gs = 0; // Soil areas are split by the provided size in order to reduce the propagation time protected double groundSurfaceSplitSideLength = 200; @@ -52,7 +55,6 @@ public abstract class GridMapMaker { public boolean verbose = true; protected boolean computeHorizontalDiffraction = true; protected boolean computeVerticalDiffraction = true; - protected GeometryFactory geometryFactory; // Initialised attributes @@ -134,14 +136,14 @@ public double getCellHeight() { return mainEnvelope.getHeight() / gridDim; } - abstract protected Envelope getComputationEnvelope(Connection connection) throws SQLException; + abstract public Envelope getComputationEnvelope(Connection connection) throws SQLException; /** * Fetch scene attributes, compute best computation cell size. * @param connection Active connection - * @throws java.sql.SQLException + * @throws java.sql.SQLException If some table are not found or parameters are invalid */ - public void initialize(Connection connection, ProgressVisitor progression) throws SQLException { + public void initialize(Connection connection) throws SQLException { if(soundReflectionOrder > 0 && maximumPropagationDistance < maximumReflectionDistance) { throw new SQLException(new IllegalArgumentException( "Maximum wall seeking distance cannot be superior than maximum propagation distance")); @@ -228,7 +230,7 @@ public String getSoilTableName() { * @return True if provided Z value are sea level (false for relative to ground level) */ public boolean isReceiverHasAbsoluteZCoordinates() { - return receiverHasAbsoluteZCoordinates; + return receiverHasSeaLevelZCoordinates; } /** @@ -236,21 +238,21 @@ public boolean isReceiverHasAbsoluteZCoordinates() { * @param receiverHasAbsoluteZCoordinates True if provided Z value are sea level (false for relative to ground level) */ public void setReceiverHasAbsoluteZCoordinates(boolean receiverHasAbsoluteZCoordinates) { - this.receiverHasAbsoluteZCoordinates = receiverHasAbsoluteZCoordinates; + this.receiverHasSeaLevelZCoordinates = receiverHasAbsoluteZCoordinates; } /** * @return True if provided Z value are sea level (false for relative to ground level) */ public boolean isSourceHasAbsoluteZCoordinates() { - return sourceHasAbsoluteZCoordinates; + return sourceHasSeaLevelZCoordinates; } /** * @param sourceHasAbsoluteZCoordinates True if provided Z value are sea level (false for relative to ground level) */ public void setSourceHasAbsoluteZCoordinates(boolean sourceHasAbsoluteZCoordinates) { - this.sourceHasAbsoluteZCoordinates = sourceHasAbsoluteZCoordinates; + this.sourceHasSeaLevelZCoordinates = sourceHasAbsoluteZCoordinates; } public boolean iszBuildings() { @@ -354,6 +356,22 @@ public void setMaximumReflectionDistance(double maximumReflectionDistance) { this.maximumReflectionDistance = maximumReflectionDistance; } + /** + * @return Maximum receiver-to-wall distance in meters below which reflection cut profiles can be ignored. + * A value of 0 means the optional filter is disabled. + */ + public double getCloseReceiverReflectionWallDistance() { + return closeReceiverReflectionWallDistance; + } + + /** + * @param closeReceiverReflectionWallDistance Maximum receiver-to-wall distance in meters below which + * reflection cut profiles can be ignored. A value of 0 disables the filter. + */ + public void setCloseReceiverReflectionWallDistance(double closeReceiverReflectionWallDistance) { + this.closeReceiverReflectionWallDistance = closeReceiverReflectionWallDistance; + } + /** * @return Sound reflection order. 0 order mean 0 reflection depth. * 2 means propagation of rays up to 2 collision with walls. diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/NoiseMapByReceiverMaker.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/NoiseMapByReceiverMaker.java index 23fac5926..8f2d442b3 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/NoiseMapByReceiverMaker.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/NoiseMapByReceiverMaker.java @@ -156,12 +156,22 @@ public void setProfilerThread(ProfilerThread profilerThread) { this.profilerThread = profilerThread; } + /** + * @param computeRaysOutFactory Factory to create output data handler for each cell + */ public void setComputeRaysOutFactory(IComputeRaysOutFactory computeRaysOutFactory) { this.computeRaysOutFactory = computeRaysOutFactory; } /** - * Do not call this method after {@link #initialize(Connection, ProgressVisitor)} has been called + * @return Factory to create an output data handler for each cell the default is {@link DefaultCutPlaneProcessing} + */ + public IComputeRaysOutFactory getComputeRaysOutFactory() { + return computeRaysOutFactory; + } + + /** + * Do not call this method after {@link #initialize(Connection)} has been called * @param tableLoader Object that generate scene for each sub-cell using database data */ public void setPropagationProcessDataFactory(TableLoader tableLoader) { @@ -175,10 +185,16 @@ public TableLoader getPropagationProcessDataFactory() { return tableLoader; } + /** + * @return Number of threads used for ray propagation, 0 means automatic detection of number of CPU cores + */ public int getThreadCount() { return threadCount; } + /** + * @param threadCount Number of threads used for ray propagation, 0 means automatic detection of number of CPU cores + */ public void setThreadCount(int threadCount) { this.threadCount = threadCount; } @@ -189,7 +205,8 @@ public void setThreadCount(int threadCount) { * @param cellIndex Computation area index * @param skipReceivers Do not process the receivers primary keys in this set and once included add the new receivers primary in it * @return Data input for cell evaluation - * @throws SQLException + * @throws SQLException SQL exception instance + * @throws IOException IO exception instance */ public SceneWithEmission prepareCell(Connection connection, CellIndex cellIndex, Set skipReceivers) throws SQLException, IOException { @@ -211,10 +228,10 @@ public SceneWithEmission prepareCell(Connection connection, CellIndex cellIndex, * Retrieves the computation envelope based on data stored in the database tables. * @param connection the database connection. * @return the computation envelope containing the bounding box of the data stored in the specified tables. - * @throws SQLException + * @throws SQLException if an SQL exception occurs while retrieving the envelope. */ @Override - protected Envelope getComputationEnvelope(Connection connection) throws SQLException { + public Envelope getComputationEnvelope(Connection connection) throws SQLException { DBTypes dbTypes = DBUtils.getDBType(connection); Envelope envelopeInternal = GeometryTableUtilities.getEnvelope(connection, TableLocation.parse(receiverTableName, dbTypes)).getEnvelopeInternal(); envelopeInternal.expandBy(maximumPropagationDistance); @@ -223,9 +240,9 @@ protected Envelope getComputationEnvelope(Connection connection) throws SQLExcep /** * Fetch all receivers and compute cells that contains receivers - * @param connection + * @param connection JDBC Connection * @return Cell index with number of receivers - * @throws SQLException + * @throws SQLException SQL exception instance */ public Map searchPopulatedCells(Connection connection) throws SQLException { if(mainEnvelope == null) { @@ -299,14 +316,6 @@ public CutPlaneVisitorFactory evaluateCell(Connection connection, CellIndex cell computeRays.setThreadCount(threadCount); } - if(!receiverHasAbsoluteZCoordinates) { - computeRays.makeReceiverRelativeZToAbsolute(); - } - - if(!sourceHasAbsoluteZCoordinates) { - computeRays.makeSourceRelativeZToAbsolute(); - } - computeRays.run(computeRaysOut); return computeRaysOut; @@ -322,12 +331,11 @@ public TableLoader getTableLoader() { /** * Initializes the noise map computation process. * @param connection Active connection - * @param progression - * @throws SQLException + * @throws SQLException if an SQL exception occurs during initialization. */ @Override - public void initialize(Connection connection, ProgressVisitor progression) throws SQLException { - super.initialize(connection, progression); + public void initialize(Connection connection) throws SQLException { + super.initialize(connection); tableLoader.initialize(connection, this); computeRaysOutFactory.initialize(connection, this); } @@ -336,7 +344,7 @@ public void initialize(Connection connection, ProgressVisitor progression) throw * Run NoiseModelling with provided parameters, return when computation is done */ public void run(Connection connection, ProgressVisitor progressLogger) throws SQLException { - initialize(connection, progressLogger); + initialize(connection); // Set of already processed receivers Set receivers = new HashSet<>(); @@ -351,6 +359,10 @@ public void run(Connection connection, ProgressVisitor progressLogger) throws SQ // Run ray propagation try { evaluateCell(connection, cellIndex, progressVisitor, receivers); + if(progressLogger.isCanceled()) { + // Computation has been canceled, exit the loop + break; + } } catch (IOException ex) { throw new SQLException(ex); } @@ -400,7 +412,7 @@ public interface IComputeRaysOutFactory { /** * Called before the first sub cell is being computed * @param progressLogger Main progression information, this method will not update the progression - * @throws SQLException + * @throws SQLException If an SQL exception occurs */ void start(ProgressVisitor progressLogger) throws SQLException; diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/NoiseMapDatabaseParameters.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/NoiseMapDatabaseParameters.java index 26db6284c..56e0ae60e 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/NoiseMapDatabaseParameters.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/NoiseMapDatabaseParameters.java @@ -45,10 +45,6 @@ public NoiseMapDatabaseParameters() { public enum ExportRaysMethods {TO_RAYS_TABLE, NONE} public ExportRaysMethods exportRaysMethod = ExportRaysMethods.NONE; - /** Cnossos revisions have multiple coefficients for road emission formulae - * this parameter will be removed when the final version of Cnossos will be published - */ - public int coefficientVersion = 2; // Output config @@ -115,17 +111,23 @@ public ExportRaysMethods getExportRaysMethod() { /** * Export rays in table (beware this could take a lot of storage space) or keep on memory or do not keep - * @param exportRaysMethod + * @param exportRaysMethod Export rays method */ public void setExportRaysMethod(ExportRaysMethods exportRaysMethod) { this.exportRaysMethod = exportRaysMethod; } + /** + * @param exportCnossosPathWithAttenuation With attenuation export also the json of the related cnossos path, for debugging purpose + */ public void setExportCnossosPathWithAttenuation(boolean exportCnossosPathWithAttenuation) { this.exportCnossosPathWithAttenuation = exportCnossosPathWithAttenuation; } + /** + * @return With attenuation export also the json of the related cnossos path, for debugging purpose + */ public boolean isKeepAbsorption() { return keepAbsorption; } @@ -138,18 +140,6 @@ public void setExportAttenuationMatrix(boolean exportAttenuationMatrix) { this.exportAttenuationMatrix = exportAttenuationMatrix; } - /** - * @param coefficientVersion Cnossos revisions have multiple coefficients for road emission formulae this parameter - * will be removed when the final version of Cnossos will be published - */ - public void setCoefficientVersion(int coefficientVersion) { - this.coefficientVersion = coefficientVersion; - } - - public int getCoefficientVersion() { - return coefficientVersion; - } - /** * Maximum result stack to be inserted in database * if the stack is full, the computation core is waiting @@ -174,6 +164,10 @@ public void setMaximumError(double maximumError) { this.maximumError = maximumError; } + /** + * @param mergeSources If true all sources contributions are merged into a single noise level per receiver. + * The source identifier is loosed in the output tables. + */ public void setMergeSources(boolean mergeSources) { this.mergeSources = mergeSources; } @@ -186,11 +180,16 @@ public String getRaysTable() { } /** + * @param raysTable Table name that contains rays dump (profile) */ public void setRaysTable(String raysTable) { this.raysTable = raysTable; } + /** + * @return If true all sources contributions are merged into a single noise level per receiver. + * The source identifier is loosed in the output tables. + */ public boolean isMergeSources() { return mergeSources; } diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/DefaultTableLoader.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/DefaultTableLoader.java index e431cd73e..3a60299ee 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/DefaultTableLoader.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/DefaultTableLoader.java @@ -34,6 +34,7 @@ import java.sql.*; import java.util.*; +import java.util.stream.Collectors; import static org.h2gis.utilities.GeometryTableUtilities.getGeometryColumnNames; @@ -79,24 +80,42 @@ public void insertTrainDirectivity() { * Initializes the NoiseMap parameters and attenuation data based on the input mode specified in the NoiseMap parameters. * @param connection the database connection to be used for initialization. * @param noiseMapByReceiverMaker the noise map by receiver maker object associated with the computation process. - * @throws SQLException + * @throws SQLException if a database access error occurs during initialization. */ @Override public void initialize(Connection connection, NoiseMapByReceiverMaker noiseMapByReceiverMaker) throws SQLException { this.noiseMapByReceiverMaker = noiseMapByReceiverMaker; + DBTypes dbType = DBUtils.getDBType(connection); SceneDatabaseInputSettings inputSettings = noiseMapByReceiverMaker.getSceneInputSettings(); if(inputSettings.inputMode == SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_GUESS) { // Check fields to find appropriate expected data - inputSettings.inputMode = SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_ATTENUATION; if(!inputSettings.sourcesEmissionTableName.isEmpty()) { List sourceFields = JDBCUtilities.getColumnNames(connection, noiseMapByReceiverMaker.getSourcesEmissionTableName()); + List periods = JDBCUtilities.getUniqueFieldValues(connection, inputSettings.sourcesEmissionTableName, TableLocation.capsIdentifier("period", dbType)).stream().map(String::toUpperCase).collect(Collectors.toList()); if(sourceFields.contains("LV_SPD")) { - inputSettings.inputMode = SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_TRAFFIC_FLOW; + if(periods.contains("D") && periods.contains("E") && periods.contains("N")) { + inputSettings.inputMode = SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_TRAFFIC_FLOW_DEN; + } else { + inputSettings.inputMode = SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_TRAFFIC_FLOW; + } } else { - inputSettings.inputMode = SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_LW; + if(periods.contains("D") && periods.contains("E") && periods.contains("N")) { + inputSettings.inputMode = SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_LW_DEN; + } else { + inputSettings.inputMode = SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_LW; + } } } else { - List sourceFields = JDBCUtilities.getColumnNames(connection, noiseMapByReceiverMaker.getSourcesTableName()); + List sourceFields = JDBCUtilities.getColumnNames(connection, noiseMapByReceiverMaker.getSourcesTableName()).stream().map(String::toUpperCase).collect(Collectors.toList()); + // Look for Emission/Traffic columns without periods + List frequencyValuesWithoutPeriod = readFrequenciesFromLwTable( + noiseMapByReceiverMaker.getFrequencyFieldPrepend(), sourceFields); + if(!frequencyValuesWithoutPeriod.isEmpty()) { + inputSettings.inputMode = SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_LW; + } else if (sourceFields.contains("LV_SPD")) { + inputSettings.inputMode = SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_TRAFFIC_FLOW; + } + // Look for Emission/Traffic columns for each period for (EmissionTableGenerator.STANDARD_PERIOD period : EmissionTableGenerator.STANDARD_PERIOD.values()) { String periodFieldName = EmissionTableGenerator.STANDARD_PERIOD_VALUE[period.ordinal()]; List frequencyValues = readFrequenciesFromLwTable( @@ -114,11 +133,17 @@ public void initialize(Connection connection, NoiseMapByReceiverMaker noiseMapBy } } } - + if(inputSettings.inputMode == SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_GUESS) { + // By default, we compute the attenuation + inputSettings.inputMode = SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_ATTENUATION; + } if(inputSettings.inputMode == SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_LW) { // Load expected frequencies used for computation // Fetch source fields - List sourceField = JDBCUtilities.getColumnNames(connection, noiseMapByReceiverMaker.getSourcesEmissionTableName()); + List sourceField = JDBCUtilities.getColumnNames(connection, + noiseMapByReceiverMaker.getSourcesEmissionTableName().isEmpty() ? + noiseMapByReceiverMaker.getSourcesTableName() : + noiseMapByReceiverMaker.getSourcesEmissionTableName()); List frequencyValues = readFrequenciesFromLwTable(noiseMapByReceiverMaker.getFrequencyFieldPrepend(), sourceField); if(frequencyValues.isEmpty()) { throw new SQLException("Source emission table "+ noiseMapByReceiverMaker.getSourcesTableName()+" does not contains any frequency bands"); @@ -278,6 +303,8 @@ public SceneWithEmission create(Connection connection, CellIndex cellIndex, scene.setBodyBarrier(noiseMapByReceiverMaker.isBodyBarrier()); scene.maxRefDist = maximumReflectionDistance; scene.maxSrcDist = maximumPropagationDistance; + scene.setCloseReceiverReflectionWallDistance(noiseMapByReceiverMaker.getCloseReceiverReflectionWallDistance()); + scene.lineSourceSpacingRatio = noiseMapByReceiverMaker.getSceneInputSettings().getLineSourceSpacingRatio(); scene.setComputeVerticalDiffraction(noiseMapByReceiverMaker.isComputeVerticalDiffraction()); scene.setComputeHorizontalDiffraction(noiseMapByReceiverMaker.isComputeHorizontalDiffraction()); @@ -316,6 +343,9 @@ public SceneWithEmission create(Connection connection, CellIndex cellIndex, " contain at least one receiver without Z ordinate." + " You must specify X,Y,Z for each receiver"); } + if(!noiseMapByReceiverMaker.isReceiverHasAbsoluteZCoordinates()) { + pt = scene.profileBuilder.makeGeometryRelativeZToAbsolute(pt, true); + } scene.addReceiver(receiverPk, pt.getCoordinate(), rs); } } @@ -335,7 +365,7 @@ public SceneWithEmission create(Connection connection, CellIndex cellIndex, * @param tableName Table name * @param defaultInterpolation Interpolation if applicable * @param frequencyFieldPrepend Frequency field name ex. HZ for HZ1000 - * @return + * @return Map of directivity spheres */ public static Map fetchDirectivity(Connection connection, String tableName, int defaultInterpolation, String frequencyFieldPrepend) throws SQLException { Map directionAttributes = new HashMap<>(); @@ -449,7 +479,7 @@ public static void fetchCellBuildings(Connection connection, String additionalQuery = ""; DBTypes dbType = DBUtils.getDBType(connection.unwrap(Connection.class)); if(!buildingTableParameters.heightField.isEmpty()) { - additionalQuery += ", " + TableLocation.quoteIdentifier(buildingTableParameters.heightField, dbType); + additionalQuery += ", " + TableLocation.capsIdentifier(buildingTableParameters.heightField, dbType); } if(fetchAlpha) { additionalQuery += ", " + buildingTableParameters.alphaFieldName; @@ -701,6 +731,8 @@ protected void fetchCellSoilAreas(Connection connection, Envelope fetchEnvelope, */ public void fetchCellSource(Connection connection, Envelope fetchEnvelope, SceneWithEmission scene, boolean doIntersection) throws SQLException { + Map sourceEmissionFieldsCache = new HashMap<>(); + Map sourceFieldNames = new HashMap<>(); String sourcesTableName = noiseMapByReceiverMaker.getSourcesTableName(); GeometryFactory geometryFactory = noiseMapByReceiverMaker.getGeometryFactory(); DBTypes dbType = DBUtils.getDBType(connection.unwrap(Connection.class)); @@ -727,6 +759,7 @@ public void fetchCellSource(Connection connection, Envelope fetchEnvelope, Scene } st.setFetchDirection(ResultSet.FETCH_FORWARD); try (SpatialResultSet rs = st.executeQuery().unwrap(SpatialResultSet.class)) { + EmissionTableGenerator.cacheFields(sourceFieldNames, rs); while (rs.next()) { Geometry geo = rs.getGeometry(); if (geo != null) { @@ -737,13 +770,20 @@ public void fetchCellSource(Connection connection, Envelope fetchEnvelope, Scene Coordinate[] coordinates = geo.getCoordinates(); for (Coordinate coordinate : coordinates) { // check z value - if (coordinate.getZ() == Coordinate.NULL_ORDINATE) { + if (Double.isNaN(coordinate.getZ())) { throw new IllegalArgumentException("The table " + sourcesTableName + " contain at least one source without Z ordinate." + " You must specify X,Y,Z for each source"); } } - scene.addSource(rs.getLong(pkIndex), geo, rs); + if(!noiseMapByReceiverMaker.isSourceHasAbsoluteZCoordinates()) { + if(scene.profileBuilder.hasDem()) { + // Coordinates are supposed to be relative to the digital elevation model + // So we must compute the altitude values + geo = scene.profileBuilder.makeGeometryRelativeZToAbsolute(geo, true); + } + } + scene.addSource(rs.getLong(pkIndex), geo, rs, sourceFieldNames); } } } @@ -768,8 +808,9 @@ public void fetchCellSource(Connection connection, Envelope fetchEnvelope, Scene } st.setFetchDirection(ResultSet.FETCH_FORWARD); try (ResultSet rs = st.executeQuery()) { + EmissionTableGenerator.cacheFields(sourceEmissionFieldsCache, rs); while (rs.next()) { - scene.addSourceEmission(rs.getLong(scene.sceneDatabaseInputSettings.sourceEmissionPrimaryKeyField), rs); + scene.addSourceEmission(rs.getLong(scene.sceneDatabaseInputSettings.sourceEmissionPrimaryKeyField), rs, sourceEmissionFieldsCache); } } finally { if (autoCommit) { diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/SceneDatabaseInputSettings.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/SceneDatabaseInputSettings.java index de1264aef..83e15afe3 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/SceneDatabaseInputSettings.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/SceneDatabaseInputSettings.java @@ -45,6 +45,12 @@ public enum INPUT_MODE { String periodAtmosphericSettingsTableName = ""; /** Cnossos coefficient version (1 = 2015, 2 = 2020) */ int coefficientVersion = 2; + /** + * dictates the density of source points created from a line sound source; + * a higher value means more points and finer discretization + * sourcePointDistance = DistanceSourceReceiver / lineSourceSpacingRatio + */ + public double lineSourceSpacingRatio = 2; public String frequencyFieldPrepend = "HZ"; public SceneDatabaseInputSettings() { @@ -132,4 +138,21 @@ public String getFrequencyFieldPrepend() { public void setFrequencyFieldPrepend(String frequencyFieldPrepend) { this.frequencyFieldPrepend = frequencyFieldPrepend; } + + /** + * @return dictates the density of source points created from a line sound source; + * a higher value means more points and finer discretization + * sourcePointDistance = DistanceSourceReceiver / lineSourceSpacingRatio + */ + public double getLineSourceSpacingRatio() { + return lineSourceSpacingRatio; + } + + /** + * dictates the density of source points created from a line sound source; + * @param lineSourceSpacingRatio a higher value means more points and finer discretization + */ + public void setLineSourceSpacingRatio(double lineSourceSpacingRatio) { + this.lineSourceSpacingRatio = lineSourceSpacingRatio; + } } \ No newline at end of file diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/SceneWithEmission.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/SceneWithEmission.java index 8645ca756..51cd697f8 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/SceneWithEmission.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/input/SceneWithEmission.java @@ -26,9 +26,6 @@ * This is input data, not thread safe, never update anything here during propagation */ public class SceneWithEmission extends SceneWithAttenuation { - /** Old style DEN columns traffic period */ - Map sourceEmissionFieldsCache = new HashMap<>(); - // For each source primary key give the map between period and source power spectrum values public Map> wjSources = new HashMap<>(); @@ -46,7 +43,7 @@ public SceneWithEmission(ProfileBuilder profileBuilder) { public SceneWithEmission() { } - public void processTrafficFlowDEN(Long pk, SpatialResultSet rs) throws SQLException { + public void processTrafficFlowDEN(Long pk, SpatialResultSet rs, Map sourceFieldNames) throws SQLException { // Source table PK, GEOM, LV_D, LV_E, LV_N ... double[][] lw = EmissionTableGenerator.computeLw(rs, sceneDatabaseInputSettings.coefficientVersion, sourceFieldNames); // Will generate D E N emission @@ -60,11 +57,11 @@ public void processTrafficFlowDEN(Long pk, SpatialResultSet rs) throws SQLExcept * @param rs Emission source table IDSOURCE, PERIOD, LV, HV .. * @throws SQLException */ - public void processTrafficFlow(Long pk, ResultSet rs) throws SQLException { + public void processTrafficFlow(Long pk, ResultSet rs, Map sourceFieldNames) throws SQLException { String period = rs.getString("PERIOD"); // Use geometry as default slope (if field slope is not provided double defaultSlope = 0; - if(!sourceEmissionFieldsCache.containsKey("SLOPE")) { + if(!sourceFieldNames.containsKey("SLOPE")) { int sourceIndex = sourcesPk.indexOf(pk); if(sourceIndex >= 0) { defaultSlope = EmissionTableGenerator.getSlope(sourceGeometries.get(sourceIndex)); @@ -73,7 +70,7 @@ public void processTrafficFlow(Long pk, ResultSet rs) throws SQLException { double[] lw = AcousticIndicatorsFunctions.dBToW( EmissionTableGenerator.getEmissionFromTrafficTable(rs, "", defaultSlope, - sceneDatabaseInputSettings.coefficientVersion, sourceEmissionFieldsCache)); + sceneDatabaseInputSettings.coefficientVersion, sourceFieldNames)); addSourceEmission(pk, period, lw); } @@ -82,31 +79,45 @@ public void processTrafficFlow(Long pk, ResultSet rs) throws SQLException { * @param rs Emission source table IDSOURCE, PERIOD, LV, HV .. * @throws SQLException */ - public void processEmission(Long pk, ResultSet rs) throws SQLException { + public void processEmission(Long pk, ResultSet rs, Map sourceFieldNames) throws SQLException { double[] lw = new double[profileBuilder.frequencyArray.size()]; List frequencyArray = profileBuilder.frequencyArray; for (int i = 0, frequencyArraySize = frequencyArray.size(); i < frequencyArraySize; i++) { Integer frequency = frequencyArray.get(i); - lw[i] = AcousticIndicatorsFunctions.dBToW(rs.getDouble(sceneDatabaseInputSettings.frequencyFieldPrepend +frequency)); + String fieldName = sceneDatabaseInputSettings.frequencyFieldPrepend+frequency; + int fieldIndex = sourceFieldNames.getOrDefault(fieldName, 0); + if(fieldIndex <= 0) { + // No emission value here for this frequency, skip the extraction of noise source level + // It could be provided later from another table + return; + } + lw[i] = AcousticIndicatorsFunctions.dBToW(rs.getDouble(fieldIndex)); + } + // Check if period field exists use empty string otherwise + if(!sourceFieldNames.containsKey("PERIOD")) { + addSourceEmission(pk, "", lw); + } else { + addSourceEmission(pk, Objects.toString(rs.getString("PERIOD"), ""), lw); } - String period = rs.getString("PERIOD"); - addSourceEmission(pk, period, lw); } @Override - public void addSource(Long pk, Geometry geom, SpatialResultSet rs) throws SQLException { - super.addSource(pk, geom, rs); + public void addSource(Long pk, Geometry geom, SpatialResultSet rs, Map sourceFieldNames) throws SQLException { + super.addSource(pk, geom, rs, sourceFieldNames); switch (Objects.requireNonNull(sceneDatabaseInputSettings.inputMode)) { case INPUT_MODE_TRAFFIC_FLOW_DEN: - processTrafficFlowDEN(pk, rs); + processTrafficFlowDEN(pk, rs, sourceFieldNames); break; case INPUT_MODE_LW_DEN: - processEmissionDEN(pk, rs); + processEmissionDEN(pk, rs, sourceFieldNames); + break; + case INPUT_MODE_LW: + processEmission(pk, rs, sourceFieldNames); break; } } - private void processEmissionDEN(Long pk, SpatialResultSet rs) throws SQLException { + private void processEmissionDEN(Long pk, SpatialResultSet rs, Map sourceFieldNames) throws SQLException { List frequencyArray = profileBuilder.frequencyArray; for (EmissionTableGenerator.STANDARD_PERIOD period : EmissionTableGenerator.STANDARD_PERIOD.values()) { double[] lw = new double[profileBuilder.frequencyArray.size()]; @@ -129,13 +140,15 @@ private void processEmissionDEN(Long pk, SpatialResultSet rs) throws SQLExceptio } } - public void addSourceEmission(Long pk, ResultSet rs) throws SQLException { + public void addSourceEmission(Long pk, ResultSet rs, Map sourceFieldNames) throws SQLException { switch (sceneDatabaseInputSettings.inputMode) { + case INPUT_MODE_TRAFFIC_FLOW_DEN: case INPUT_MODE_TRAFFIC_FLOW: - processTrafficFlow(pk, rs); + processTrafficFlow(pk, rs, sourceFieldNames); break; + case INPUT_MODE_LW_DEN: case INPUT_MODE_LW: - processEmission(pk, rs); + processEmission(pk, rs, sourceFieldNames); break; } } @@ -163,7 +176,6 @@ public void addSourceEmission(Long sourcePrimaryKey, String period, double[] wj) @Override public void clearSources() { super.clearSources(); - sourceEmissionFieldsCache.clear(); wjSources.clear(); } diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/output/AttenuationOutputSingleThread.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/output/AttenuationOutputSingleThread.java index ce80dba22..3268c03fa 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/output/AttenuationOutputSingleThread.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/output/AttenuationOutputSingleThread.java @@ -22,15 +22,12 @@ import org.noise_planet.noisemodelling.pathfinder.profilebuilder.CutProfile; import org.noise_planet.noisemodelling.propagation.AttenuationParameters; import org.noise_planet.noisemodelling.propagation.ReceiverNoiseLevel; -import org.noise_planet.noisemodelling.propagation.cnossos.AttenuationCnossos; -import org.noise_planet.noisemodelling.propagation.cnossos.CnossosPath; +import org.noise_planet.noisemodelling.propagation.cnossos.*; import org.noise_planet.noisemodelling.pathfinder.utils.AcousticIndicatorsFunctions; -import org.noise_planet.noisemodelling.propagation.cnossos.CnossosPathBuilder; import java.util.*; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.DoubleStream; import static org.noise_planet.noisemodelling.pathfinder.utils.AcousticIndicatorsFunctions.*; import static org.noise_planet.noisemodelling.pathfinder.utils.AcousticIndicatorsFunctions.wToDb; @@ -60,10 +57,10 @@ public class AttenuationOutputSingleThread implements CutPlaneVisitor { /** * MaxError DB Processing variable * Favourable Free Field cumulated global power at receiver, only used to stop looking for far sources - * Key source index + * Key unique source point identifier * Value maximum expected noise level in w */ - Map> maximumWjExpectedSplAtReceiver = new HashMap<>(); + Map> maximumWjExpectedSplAtReceiver = new HashMap<>(); public AtomicInteger cutProfileCount = new AtomicInteger(0); @@ -81,22 +78,13 @@ public AttenuationOutputSingleThread(AttenuationOutputMultiThread multiThreadPar } /** - * - * @param sourceInfo - * @param receiverInfo - * @param cnossosParameters - * @return Attenuation in dB + * The maximumError shortcut stops the path finder before all farther sources are visited. + * When rays are explicitly exported, users expect the rays table to describe the complete + * propagation search, so the shortcut must stay disabled for that diagnostic output. */ - private static double[] computeFastAttenuation(PathFinder.SourcePointInfo sourceInfo, - PathFinder.ReceiverPointInfo receiverInfo, AttenuationParameters cnossosParameters) { - // For the quick attenuation evaluation - // only take account of geometric dispersion and atmospheric attenuation - double distance = Math.max(1.0, sourceInfo.position.distance3D(receiverInfo.position)); - // 3 dB gain as we consider source G path is equal to 0 - double attenuationDivGeom = AttenuationCnossos.getADiv(distance) - 3; - return AcousticIndicatorsFunctions.multiplicationArray(AcousticIndicatorsFunctions.sumArray( - AttenuationCnossos.aAtm(cnossosParameters.getAlpha_atmo(), distance), - attenuationDivGeom), -1); + private boolean isMaximumErrorPruningEnabled() { + return dbSettings.maximumError > 0 && + dbSettings.getExportRaysMethod() == NoiseMapDatabaseParameters.ExportRaysMethods.NONE; } private double[] processAndStoreAttenuation(AttenuationParameters data, CnossosPath proPathParameters, String period) { @@ -133,6 +121,10 @@ public PathSearchStrategy onNewCutPlane(CutProfile cutProfile) { cutProfileCount.addAndGet(1); PathSearchStrategy strategy = PathSearchStrategy.CONTINUE; final SceneWithEmission scene = multiThread.sceneWithEmission; + if(scene.getCloseReceiverReflectionWallDistance() > 0 + && cutProfile.hasCloseReflectionBeforeReceiver(scene.getCloseReceiverReflectionWallDistance())) { + return strategy; + } List cnossosPaths = CnossosPathBuilder.computeCnossosPathsFromCutProfile(cutProfile, scene.isBodyBarrier(), scene.profileBuilder.exactFrequencyArray, scene.defaultGroundAttenuation); for (CnossosPath cnossosPath : cnossosPaths) { @@ -195,24 +187,27 @@ public PathSearchStrategy onNewCutPlane(CutProfile cutProfile) { new ReceiverNoiseLevel(new PathFinder.SourcePointInfo(source), new PathFinder.ReceiverPointInfo(receiver), period, levels); processNoiseLevel(receiverNoiseLevel); - if(dbSettings.maximumError > 0) { + if(isMaximumErrorPruningEnabled()) { double powerSum = sumArray(levels); wjAtReceiver.merge(period, powerSum, Double::sum); } } } } - if(dbSettings.maximumError > 0 && scene.wjSources.containsKey(sourcePk)) { + // To reduce the computation time, we evaluate the potential remaining power + // at the receiver and stop processing further sources if we are already close enough to + // the expected final level at the receiver (if maximumError is defined in dbSettings) + if(isMaximumErrorPruningEnabled() && scene.wjSources.containsKey(sourcePk)) { boolean keepRunning = false; - // update remaining expected max power for each source periods + // Update remaining expected max power for each source period. + // We remove the currently processed source point from the precomputed budget. ArrayList emissions = scene.wjSources.get(sourcePk); + SourcePointKey sourcePointKey = new SourcePointKey(source); for (SceneWithEmission.PeriodEmission periodEmission : emissions) { final String period = periodEmission.period; - // replace unknown value (evaluated on startReceiver) of expected power for this source point if (maximumWjExpectedSplAtReceiver.containsKey(period)) { - maximumWjExpectedSplAtReceiver.get(period).remove(source.coordinate); + maximumWjExpectedSplAtReceiver.get(period).remove(sourcePointKey); if (maximumWjExpectedSplAtReceiver.get(period).isEmpty()) { - // no remaining power at this period maximumWjExpectedSplAtReceiver.remove(period); } } @@ -222,19 +217,18 @@ public PathSearchStrategy onNewCutPlane(CutProfile cutProfile) { final double levelAtReceiver = entry.getValue(); if(!maximumWjExpectedSplAtReceiver.containsKey(period)) { - // nothing to evaluate here, as there is no expected further power for this period + // Nothing to evaluate here, as there is no expected further power for this period. continue; } // Evaluate the current noise level at receiver compared to the final - // expected noise level at the receiver + // expected noise level at the receiver. double nonProcessedPower = maximumWjExpectedSplAtReceiver.get(period).values().stream() .reduce(Double::sum).orElse(0.0); - double maximumExpectedLevelInDb = AcousticIndicatorsFunctions.wToDb(levelAtReceiver - + nonProcessedPower); + double maximumExpectedLevelInDb = AcousticIndicatorsFunctions.wToDb(levelAtReceiver + nonProcessedPower); double dBDiff = maximumExpectedLevelInDb - wToDb(levelAtReceiver); if (dBDiff > dbSettings.maximumError) { - // For this period we expect to see some significant sources further away + // For this period we still expect to see some significant sources further away. keepRunning = true; break; } @@ -252,7 +246,7 @@ public void startReceiver(PathFinder.ReceiverPointInfo receiver, Collection 0 && !multiThread.sceneWithEmission.wjSources.isEmpty()) { + if(isMaximumErrorPruningEnabled() && !multiThread.sceneWithEmission.wjSources.isEmpty()) { wjAtReceiver = new HashMap<>(multiThread.sceneWithEmission.periodSet.size()); for (String period : multiThread.sceneWithEmission.periodSet) { wjAtReceiver.put(period, 0.0); @@ -261,20 +255,45 @@ public void startReceiver(PathFinder.ReceiverPointInfo receiver, Collection()); + List pts2D = cutProfile.computePts2D(); + cnossosPath.setSRSegment(CnossosPathBuilder.computeSegment(pts2D.get(0), pts2D.get(1), new double[] {0, 0})); + cnossosPath.getPointList().add(new PointPath(pts2D.get(0), 0, PointPath.POINT_TYPE.SRCE)); + cnossosPath.getPointList().add(new PointPath(pts2D.get(1), 0, PointPath.POINT_TYPE.RECV)); + double[] attenuation = dBToW(AttenuationCnossos.computeCnossosAttenuation(scene.defaultCnossosParameters, cnossosPath, scene, false)); + // For line source apply a gain on the attenuation + if(sourcePointInfo.li > 1) { + attenuation = multiplicationArray(attenuation, sourcePointInfo.li); + } if(scene.wjSources.containsKey(sourcePointInfo.sourcePk)) { ArrayList emissions = scene.wjSources.get(sourcePointInfo.sourcePk); for (SceneWithEmission.PeriodEmission periodEmission : emissions) { - double[] wjAtReceiver = multiplicationArray(attenuation, periodEmission.emission); + // Use period-specific attenuation settings when available so the remaining-power + // budget matches the actual period being evaluated by the maxError algorithm. + AttenuationParameters parameters = scene.cnossosParametersPerPeriod.getOrDefault( + periodEmission.period, scene.defaultCnossosParameters); + double[] attenuationPerPeriod = attenuation; + if(parameters != scene.defaultCnossosParameters) { + attenuationPerPeriod = dBToW(AttenuationCnossos.computeCnossosAttenuation(parameters, + cnossosPath, scene, false)); + if(sourcePointInfo.li > 1) { + attenuationPerPeriod = multiplicationArray(attenuationPerPeriod, sourcePointInfo.li); + } + } + double[] wjAtReceiver = multiplicationArray(attenuationPerPeriod, periodEmission.emission); double sumPower = sumArray(wjAtReceiver); - HashMap sourceLevel; + HashMap sourceLevel; if(!maximumWjExpectedSplAtReceiver.containsKey(periodEmission.period)) { sourceLevel = new HashMap<>(); maximumWjExpectedSplAtReceiver.put(periodEmission.period, sourceLevel); } else { sourceLevel = maximumWjExpectedSplAtReceiver.get(periodEmission.period); } - sourceLevel.merge(sourcePointInfo.getCoord(), sumPower, Double::sum); + sourceLevel.merge(new SourcePointKey(sourcePointInfo), sumPower, Double::sum); } } } @@ -397,6 +416,7 @@ public void finalizeReceiver(PathFinder.ReceiverPointInfo receiver) { } } if (dbSettings.isMergeSources()) { + // If Merge source is activated, the following code will push empty values (-99dB) when no rays have reached the receiver Set difference = new HashSet<>(multiThread.sceneWithEmission.periodSet); if(computeLden) { difference.add(EmissionTableGenerator.DEN_PERIOD); @@ -462,4 +482,5 @@ public TimePeriodParameters update(TimePeriodParameters other) { return this; } } + } diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/output/SourcePointKey.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/output/SourcePointKey.java new file mode 100644 index 000000000..61b400fdc --- /dev/null +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/output/SourcePointKey.java @@ -0,0 +1,59 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

+ * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

+ * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + +package org.noise_planet.noisemodelling.jdbc.output; + +import org.noise_planet.noisemodelling.pathfinder.PathFinder; +import org.noise_planet.noisemodelling.pathfinder.profilebuilder.CutPointSource; + +import java.util.Objects; + +/** + * Unique identifier for one discretized source point in the maxError bookkeeping. + * We cannot use the coordinate alone because distinct source points may legitimately + * share the same position while belonging to different source identifiers. + * A line source will create multiple source points with the same primary key and index but with different coordinates. + */ +final class SourcePointKey { + final long sourcePk; + final int sourceIndex; + final long x; + final long y; + final long z; + + SourcePointKey(PathFinder.SourcePointInfo sourcePointInfo) { + this.sourcePk = sourcePointInfo.sourcePk; + this.sourceIndex = sourcePointInfo.sourceIndex; + this.x = Double.doubleToLongBits(sourcePointInfo.position.x); + this.y = Double.doubleToLongBits(sourcePointInfo.position.y); + this.z = Double.doubleToLongBits(sourcePointInfo.position.z); + } + + SourcePointKey(CutPointSource sourcePoint) { + this.sourcePk = sourcePoint.sourcePk; + this.sourceIndex = sourcePoint.id; + this.x = Double.doubleToLongBits(sourcePoint.coordinate.x); + this.y = Double.doubleToLongBits(sourcePoint.coordinate.y); + this.z = Double.doubleToLongBits(sourcePoint.coordinate.z); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SourcePointKey)) return false; + SourcePointKey that = (SourcePointKey) o; + return sourcePk == that.sourcePk && sourceIndex == that.sourceIndex && + x == that.x && y == that.y && z == that.z; + } + + @Override + public int hashCode() { + return Objects.hash(sourcePk, sourceIndex, x, y, z); + } +} diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/railway/RailWayLWIterator.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/railway/RailWayLWIterator.java index 52e3011ad..16ba435c8 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/railway/RailWayLWIterator.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/railway/RailWayLWIterator.java @@ -30,6 +30,9 @@ public class RailWayLWIterator implements Iterator { + public static final String RAILWAY_VEHICLES_CNOSSOS_JSON = "RailwayVehiclesCnossos.json"; + public static final String RAILWAY_TRAINSETS_JSON = "RailwayTrainsets.json"; + public static final String RAILWAY_EMISSION_CNOSSOS_JSON = "RailwayEmissionCnossos.json"; private RailwayCnossos railway = new RailwayCnossos(); private Connection connection; private RailWayLWGeom railWayLWComplete = null; @@ -46,27 +49,33 @@ public class RailWayLWIterator implements Iterator { * @param tableTrackGeometry Track geometry and metadata * @param tableTrainTraffic Train traffic associated with tracks */ - public RailWayLWIterator(Connection connection, String tableTrackGeometry, String tableTrainTraffic) { - this.railway.setVehicleDataFile("RailwayVehiclesCnossos.json"); - this.railway.setTrainSetDataFile("RailwayTrainsets.json"); - this.railway.setRailwayDataFile("RailwayCnossosSNCF_2021.json"); + public RailWayLWIterator(Connection connection, String tableTrackGeometry, String tableTrainTraffic) throws IOException { + this.railway.setVehicleDataFile(RAILWAY_VEHICLES_CNOSSOS_JSON); + this.railway.setTrainSetDataFile(RAILWAY_TRAINSETS_JSON); + this.railway.setRailwayDataFile(RAILWAY_EMISSION_CNOSSOS_JSON); this.connection = connection; this.tableTrackGeometry = tableTrackGeometry; this.tableTrainTraffic = tableTrainTraffic; railWayLWComplete = fetchNext(railWayLWIncomplete); } - /** * Generate sound source for train (with train source directivity) from traffic and geometry tracks tables - * @param connection - * @param tableTrackGeometry Track geometry and metadata - * @param tableTrainTraffic Train traffic associated with tracks + * Constructs a RailWayLWIterator instance to process railway data by reading from a database connection + * and associated data files. Initializes the railway metadata and fetches the first incomplete railway geometry. + * + * @param connection Database connection used to fetch railway and traffic data. + * @param tableTrackGeometry Table name containing track geometry and metadata. + * @param tableTrainTraffic Table name containing train traffic details associated with tracks. + * @param vehicleDataFile File path Url or resource filename (from org.noise_planet.noisemodelling.emission.railway package) for vehicle data configuration. + * @param trainSetDataFile File path Url or resource filename (from org.noise_planet.noisemodelling.emission.railway package) for train set data configuration. + * @param railwayEmissionDataFile File path Url or resource filename (from org.noise_planet.noisemodelling.emission.railway package) for railway metadata configuration. + * @throws IOException If an error occurs during file reading or parsing the specified data files. */ - public RailWayLWIterator(Connection connection, String tableTrackGeometry, String tableTrainTraffic, String vehicleDataFile, String trainSetDataFile, String railwayDataFile) { + public RailWayLWIterator(Connection connection, String tableTrackGeometry, String tableTrainTraffic, String vehicleDataFile, String trainSetDataFile, String railwayEmissionDataFile) throws IOException { this.railway.setVehicleDataFile(vehicleDataFile); this.railway.setTrainSetDataFile(trainSetDataFile); - this.railway.setRailwayDataFile(railwayDataFile); + this.railway.setRailwayDataFile(railwayEmissionDataFile); this.connection = connection; this.tableTrackGeometry = tableTrackGeometry; this.tableTrainTraffic = tableTrainTraffic; @@ -227,11 +236,11 @@ public RailWayCnossosParameters getRailwayEmissionFromResultSet(ResultSet rs, St double vehiclePerHour = 1; int rollingCondition = 0; double idlingTime = 0; - int trackTransfer = 4; - int impactNoise = 0; - int bridgeTransfert = 0; + String trackTransferStr = "SNCF4"; + String impactNoiseStr = ""; + String bridgeTransfertStr = ""; int curvature = 0; - int railRoughness = 1; + String railRoughnessStr = "SNCF1"; int nbTrack = 2; double vMaxInfra = 160; double commercialSpeed = 160; @@ -252,17 +261,19 @@ public RailWayCnossosParameters getRailwayEmissionFromResultSet(ResultSet rs, St idlingTime = rs.getDouble("IDLINGTIME"); } if (sourceFields.containsKey("TRANSFER")) { - trackTransfer = rs.getInt("TRANSFER"); + trackTransferStr = rs.getString("TRANSFER"); } if (sourceFields.containsKey("ROUGHNESS")) { - railRoughness = rs.getInt("ROUGHNESS"); + railRoughnessStr = rs.getString("ROUGHNESS"); } if (sourceFields.containsKey("IMPACT")) { - impactNoise = rs.getInt("IMPACT"); + String val = rs.getString("IMPACT"); + impactNoiseStr = val != null ? val : ""; } if (sourceFields.containsKey("BRIDGE")) { - bridgeTransfert = rs.getInt("BRIDGE"); + String val = rs.getString("BRIDGE"); + bridgeTransfertStr = val != null ? val : ""; } if (sourceFields.containsKey("CURVATURE")) { curvature = rs.getInt("CURVATURE"); @@ -299,8 +310,8 @@ public RailWayCnossosParameters getRailwayEmissionFromResultSet(ResultSet rs, St RailWayCnossosParameters lWRailWay = new RailWayCnossosParameters(); - RailwayTrackCnossosParameters trackParameters = new RailwayTrackCnossosParameters(vMaxInfra, trackTransfer, railRoughness, - impactNoise, bridgeTransfert, curvature, commercialSpeed, isTunnel, nbTrack); + RailwayTrackCnossosParameters trackParameters = new RailwayTrackCnossosParameters(vMaxInfra, trackTransferStr, railRoughnessStr, + impactNoiseStr, bridgeTransfertStr, curvature, commercialSpeed, isTunnel, nbTrack); Map vehicles = railway.getVehicleFromTrainset(train); // double vehiclePerHouri=vehiclePerHour; diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/utils/AscReaderDriver.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/utils/AscReaderDriver.java index 9aac4ef2b..ad0133f74 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/utils/AscReaderDriver.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/utils/AscReaderDriver.java @@ -230,8 +230,9 @@ public String[] read(Connection connection, File fileName, ProgressVisitor progr stmt.execute("DROP TABLE IF EXISTS " + outputTableName); stmt.close(); } - FileInputStream fis = new FileInputStream(fileName); - outputTableName = readAsc(connection, new GZIPInputStream(fis), progress, outputTableName, srid); + try (FileInputStream fis = new FileInputStream(fileName)) { + outputTableName = readAsc(connection, new GZIPInputStream(fis), progress, outputTableName, srid); + } return new String[]{outputTableName}; } else { throw new SQLException("The asc read driver supports only asc or gz extensions"); diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/utils/DataBaseUtilities.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/utils/DataBaseUtilities.java new file mode 100644 index 000000000..c4330235f --- /dev/null +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/utils/DataBaseUtilities.java @@ -0,0 +1,59 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

+ * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

+ * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.jdbc.utils; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class DataBaseUtilities { + /** + * Checks if the given SRID uses meters as its unit by querying the SPATIAL_REF_SYS table. + * + * @param connection A live JDBC connection + * @param srid The SRID to check + * @return true if the units are metric (meters) + */ + public static boolean isSridMetric(Connection connection, int srid) throws SQLException { + String sql = "SELECT PROJ4TEXT FROM SPATIAL_REF_SYS WHERE SRID = ?"; + + try (PreparedStatement ps = connection.prepareStatement(sql)) { + ps.setInt(1, srid); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + String proj = rs.getString("PROJ4TEXT"); + if (proj == null || proj.isEmpty()) { + return false; + } + + // Normalize to lowercase for reliable matching + proj = proj.toLowerCase(); + + /* + * Logic for Proj4 metric detection: + * 1. Check for "+units=m". + * We ensure it's not "+units=mm" (millimeters). + * 2. Check for "+to_meter=1" or "+to_meter=1.0". + */ + boolean hasMeterUnit = proj.contains("+units=m") && !proj.contains("+units=mm"); + boolean hasMeterFactor = proj.contains("+to_meter=1") || proj.contains("+to_meter=1.0"); + + return hasMeterUnit || hasMeterFactor; + } + } + } catch (SQLException e) { + // Log the exception according to your project's logging policy + System.err.println("Error querying SPATIAL_REF_SYS: " + e.getMessage()); + } + + return false; + } +} diff --git a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/utils/IsoSurface.java b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/utils/IsoSurface.java index 556fd33f8..35159cf27 100644 --- a/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/utils/IsoSurface.java +++ b/noisemodelling-jdbc/src/main/java/org/noise_planet/noisemodelling/jdbc/utils/IsoSurface.java @@ -9,11 +9,12 @@ package org.noise_planet.noisemodelling.jdbc.utils; +import org.h2gis.api.EmptyProgressVisitor; +import org.h2gis.api.ProgressVisitor; import org.h2gis.functions.spatial.convert.ST_Force2D; import org.h2gis.functions.spatial.convert.ST_Force3D; import org.h2gis.utilities.JDBCUtilities; import org.h2gis.utilities.TableLocation; -import org.h2gis.utilities.TableUtilities; import org.h2gis.utilities.dbtypes.DBTypes; import org.h2gis.utilities.dbtypes.DBUtils; import org.h2gis.utilities.jts_utils.Contouring; @@ -57,6 +58,7 @@ public class IsoSurface { public static final List NF31_133_ISO = Collections.unmodifiableList(Arrays.asList(35.0,40.0,45.0,50.0,55.0,60.0,65.0,70.0,75.0,80.0,200.0)); private int exportDimension = 2; + private ProgressVisitor progressVisitor = new EmptyProgressVisitor(); /** * @param isoLevels Iso levels in dB. First range start with -Infinity then first level excluded. @@ -521,6 +523,39 @@ public void createTable(Connection connection) throws SQLException { createTable(connection, pkField); } + /** + * Retrieve all unique time periods in receivers level table + * @param connection SQL connection + * @return List of unique periods + * @throws SQLException Error during SQL query + */ + public List getUniquePeriods(Connection connection) throws SQLException { + List fieldValues = new ArrayList<>(); + try(Statement statement = connection.createStatement()) { + try (ResultSet result = + statement.executeQuery(String.format("SELECT DISTINCT period FROM %s ORDER BY period", pointTable))) { + while (result.next()) { + fieldValues.add(result.getString(1)); + } + } + } + return fieldValues; + } + + /** + * @return instance of progress information + */ + public ProgressVisitor getProgressVisitor() { + return progressVisitor; + } + + /** + * @param progressVisitor Progress informations + */ + public void setProgressVisitor(ProgressVisitor progressVisitor) { + this.progressVisitor = progressVisitor; + } + /** * @param connection * @param pkField Field name in point table to join with Triangle table and point table @@ -571,12 +606,33 @@ public void createTable(Connection connection, String pkField) throws SQLExcepti if(!aggregateByPeriod) { periods.add(""); } else { - periods.addAll(JDBCUtilities.getUniqueFieldValues(connection, pointTable, periodField)); + periods.addAll(getUniquePeriods(connection)); } + ProgressVisitor periodProgress = progressVisitor.subProcess(periods.size()); for (String period : periods) { if(aggregateByPeriod) { statement.setString(1, period); } + + // Evaluate the number of triangles with this period in order to have a relevant progress information + int numRows = 0; + StringBuilder selectCountQuery = new StringBuilder(); + selectCountQuery.append("SELECT COUNT(*) FROM ").append(triangleTable); + if(aggregateByPeriod) { + selectCountQuery.append(" t, ").append(pointTable).append(" p1 WHERE t.PK_1 = p1.").append(pkField); + selectCountQuery.append(" AND p1.PERIOD = ?"); + } + try(PreparedStatement countStatement = connection.prepareStatement(selectCountQuery.toString())) { + if(aggregateByPeriod) { + countStatement.setString(1, period); + } + try (ResultSet countResult = countStatement.executeQuery()) { + if (countResult.next()) { + numRows = countResult.getInt(1); + } + } + } + ProgressVisitor cellProgress = periodProgress.subProcess(numRows); // Cache iso for the current processing cell Map> polyMap = new HashMap<>(); try (ResultSet rs = statement.executeQuery()) { @@ -659,6 +715,7 @@ public void createTable(Connection connection, String pkField) throws SQLExcepti polygonsArray.add(poly); } } + cellProgress.endStep(); } } if (!polyMap.isEmpty()) { diff --git a/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/IsoSurfaceJDBCTest.java b/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/IsoSurfaceJDBCTest.java index 5116a3346..8e7a32b19 100644 --- a/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/IsoSurfaceJDBCTest.java +++ b/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/IsoSurfaceJDBCTest.java @@ -9,9 +9,12 @@ package org.noise_planet.noisemodelling.jdbc; +import org.h2.value.ValueBoolean; import org.h2gis.api.EmptyProgressVisitor; import org.h2gis.functions.factory.H2GISDBFactory; import org.h2gis.functions.io.geojson.GeoJsonRead; +import org.h2gis.functions.io.shp.SHPWrite; +import org.h2gis.utilities.GeometryTableUtilities; import org.h2gis.utilities.JDBCUtilities; import org.h2gis.utilities.SpatialResultSet; import org.junit.jupiter.api.AfterEach; @@ -93,8 +96,9 @@ public void testIsoSurface() throws SQLException, IOException { @Test public void testContouring3D() throws SQLException, IOException, LayerDelaunayError { // Will create elevation iso from DEM table + // Take the resource from the other project in the source tree (we are not dependent on it) GeoJsonRead.importTable(connection, Paths.get(Paths.get(System.getProperty("user.dir")).getParent().toString(), - "wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dem.geojson").toString()); + "noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dem.geojson").toString()); LayerTinfour delaunayTool = new LayerTinfour(); try (PreparedStatement st = connection.prepareStatement( "SELECT the_geom FROM DEM")) { @@ -110,7 +114,7 @@ public void testContouring3D() throws SQLException, IOException, LayerDelaunayEr delaunayTool.processDelaunay(); DelaunayReceiversMaker.generateResultTable(connection, "RECEIVERS", "TRIANGLES", new AtomicInteger(), delaunayTool.getVertices(), new GeometryFactory(), delaunayTool.getTriangles(), - 0, 0, 1); + 0, 0, 1, false); try(Statement st = connection.createStatement()) { st.execute("ALTER TABLE RECEIVERS ADD COLUMN HEIGHT FLOAT"); st.execute("UPDATE RECEIVERS SET HEIGHT = ST_Z(THE_GEOM)"); @@ -140,8 +144,9 @@ public void testContouring3D() throws SQLException, IOException, LayerDelaunayEr @Test public void testContouring3DMerge() throws SQLException, IOException, LayerDelaunayError { // Will create elevation iso from DEM table + // Take the resource from the other project in the source tree (we are not dependent on it) GeoJsonRead.importTable(connection, Paths.get(Paths.get(System.getProperty("user.dir")).getParent().toString(), - "wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dem.geojson").toString()); + "noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dem.geojson").toString()); LayerTinfour delaunayTool = new LayerTinfour(); try (PreparedStatement st = connection.prepareStatement( "SELECT the_geom FROM DEM")) { @@ -157,7 +162,7 @@ public void testContouring3DMerge() throws SQLException, IOException, LayerDelau delaunayTool.processDelaunay(); DelaunayReceiversMaker.generateResultTable(connection, "RECEIVERS", "TRIANGLES", new AtomicInteger(), delaunayTool.getVertices(), new GeometryFactory(), delaunayTool.getTriangles(), - 0, 0, 1); + 0, 0, 1, false); try(Statement st = connection.createStatement()) { st.execute("ALTER TABLE RECEIVERS ADD COLUMN HEIGHT FLOAT"); st.execute("UPDATE RECEIVERS SET HEIGHT = ST_Z(THE_GEOM)"); @@ -192,7 +197,7 @@ public void testNoiseMapBuilding() throws Exception { noisemap.setReceiverHasAbsoluteZCoordinates(false); noisemap.setSourceHasAbsoluteZCoordinates(false); noisemap.setHeightField("HEIGHT"); - noisemap.initialize(connection, new EmptyProgressVisitor()); + noisemap.initialize(connection); AtomicInteger pk = new AtomicInteger(0); for(int i=0; i < noisemap.getGridDim(); i++) { @@ -214,9 +219,9 @@ public void testGenerateReceiversAndPeriodIsoCountours() throws SQLException { IsoSurface isoSurface = new IsoSurface(IsoSurface.NF31_133_ISO, srid); // Generate delaunay triangulation DelaunayReceiversMaker delaunayReceiversMaker = new DelaunayReceiversMaker("BUILDINGS", "ROADS_TRAFF"); - delaunayReceiversMaker.setMaximumArea(800); + delaunayReceiversMaker.setMaximumArea(0); delaunayReceiversMaker.setGridDim(1); - delaunayReceiversMaker.run(connection, "RECEIVERS" , isoSurface.getTriangleTable()); + delaunayReceiversMaker.run(connection, "RECEIVERS" , isoSurface.getTriangleTable(), new EmptyProgressVisitor()); // Create noise map for 4 periods NoiseMapByReceiverMaker noiseMapByReceiverMaker = new NoiseMapByReceiverMaker("BUILDINGS", @@ -227,7 +232,6 @@ public void testGenerateReceiversAndPeriodIsoCountours() throws SQLException { noiseMapByReceiverMaker.setComputeHorizontalDiffraction(false); noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportReceiverPosition = true; noiseMapByReceiverMaker.setGridDim(1); - noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().setMaximumError(3); noiseMapByReceiverMaker.run(connection, new RootProgressVisitor(1, true, 5)); @@ -245,6 +249,7 @@ public void testGenerateReceiversAndPeriodIsoCountours() throws SQLException { isoSurface.setPointTableField("LAEQ"); isoSurface.setSmooth(false); // faster isoSurface.setMergeTriangles(false); // faster + isoSurface.setProgressVisitor(new RootProgressVisitor(1, true, 5)); isoSurface.createTable(connection, "IDRECEIVER"); List columnNames = JDBCUtilities.getColumnNames(connection, isoSurface.getOutputTable()); @@ -259,4 +264,81 @@ public void testGenerateReceiversAndPeriodIsoCountours() throws SQLException { } } + + @Test + public void testDelaunayReceiverSkipCells() throws SQLException, IOException { + GeoJsonRead.importTable(connection, IsoSurfaceJDBCTest.class.getResource("SPARSE_BUILDINGS.geojson").getFile()); + GeoJsonRead.importTable(connection, IsoSurfaceJDBCTest.class.getResource("SPARSE_ROADS.geojson").getFile()); + try(Statement st = connection.createStatement()) { + st.execute("ALTER TABLE SPARSE_BUILDINGS ALTER COLUMN PK INTEGER NOT NULL"); + st.execute("ALTER TABLE SPARSE_BUILDINGS ADD PRIMARY KEY (PK)"); + st.execute("ALTER TABLE SPARSE_ROADS ALTER COLUMN PK INTEGER NOT NULL"); + st.execute("ALTER TABLE SPARSE_ROADS ADD PRIMARY KEY (PK)"); + } + + DelaunayReceiversMaker delaunayReceiversMaker = new DelaunayReceiversMaker("SPARSE_BUILDINGS", "SPARSE_ROADS"); + + delaunayReceiversMaker.setMinimalSourceGeometriesDistanceToComputeCell(1000); + delaunayReceiversMaker.setMaximumPropagationDistance(500); + delaunayReceiversMaker.setMaximumArea(2000); + delaunayReceiversMaker.setVerbose(true); + delaunayReceiversMaker.setExportTrianglesGeometries(false); + delaunayReceiversMaker.run(connection, "RECEIVERS", "TRIANGLES", new EmptyProgressVisitor()); + + // Count the number of unique cell_id values + int rowCount = 0; + try(Statement st = connection.createStatement()) { + try (ResultSet rs = st.executeQuery("SELECT COUNT(DISTINCT CELL_ID) AS CNT FROM TRIANGLES")) { + if (rs.next()) { + rowCount = rs.getInt("CNT"); + } + } + } + // 16 instead of 4096 + assertEquals(16, rowCount); + + } + + + @Test + public void testDelaunayNoReceiverInBuildings() throws SQLException, IOException { + GeoJsonRead.importTable(connection, IsoSurfaceJDBCTest.class.getResource("delaunaytest/buildings.geojson.gz").getFile(), "BUILDINGS", ValueBoolean.TRUE); + GeoJsonRead.importTable(connection, IsoSurfaceJDBCTest.class.getResource("delaunaytest/sources.geojson.gz").getFile(), "SOURCES", ValueBoolean.TRUE); + try(Statement st = connection.createStatement()) { + // Add primary keys + st.execute("ALTER TABLE buildings ALTER COLUMN PK INTEGER NOT NULL"); + st.execute("ALTER TABLE buildings ADD PRIMARY KEY (PK)"); + st.execute("ALTER TABLE sources ALTER COLUMN PK INTEGER NOT NULL"); + st.execute("ALTER TABLE sources ADD PRIMARY KEY (PK)"); + // Create spatial indexes + st.execute("CREATE SPATIAL INDEX ON sources(THE_GEOM)"); + st.execute("CREATE SPATIAL INDEX ON buildings(THE_GEOM)"); + } + + + + DelaunayReceiversMaker delaunayReceiversMaker = new DelaunayReceiversMaker("BUILDINGS", "SOURCES"); + + delaunayReceiversMaker.setMaximumPropagationDistance(5000); + delaunayReceiversMaker.setMaximumArea(500); + delaunayReceiversMaker.run(connection, "RECEIVERS", "TRIANGLES", new EmptyProgressVisitor()); + + // Check if there is no receiver in buildings + try(Statement st = connection.createStatement()) { + try (ResultSet rs = st.executeQuery("SELECT COUNT(*) AS CNT FROM RECEIVERS R, BUILDINGS B WHERE R.THE_GEOM && B.THE_GEOM AND ST_CONTAINS(B.THE_GEOM, R.THE_GEOM)")) { + if (rs.next()) { + assertEquals(0, rs.getInt("CNT")); + } + } + } + // Check the minimal distance of receivers to buildings + try(Statement st = connection.createStatement()) { + try (ResultSet rs = st.executeQuery("SELECT MIN(ST_DISTANCE(RECEIVERS.THE_GEOM, BUILDINGS.THE_GEOM)) AS MINDIST FROM RECEIVERS, BUILDINGS WHERE ST_EXPAND(RECEIVERS.THE_GEOM, 10) && BUILDINGS.THE_GEOM")) { + if (rs.next()) { + assertTrue(rs.getDouble("MINDIST") > 1, "Minimal distance between receivers and buildings should be greater than 1m"); + } + } + } + + } } \ No newline at end of file diff --git a/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/NoiseMapByReceiverMakerTest.java b/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/NoiseMapByReceiverMakerTest.java index 3ec5d1689..af55fa7dc 100644 --- a/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/NoiseMapByReceiverMakerTest.java +++ b/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/NoiseMapByReceiverMakerTest.java @@ -31,6 +31,7 @@ import org.noise_planet.noisemodelling.propagation.cnossos.CnossosPath; import org.noise_planet.noisemodelling.pathfinder.profilebuilder.GroundAbsorption; import org.noise_planet.noisemodelling.pathfinder.utils.geometry.Orientation; +import org.noise_planet.noisemodelling.propagation.cnossos.PointPath; import java.sql.Connection; import java.sql.ResultSet; @@ -70,7 +71,7 @@ public void testGroundSurface() throws Exception { noiseMapByReceiverMaker.setHeightField("HEIGHT"); noiseMapByReceiverMaker.setSoilTableName("LAND_G"); noiseMapByReceiverMaker.setFrequencyFieldPrepend("DB_M"); - noiseMapByReceiverMaker.initialize(connection, new EmptyProgressVisitor()); + noiseMapByReceiverMaker.initialize(connection); Set processedReceivers = new HashSet<>(); Map populatedCells = noiseMapByReceiverMaker.searchPopulatedCells(connection); @@ -140,7 +141,6 @@ public void testPointDirectivity() throws Exception { noiseMapByReceiverMaker.setMaximumPropagationDistance(1000); noiseMapByReceiverMaker.setHeightField("HEIGHT"); noiseMapByReceiverMaker.setInputMode(SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_LW_DEN); - noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().setCoefficientVersion(1); // Use train directivity functions instead of discrete directivity noiseMapByReceiverMaker.getSceneInputSettings().setUseTrainDirectivity(true); @@ -180,7 +180,6 @@ public void testLineDirectivity() throws Exception { noiseMapByReceiverMaker.setMaximumPropagationDistance(1000); noiseMapByReceiverMaker.setHeightField("HEIGHT"); noiseMapByReceiverMaker.setInputMode(SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_LW_DEN); - noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().setCoefficientVersion(1); noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportRaysMethod = NoiseMapDatabaseParameters.ExportRaysMethods.TO_RAYS_TABLE; noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportCnossosPathWithAttenuation = true; noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportAttenuationMatrix = true; @@ -258,7 +257,6 @@ public void testPointRayDirectivity() throws Exception { noiseMapByReceiverMaker.setMaximumPropagationDistance(1000); noiseMapByReceiverMaker.setHeightField("HEIGHT"); noiseMapByReceiverMaker.setInputMode(SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_LW_DEN); - noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().setCoefficientVersion(1); noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportRaysMethod = NoiseMapDatabaseParameters.ExportRaysMethods.TO_RAYS_TABLE; noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportCnossosPathWithAttenuation = true; noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportAttenuationMatrix = true; @@ -328,9 +326,9 @@ public void testEmissionTrafficTable() throws SQLException { IsoSurface isoSurface = new IsoSurface(IsoSurface.NF31_133_ISO, srid); // Generate delaunay triangulation DelaunayReceiversMaker delaunayReceiversMaker = new DelaunayReceiversMaker("BUILDINGS", "ROADS_TRAFF"); - delaunayReceiversMaker.setMaximumArea(800); + delaunayReceiversMaker.setMaximumArea(0); delaunayReceiversMaker.setGridDim(1); - delaunayReceiversMaker.run(connection, "RECEIVERS", isoSurface.getTriangleTable()); + delaunayReceiversMaker.run(connection, "RECEIVERS", isoSurface.getTriangleTable(), new EmptyProgressVisitor()); // Create noise map for 4 periods NoiseMapByReceiverMaker noiseMapByReceiverMaker = new NoiseMapByReceiverMaker("BUILDINGS", @@ -338,6 +336,7 @@ public void testEmissionTrafficTable() throws SQLException { noiseMapByReceiverMaker.setMaximumPropagationDistance(100); noiseMapByReceiverMaker.setSoundReflectionOrder(0); + noiseMapByReceiverMaker.setComputeVerticalDiffraction(false); noiseMapByReceiverMaker.setComputeHorizontalDiffraction(false); noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportReceiverPosition = true; noiseMapByReceiverMaker.setGridDim(1); @@ -351,8 +350,8 @@ public void testEmissionTrafficTable() throws SQLException { int resultRowCount = JDBCUtilities.getRowCount(connection, noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().receiversLevelTable); - // D E N, should be 3 more rows than receivers - assertEquals(receiversRowCount * 3, resultRowCount); + // D E N and DEN, should be 4 more rows than receivers + assertEquals(receiversRowCount * 4, resultRowCount); } } @@ -373,9 +372,9 @@ public void testEmissionLwTable() throws SQLException { IsoSurface isoSurface = new IsoSurface(IsoSurface.NF31_133_ISO, srid); // Generate delaunay triangulation DelaunayReceiversMaker delaunayReceiversMaker = new DelaunayReceiversMaker("BUILDINGS", "SOURCES_GEOM"); - delaunayReceiversMaker.setMaximumArea(800); + delaunayReceiversMaker.setMaximumArea(0); delaunayReceiversMaker.setGridDim(1); - delaunayReceiversMaker.run(connection, "RECEIVERS", isoSurface.getTriangleTable()); + delaunayReceiversMaker.run(connection, "RECEIVERS", isoSurface.getTriangleTable(), new EmptyProgressVisitor()); // Create noise map for 4 periods NoiseMapByReceiverMaker noiseMapByReceiverMaker = new NoiseMapByReceiverMaker("BUILDINGS", @@ -397,8 +396,8 @@ public void testEmissionLwTable() throws SQLException { int resultRowCount = JDBCUtilities.getRowCount(connection, noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().receiversLevelTable); - // D E N, should be 3 more rows than receivers - assertEquals(receiversRowCount * 3, resultRowCount); + // D E N and DEN, should be 4 more rows than receivers + assertEquals(receiversRowCount * 4, resultRowCount); } } @@ -433,7 +432,6 @@ public void testPointDem() throws Exception { noiseMapByReceiverMaker.setSoundReflectionOrder(0); noiseMapByReceiverMaker.setMaximumPropagationDistance(1000); noiseMapByReceiverMaker.setHeightField("HEIGHT"); - noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().setCoefficientVersion(1); noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportRaysMethod = NoiseMapDatabaseParameters.ExportRaysMethods.TO_RAYS_TABLE; noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().raysTable = "RAYS"; noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportCnossosPathWithAttenuation = true; @@ -469,11 +467,11 @@ public void testPointDem() throws Exception { /** - * Place a point source into a building to check if the source is ignored + * Place a point source into a building to check if the source is still computed but a warning will be logged * @throws Exception */ @Test - public void testIgnoredSourceInBuilding() throws Exception { + public void testSourceInBuilding() throws Exception { try (Statement st = connection.createStatement()) { // Import shape file // org/noise_planet/noisemodelling/jdbc/PointSource/DEM_Fence.shp @@ -500,7 +498,6 @@ public void testIgnoredSourceInBuilding() throws Exception { noiseMapByReceiverMaker.setSoundReflectionOrder(0); noiseMapByReceiverMaker.setMaximumPropagationDistance(1000); noiseMapByReceiverMaker.setHeightField("HEIGHT"); - noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().setCoefficientVersion(1); noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportRaysMethod = NoiseMapDatabaseParameters.ExportRaysMethods.TO_RAYS_TABLE; noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().raysTable = "RAYS"; noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportCnossosPathWithAttenuation = true; @@ -520,7 +517,12 @@ public void testIgnoredSourceInBuilding() throws Exception { pathsParameters.add(cnossosPath); } } - assertEquals(0 , pathsParameters.size()); + // Diffraction over the walls of the building, but no direct path + assertEquals(2 , pathsParameters.size()); + // Homogenous path with diffraction over the building wall + assertEquals(PointPath.POINT_TYPE.DIFH, pathsParameters.get(0).getPointList().get(1).type); + // Favorable path with diffraction over the building wall + assertEquals(PointPath.POINT_TYPE.DIFH, pathsParameters.get(1).getPointList().get(1).type); } } } \ No newline at end of file diff --git a/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/SceneWithEmissionTest.java b/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/SceneWithEmissionTest.java index 51d4bc2d3..196edcf25 100644 --- a/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/SceneWithEmissionTest.java +++ b/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/SceneWithEmissionTest.java @@ -11,21 +11,32 @@ import org.h2gis.api.EmptyProgressVisitor; import org.h2gis.functions.factory.H2GISDBFactory; +import org.h2gis.utilities.GeometryTableUtilities; import org.h2gis.utilities.JDBCUtilities; +import org.h2gis.utilities.TableLocation; +import org.h2gis.utilities.dbtypes.DBTypes; +import org.h2gis.utilities.dbtypes.DBUtils; import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.*; import org.locationtech.jts.io.ParseException; import org.locationtech.jts.io.WKTReader; import org.noise_planet.noisemodelling.jdbc.input.SceneDatabaseInputSettings; +import org.noise_planet.noisemodelling.jdbc.input.DefaultTableLoader; import org.noise_planet.noisemodelling.jdbc.input.SceneWithEmission; import org.noise_planet.noisemodelling.jdbc.output.AttenuationOutputMultiThread; +import org.noise_planet.noisemodelling.jdbc.utils.CellIndex; import org.noise_planet.noisemodelling.pathfinder.PathFinder; import org.noise_planet.noisemodelling.pathfinder.delaunay.LayerDelaunayError; +import org.noise_planet.noisemodelling.pathfinder.path.Scene; +import org.noise_planet.noisemodelling.pathfinder.profilebuilder.CutProfile; import org.noise_planet.noisemodelling.pathfinder.profilebuilder.ProfileBuilder; import org.noise_planet.noisemodelling.pathfinder.profilebuilder.WallAbsorption; import org.noise_planet.noisemodelling.pathfinder.utils.AcousticIndicatorsFunctions; import org.noise_planet.noisemodelling.propagation.AttenuationParameters; import org.noise_planet.noisemodelling.propagation.ReceiverNoiseLevel; +import org.noise_planet.noisemodelling.propagation.cnossos.CnossosPath; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.sql.Connection; @@ -41,8 +52,11 @@ * Test class evaluation and testing attenuation values. */ public class SceneWithEmissionTest { + private static final Logger LOGGER = LoggerFactory.getLogger(SceneWithEmissionTest.class); private static final double HUMIDITY = 70; private static final double TEMPERATURE = 10; + public boolean verbose = false; + private List testIgnoreNonSignificantSourcesParam(Connection connection, double maxError) throws SQLException, IOException { return testIgnoreNonSignificantSourcesParam(connection, maxError, "BUILDINGS", "LW_ROADS", "RECEIVERS", ""); @@ -127,6 +141,160 @@ private static Map fetchReceiverLevel(Connection connection) thr return allSourcesReceiverLevel; } + private static double[] createFlatSpectrum(ProfileBuilder profileBuilder, double levelDb) { + double[] spectrum = new double[profileBuilder.frequencyArray.size()]; + Arrays.fill(spectrum, AcousticIndicatorsFunctions.dBToW(levelDb)); + return spectrum; + } + + private static AttenuationParameters createPeriodParameters(SceneWithEmission scene) { + AttenuationParameters parameters = new AttenuationParameters(scene.defaultCnossosParameters); + parameters.setHumidity(HUMIDITY); + parameters.setTemperature(TEMPERATURE); + return parameters; + } + + private static AttenuationOutputMultiThread runSceneWithMaximumError(SceneWithEmission scene, double maxError) { + AttenuationOutputMultiThread output = new AttenuationOutputMultiThread(scene); + output.noiseMapDatabaseParameters.setMaximumError(maxError); + output.noiseMapDatabaseParameters.setMergeSources(false); + output.noiseMapDatabaseParameters.setExportRaysMethod(NoiseMapDatabaseParameters.ExportRaysMethods.TO_RAYS_TABLE); + output.noiseMapDatabaseParameters.setExportAttenuationMatrix(true); + PathFinder computeRays = new PathFinder(scene); + computeRays.setThreadCount(1); + computeRays.run(output); + return output; + } + + private static Map aggregateGlobalLevelsByPeriod(Collection receiverLevels) { + Map levelsByPeriod = new HashMap<>(); + for (ReceiverNoiseLevel receiverNoiseLevel : receiverLevels) { + levelsByPeriod.merge(receiverNoiseLevel.period, + sumArray(AcousticIndicatorsFunctions.dBToW(receiverNoiseLevel.levels)), Double::sum); + } + return levelsByPeriod; + } + + private static Map countSourcePeriodReceiverLevels(Collection receiverLevels) { + Map counts = new HashMap<>(); + for (ReceiverNoiseLevel receiverNoiseLevel : receiverLevels) { + String key = receiverNoiseLevel.period + "#" + receiverNoiseLevel.source.sourcePk; + counts.merge(key, 1, Integer::sum); + } + return counts; + } + + private static Map countSourcePeriodRays(Collection cnossosPaths) { + Map counts = new HashMap<>(); + for (CnossosPath cnossosPath : cnossosPaths) { + String key = cnossosPath.getTimePeriod() + "#" + cnossosPath.getCutProfile().getSource().sourcePk; + counts.merge(key, 1, Integer::sum); + } + return counts; + } + + private static void assertOutputsEquivalentWithinMaximumError(AttenuationOutputMultiThread baseline, + AttenuationOutputMultiThread optimized, + double maxError) { + Map baselineReceiverKeys = countSourcePeriodReceiverLevels(baseline.resultsCache.receiverLevels); + Map optimizedReceiverKeys = countSourcePeriodReceiverLevels(optimized.resultsCache.receiverLevels); + assertEquals(baselineReceiverKeys, optimizedReceiverKeys, + "Optimized run should keep the same source-period receiver contributions as baseline"); + + Map baselineRayKeys = countSourcePeriodRays(baseline.resultsCache.cnossosPaths); + Map optimizedRayKeys = countSourcePeriodRays(optimized.resultsCache.cnossosPaths); + assertEquals(baselineRayKeys, optimizedRayKeys, + "Optimized run should keep the same source-period ray contributions as baseline"); + + Map baselineLevels = aggregateGlobalLevelsByPeriod(baseline.resultsCache.receiverLevels); + Map optimizedLevels = aggregateGlobalLevelsByPeriod(optimized.resultsCache.receiverLevels); + assertEquals(baselineLevels.keySet(), optimizedLevels.keySet(), + "Optimized run should keep the same period coverage as baseline"); + for (Map.Entry entry : baselineLevels.entrySet()) { + String period = entry.getKey(); + double baselineDb = wToDb(entry.getValue()); + double optimizedDb = wToDb(optimizedLevels.get(period)); + assertTrue(Math.abs(baselineDb - optimizedDb) <= maxError, + String.format(Locale.ROOT, + "Period %s differs by %.2f dB, expected <= %.2f dB", period, + Math.abs(baselineDb - optimizedDb), maxError)); + } + } + + private static long runDynamicConfMaxErrorFixture(double maxError) throws Exception { + String dbName = "dynamicConfMaxError_" + Long.toUnsignedString(Double.doubleToLongBits(maxError)); + try (Connection connection = + JDBCUtilities.wrapConnection(H2GISDBFactory.createSpatialDataBase(dbName, true, ""))) { + try (Statement st = connection.createStatement()) { + st.execute(String.format("CALL SHPREAD('%s', 'BUILDINGS')", + SceneWithEmissionTest.class.getResource("dynamicConfMaxErrorTest/buldings_test.shp").getFile())); + st.execute(String.format("CALL SHPREAD('%s', 'SOURCES')", + SceneWithEmissionTest.class.getResource("dynamicConfMaxErrorTest/sources_test.shp").getFile())); + st.execute(String.format("CALL SHPREAD('%s', 'RECEIVERS')", + SceneWithEmissionTest.class.getResource("dynamicConfMaxErrorTest/receivers_test.shp").getFile())); + } + + splitDynamicSourcesPeriod(connection, "SOURCES", "PK", "PERIOD", + "SOURCES_GEOM", "SOURCES_EMISSION"); + + NoiseMapByReceiverMaker noiseMap = new NoiseMapByReceiverMaker("BUILDINGS", "SOURCES_GEOM", "RECEIVERS"); + noiseMap.setGridDim(1); + noiseMap.setThreadCount(1); + noiseMap.setHeightField("HEIGHT"); + noiseMap.setSourcesEmissionTableName("SOURCES_EMISSION"); + noiseMap.setMaximumPropagationDistance(100); + noiseMap.setMaximumReflectionDistance(50); + noiseMap.setSoundReflectionOrder(0); + noiseMap.setComputeHorizontalDiffraction(true); + noiseMap.setComputeVerticalDiffraction(true); + noiseMap.getNoiseMapDatabaseParameters().setMergeSources(true); + noiseMap.getNoiseMapDatabaseParameters().setMaximumError(maxError); + noiseMap.getNoiseMapDatabaseParameters().setExportRaysMethod(NoiseMapDatabaseParameters.ExportRaysMethods.TO_RAYS_TABLE); + noiseMap.getNoiseMapDatabaseParameters().setRaysTable("RAYS"); + noiseMap.getNoiseMapDatabaseParameters().setExportAttenuationMatrix(true); + noiseMap.getNoiseMapDatabaseParameters().setExportCnossosPathWithAttenuation(true); + noiseMap.getNoiseMapDatabaseParameters().keepAbsorption = true; + + DefaultTableLoader defaultTableLoader = (DefaultTableLoader) noiseMap.getPropagationProcessDataFactory(); + defaultTableLoader.defaultParameters.setWindRose(new double[AttenuationParameters.DEFAULT_WIND_ROSE.length]); + + noiseMap.run(connection, new EmptyProgressVisitor()); + + return JDBCUtilities.getRowCount(connection, noiseMap.getNoiseMapDatabaseParameters().getRaysTable()); + } + } + + private static void splitDynamicSourcesPeriod(Connection connection, String tableSourceDynamic, + String sourceIndexFieldName, String sourcePeriodFieldName, + String sourceGeomTableName, String sourceEmissionTableName) + throws SQLException { + DBTypes dbType = DBUtils.getDBType(connection.unwrap(Connection.class)); + String sourceIndexField = TableLocation.capsIdentifier(sourceIndexFieldName, dbType); + String sourcePeriodField = TableLocation.capsIdentifier(sourcePeriodFieldName, dbType); + + try (Statement st = connection.createStatement()) { + st.execute("DROP TABLE IF EXISTS " + sourceGeomTableName); + st.execute("DROP TABLE IF EXISTS " + sourceEmissionTableName); + } + + List columnNames = new ArrayList<>(JDBCUtilities.getColumnNames(connection, tableSourceDynamic)); + columnNames.remove(TableLocation.capsIdentifier("THE_GEOM", dbType)); + columnNames.remove(sourcePeriodField); + columnNames.remove(sourceIndexField); + String additionalColumns = String.join(", ", columnNames); + int sridSources = GeometryTableUtilities.getSRID(connection, TableLocation.parse(tableSourceDynamic, dbType)); + + try (Statement st = connection.createStatement()) { + st.execute("CREATE TABLE " + sourceGeomTableName + "(IDSOURCE INT PRIMARY KEY, THE_GEOM GEOMETRY) " + + "AS SELECT " + sourceIndexField + " IDSOURCE, ANY_VALUE(THE_GEOM) THE_GEOM FROM " + + tableSourceDynamic + " GROUP BY IDSOURCE"); + st.execute("CREATE TABLE " + sourceEmissionTableName + " AS SELECT " + sourceIndexField + " IDSOURCE, " + + sourcePeriodField + " PERIOD, " + additionalColumns + " FROM " + tableSourceDynamic); + st.execute("CREATE INDEX ON " + sourceEmissionTableName + " (IDSOURCE, PERIOD)"); + st.execute("SELECT UpdateGeometrySRID('" + sourceGeomTableName + "','the_geom', " + sridSources + ")"); + } + } + /** * Test optimisation feature {@link NoiseMapDatabaseParameters#setMaximumError(double)} * This feature is disabled and all sound sources are computed @@ -187,18 +355,15 @@ public void testSourceLines() throws ParseException { double[] roadLvl = AcousticIndicatorsFunctions.dBToW(new double[]{25.65, 38.15, 54.35, 60.35, 74.65, 66.75, 59.25, 53.95}); SceneWithEmission scene = new SceneWithEmission(builder); - scene.addReceiver(new Coordinate(50, 50, 0.05)); - scene.addReceiver(new Coordinate(48, 50, 4)); - scene.addReceiver(new Coordinate(44, 50, 4)); - scene.addReceiver(new Coordinate(40, 50, 4)); - scene.addReceiver(new Coordinate(20, 50, 4)); - scene.addReceiver(new Coordinate(0, 50, 4)); + scene.addReceiver(scene.profileBuilder.offsetCoordinatesToAltitudeUsingDigitalElevationModel( + new Coordinate[]{new Coordinate(50, 50, 0.05), new Coordinate(48, 50, 4), new Coordinate(44, 50, 4), + new Coordinate(40, 50, 4), new Coordinate(20, 50, 4), new Coordinate(0, 50, 4)}, false)); List srcPtsRef = new ArrayList<>(); PathFinder.splitLineStringIntoPoints(geomSource, 1.0, srcPtsRef); for (long i = 0; i < srcPtsRef.size(); i++) { Coordinate srcPtRef = srcPtsRef.get((int) i); - scene.addSource(i, factory.createPoint(srcPtRef)); + scene.addSource(i, scene.profileBuilder.makeGeometryRelativeZToAbsolute(factory.createPoint(srcPtRef), false)); scene.addSourceEmission(i, "", roadLvl); } @@ -213,7 +378,6 @@ public void testSourceLines() throws ParseException { AttenuationOutputMultiThread propDataOut = new AttenuationOutputMultiThread(scene); PathFinder computeRays = new PathFinder(scene); - computeRays.makeRelativeZToAbsolute(); computeRays.setThreadCount(1); computeRays.run(propDataOut); @@ -360,5 +524,233 @@ public void testReceiverOverBuilding() throws LayerDelaunayError, ParseException 0.1); } + @Test + public void testMaximumErrorMultiPeriodOverlappingSourcesFreeField() { + final double maxError = 0.1; + GeometryFactory factory = new GeometryFactory(); + + ProfileBuilder builder = new ProfileBuilder(); + builder.finishFeeding(); + + SceneWithEmission scene = new SceneWithEmission(builder); + scene.addReceiver(new Coordinate(0, 0, 4.0)); + scene.setComputeHorizontalDiffraction(false); + scene.setComputeVerticalDiffraction(false); + scene.setReflexionOrder(0); + scene.maxSrcDist = 500; + scene.defaultCnossosParameters.setHumidity(HUMIDITY); + scene.defaultCnossosParameters.setTemperature(TEMPERATURE); + scene.cnossosParametersPerPeriod.put("T0", createPeriodParameters(scene)); + scene.cnossosParametersPerPeriod.put("T1", createPeriodParameters(scene)); + + scene.addSource(1L, factory.createPoint(new Coordinate(5, 0, 0.05))); + scene.addSourceEmission(1L, "T0", createFlatSpectrum(builder, 120.0)); + + Coordinate duplicatedSource = new Coordinate(60, 0, 0.05); + scene.addSource(2L, factory.createPoint(duplicatedSource)); + scene.addSourceEmission(2L, "T1", createFlatSpectrum(builder, 112.0)); + scene.addSource(3L, factory.createPoint(new Coordinate(duplicatedSource))); + scene.addSourceEmission(3L, "T1", createFlatSpectrum(builder, 112.0)); + + AttenuationOutputMultiThread baseline = runSceneWithMaximumError(scene, 0.0); + AttenuationOutputMultiThread optimized = runSceneWithMaximumError(scene, maxError); + + assertOutputsEquivalentWithinMaximumError(baseline, optimized, maxError); + } + + @Test + public void testMaximumErrorMultiPeriodOverlappingSourcesWithReflection() { + final double maxError = 0.1; + GeometryFactory factory = new GeometryFactory(); + + List alphaWallFrequencies = Arrays.asList(AcousticIndicatorsFunctions.asOctaveBands( + ProfileBuilder.DEFAULT_FREQUENCIES_THIRD_OCTAVE)); + List alphaWall = new ArrayList<>(alphaWallFrequencies.size()); + for(int frequency : alphaWallFrequencies) { + alphaWall.add(WallAbsorption.getWallAlpha(100000, frequency)); + } + + ProfileBuilder profileBuilder = new ProfileBuilder() + .addWall(new Coordinate[]{ + new Coordinate(6, 0, 4), + new Coordinate(-5, 12, 4), + }, 8, alphaWall, 0) + .addWall(new Coordinate[]{ + new Coordinate(14, 4, 4), + new Coordinate(3, 16, 4), + }, 8, alphaWall, 1); + profileBuilder.setzBuildings(true); + profileBuilder.finishFeeding(); + + SceneWithEmission scene = new SceneWithEmission(profileBuilder); + scene.addReceiver(new Coordinate(4.5, 8, 1.6)); + scene.setDefaultGroundAttenuation(0.5); + scene.setComputeHorizontalDiffraction(false); + scene.setComputeVerticalDiffraction(false); + scene.setReflexionOrder(1); + scene.maxSrcDist = 500; + scene.maxRefDist = 500; + scene.defaultCnossosParameters.setHumidity(HUMIDITY); + scene.defaultCnossosParameters.setTemperature(TEMPERATURE); + scene.cnossosParametersPerPeriod.put("T0", createPeriodParameters(scene)); + scene.cnossosParametersPerPeriod.put("T1", createPeriodParameters(scene)); + + scene.addSource(1L, factory.createPoint(new Coordinate(2.5, 8, 0.1))); + scene.addSourceEmission(1L, "T0", createFlatSpectrum(profileBuilder, 120.0)); + + Coordinate duplicatedSource = new Coordinate(8, 5.5, 0.1); + scene.addSource(2L, factory.createPoint(duplicatedSource)); + scene.addSourceEmission(2L, "T1", createFlatSpectrum(profileBuilder, 112.0)); + scene.addSource(3L, factory.createPoint(new Coordinate(duplicatedSource))); + scene.addSourceEmission(3L, "T1", createFlatSpectrum(profileBuilder, 112.0)); + + AttenuationOutputMultiThread baseline = runSceneWithMaximumError(scene, 0.0); + assertTrue(baseline.resultsCache.cnossosPaths.stream().anyMatch(cnossosPath -> + cnossosPath.getCutProfile().getProfileType() == CutProfile.PROFILE_TYPE.REFLECTION), + "Baseline scene should include at least one reflection path"); + + AttenuationOutputMultiThread optimized = runSceneWithMaximumError(scene, maxError); + + assertOutputsEquivalentWithinMaximumError(baseline, optimized, maxError); + } + + @Test + public void testDynamicConfMaxErrorFixtureKeepsSameRayCount() throws Exception { + long rayCountWithoutPruning = runDynamicConfMaxErrorFixture(0.0); + long rayCountWithPruning = runDynamicConfMaxErrorFixture(0.1); + + assertTrue(rayCountWithoutPruning > 0, "Fixture should generate at least one ray"); + assertEquals(rayCountWithoutPruning, rayCountWithPruning, + String.format(Locale.ROOT, + "Expected the same number of rays with confMaxError=0.0 and 0.1, but got %d and %d", + rayCountWithoutPruning, rayCountWithPruning)); + } + + /** + * Comparison: line source (500 m) and 0.1 dB error simplification vs discretized point sources (1 m spacing) without error. + * Free-field, no buildings, no ground effects (fully reflective), flat spectrum. + * The difference at each receiver should be less than the maximum error parameter per frequency band. + */ + @Test + public void testLongLineSourceVsDiscretePointsMaximumError() throws ParseException { + double maxError = 0.1; + GeometryFactory factory = new GeometryFactory(); + + // 500 m horizontal line source at height 0.05 m + double cx = 250.0; + double cy = 0.0; + double halfLen = 250.0; + double x1 = cx - halfLen; + double x2 = cx + halfLen; + + WKTReader wktReader = new WKTReader(factory); + LineString lineSource = (LineString) wktReader.read( + "LINESTRING (" + x1 + " " + cy + " 0.05, " + x2 + " " + cy + " 0.05)"); + + // Free-field: no buildings, no ground effect + ProfileBuilder builder = new ProfileBuilder(); + builder.finishFeeding(); + + double lwOctDb = 73.037; + double[] roadLvl = new double[8]; + for (int i = 0; i < 8; i++) { + roadLvl[i] = AcousticIndicatorsFunctions.dBToW(lwOctDb); + } + + // Receivers at various distances and angles from mid-point of the line + // Angles relative to the line direction: 0° = along line, 45° = diagonal, 90° = perpendicular + double[] receiverDistances = {10, 50, 100, 200, 400}; + double[] receiverAngles = {0, 45, 90}; // degrees + + // === RUN 1: Discretized point sources at 1 m spacing === + SceneWithEmission scene = new SceneWithEmission(builder); + List receiverLabels = new ArrayList<>(); + for (double angleDeg : receiverAngles) { + double angleRad = Math.toRadians(angleDeg); + for (double dist : receiverDistances) { + double rx = cx + dist * Math.cos(angleRad); + double ry = cy + dist * Math.sin(angleRad); + scene.addReceiver(new Coordinate(rx, ry, 4.0)); + receiverLabels.add(String.format("d=%dm, angle=%d°", (int) dist, (int) angleDeg)); + } + } + + List srcPts = new ArrayList<>(); + PathFinder.splitLineStringIntoPoints(lineSource, 1.0, srcPts); + for (int i = 0; i < srcPts.size(); i++) { + scene.addSource((long) i, factory.createPoint(srcPts.get(i))); + scene.addSourceEmission((long) i, "", roadLvl); + } + + scene.setComputeHorizontalDiffraction(false); + scene.setComputeVerticalDiffraction(false); + scene.setReflexionOrder(0); + scene.maxSrcDist = 800; + + scene.defaultCnossosParameters.setHumidity(70); + scene.defaultCnossosParameters.setTemperature(15); + + AttenuationOutputMultiThread outPoints = new AttenuationOutputMultiThread(scene); + outPoints.noiseMapDatabaseParameters.setMaximumError(0); + PathFinder computeRays = new PathFinder(scene); + computeRays.setThreadCount(1); + computeRays.run(outPoints); + + // === RUN 2: Single line source === + scene.clearSources(); + scene.addSource(1L, lineSource); + scene.addSourceEmission(1L, "", roadLvl); + AttenuationOutputMultiThread outLine = new AttenuationOutputMultiThread(scene); + outLine.noiseMapDatabaseParameters.setMaximumError(maxError); + computeRays.run(outLine); + + // === Compare results === + List pointLevels = new ArrayList<>(outPoints.resultsCache.receiverLevels); + List lineLevels = new ArrayList<>(outLine.resultsCache.receiverLevels); + + int expectedCount = receiverDistances.length * receiverAngles.length; + assertEquals(expectedCount, pointLevels.size(), + "Expected one result per receiver (points)"); + assertEquals(expectedCount, lineLevels.size(), + "Expected one result per receiver (line)"); + + for (int i = 0; i < pointLevels.size(); i++) { + double globalPoints = AcousticIndicatorsFunctions.sumDbArray(pointLevels.get(i).levels); + double globalLine = AcousticIndicatorsFunctions.sumDbArray(lineLevels.get(i).levels); + double diff = Math.abs(globalPoints - globalLine); + if(verbose) { + LOGGER.info("Receiver {} ({}): points={} dB, line={} dB, diff={} dB", i, receiverLabels.get(i), + String.format("%.2f", globalPoints), String.format("%.2f", globalLine), String.format("%.2f", + diff)); + } + assertTrue(diff < maxError, + "Difference between line and point sources at receiver " + i + + " (" + receiverLabels.get(i) + ") is " + String.format("%.2f dB, expected < %.2f dB", diff, maxError)); + } + } + + /** + * Test if HZ fields in Source geometry table is recognized (no time periods) + * @throws Exception + */ + @Test + public void testSceneInputStructureGuessLwInGeometryTable() throws Exception { + try(Connection connection = JDBCUtilities.wrapConnection(H2GISDBFactory.createSpatialDataBase( + "testSceneInputStructureGuessLwInGeometryTable", true, ""))) { + // Insert dummy data + connection.createStatement().execute(Utils.getRunScriptRes("testGeometryWithLWFields.sql")); + NoiseMapByReceiverMaker maker = new NoiseMapByReceiverMaker("BUILDINGS", "SOURCES", "RECEIVERS"); + maker.setGridDim(1); + maker.initialize(connection); + assertEquals(SceneDatabaseInputSettings.INPUT_MODE.INPUT_MODE_LW, maker.getSceneInputSettings().getInputMode(), + "Scene input structure should be correctly identified as having LW in geometry table"); + SceneWithEmission sceneWithEmission = maker.getTableLoader().create(connection, new CellIndex(0, 0), new HashSet<>()); + assertEquals(1, sceneWithEmission.sourceGeometries.size()); + assertTrue(sceneWithEmission.wjSources.containsKey(1L), "Source with PK=1 should be present in wjSources"); + assertEquals(24, sceneWithEmission.wjSources.get(1L).get(0).emission.length); + assertEquals(dBToW(100.0), sceneWithEmission.wjSources.get(1L).get(0).emission[0], 1e-6, + "First frequency band should have correct LW value converted to W"); + } + } } diff --git a/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/TableLoaderTest.java b/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/TableLoaderTest.java index 237b7d9a1..d76194ef3 100644 --- a/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/TableLoaderTest.java +++ b/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/TableLoaderTest.java @@ -13,6 +13,7 @@ import org.h2gis.functions.io.dbf.DBFRead; import org.h2gis.functions.io.shp.SHPRead; import org.h2gis.utilities.JDBCUtilities; +import org.h2gis.utilities.SpatialResultSet; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -24,6 +25,7 @@ import org.noise_planet.noisemodelling.jdbc.railway.RailWayLWGeom; import org.noise_planet.noisemodelling.jdbc.railway.RailWayLWIterator; import org.noise_planet.noisemodelling.jdbc.utils.CellIndex; +import org.noise_planet.noisemodelling.pathfinder.profilebuilder.ProfileBuilder; import org.noise_planet.noisemodelling.pathfinder.utils.AcousticIndicatorsFunctions; import java.io.IOException; @@ -38,12 +40,14 @@ import java.util.stream.Collectors; import static org.junit.jupiter.api.Assertions.*; -import static org.noise_planet.noisemodelling.pathfinder.utils.AcousticIndicatorsFunctions.sumArray; -import static org.noise_planet.noisemodelling.pathfinder.utils.AcousticIndicatorsFunctions.sumDbArray; +import static org.noise_planet.noisemodelling.pathfinder.utils.AcousticIndicatorsFunctions.*; public class TableLoaderTest { private Connection connection; + public static double[] aWeightingArray = Arrays.stream( + asOctaveBands(ProfileBuilder.DEFAULT_FREQUENCIES_A_WEIGHTING_THIRD_OCTAVE)). + mapToDouble(value -> value).toArray(); @BeforeEach public void tearUp() throws Exception { @@ -66,7 +70,7 @@ public void testNoiseEmissionRailWay() throws SQLException, IOException { assertTrue(rs.next()); expectedNumberOfRows = rs.getInt(1); } - RailWayLWIterator railWayLWIterator = new RailWayLWIterator(connection,"RAILTRACK", "RAILTRAIN","RailwayVehiclesCnossos.json","RailwayTrainsets.json", "RailwayCnossosSNCF_2021.json"); + RailWayLWIterator railWayLWIterator = new RailWayLWIterator(connection,"RAILTRACK", "RAILTRAIN","RailwayVehiclesCnossos.json","RailwayTrainsets.json", "RailwayEmissionCnossos.json"); int numberOfRows = 0; while (railWayLWIterator.hasNext()) { @@ -154,6 +158,12 @@ public void testNoiseEmissionRailWay_OC5() throws SQLException, IOException { SHPRead.importTable(connection, TableLoaderTest.class.getResource("Test/OC/RailTrack.shp").getFile()); DBFRead.importTable(connection, TableLoaderTest.class.getResource("Test/OC/RailTrain.dbf").getFile()); + // Update using new string-based identifiers + connection.createStatement().execute("ALTER TABLE RAILTRACK ALTER COLUMN ROUGHNESS VARCHAR"); + connection.createStatement().execute("ALTER TABLE RAILTRACK ALTER COLUMN TRANSFER VARCHAR"); + connection.createStatement().execute("UPDATE RAILTRACK SET ROUGHNESS = CONCAT('SNCF', ROUGHNESS)"); + connection.createStatement().execute("UPDATE RAILTRACK SET TRANSFER = CONCAT('SNCF', TRANSFER)"); + RailWayLWIterator railWayLWIterator = new RailWayLWIterator(connection,"RAILTRACK", "RAILTRAIN"); RailWayLWGeom v = railWayLWIterator.next(); assertNotNull(v); @@ -166,6 +176,47 @@ public void testNoiseEmissionRailWay_OC5() throws SQLException, IOException { } + /** + * Test with SNCF-prefixed string track parameter keys (VARCHAR columns) + * to validate that the merged RailwayEmissionCnossos.json works with properly prefixed keys + * read directly from the database (e.g. "SNCF7", "SNCF1"). + */ + @Test + public void testNoiseEmissionRailWay_OC5_SNCFPrefixed() throws SQLException, IOException { + // Import geometry from existing OC test data + SHPRead.importTable(connection, TableLoaderTest.class.getResource("Test/OC/RailTrack.shp").getFile()); + + // Re-create RAILTRACK with VARCHAR columns for TRANSFER, ROUGHNESS, IMPACT, BRIDGE + // using SNCF-prefixed values matching the merged RailwayEmissionCnossos.json keys + connection.createStatement().execute("ALTER TABLE RAILTRACK DROP COLUMN TRANSFER"); + connection.createStatement().execute("ALTER TABLE RAILTRACK DROP COLUMN ROUGHNESS"); + connection.createStatement().execute("ALTER TABLE RAILTRACK DROP COLUMN IMPACT"); + connection.createStatement().execute("ALTER TABLE RAILTRACK DROP COLUMN BRIDGE"); + connection.createStatement().execute("ALTER TABLE RAILTRACK ADD COLUMN TRANSFER VARCHAR(20)"); + connection.createStatement().execute("ALTER TABLE RAILTRACK ADD COLUMN ROUGHNESS VARCHAR(20)"); + connection.createStatement().execute("ALTER TABLE RAILTRACK ADD COLUMN IMPACT VARCHAR(20)"); + connection.createStatement().execute("ALTER TABLE RAILTRACK ADD COLUMN BRIDGE VARCHAR(20)"); + connection.createStatement().execute("UPDATE RAILTRACK SET TRANSFER='SNCF7', ROUGHNESS='SNCF1', IMPACT='', BRIDGE=''"); + + // Import train traffic data from existing OC test + DBFRead.importTable(connection, TableLoaderTest.class.getResource("Test/OC/RailTrain.dbf").getFile()); + + // Use the merged RailwayEmissionCnossos.json with SNCF-prefixed keys + RailWayLWIterator railWayLWIterator = new RailWayLWIterator(connection, "RAILTRACK", "RAILTRAIN", + "RailwayVehiclesCnossos.json", "RailwayTrainsets.json", "RailwayEmissionCnossos.json"); + RailWayLWGeom v = railWayLWIterator.next(); + assertNotNull(v); + v.setNbTrack(2); + RailWayParameters railWayLW = v.getRailWayLW(); + assertNotNull(railWayLW); + assertFalse(railWayLW.getRailwaySourceList().isEmpty(), "Railway source list should not be empty with SNCF-prefixed keys"); + List geometries = v.getRailWayLWGeometry(); + assertNotNull(geometries); + + v = railWayLWIterator.next(); + assertFalse(railWayLWIterator.hasNext()); + } + @Test public void testNoiseEmissionRailWay_BM() throws SQLException, IOException { double[] dBA = new double[]{-30,-26.2,-22.5,-19.1,-16.1,-13.4,-10.9,-8.6,-6.6,-4.8,-3.2,-1.9,-0.8,0,0.6,1,1.2,1.3,1.2,1,0.5,-0.1,-1.1,-2.5}; @@ -173,9 +224,15 @@ public void testNoiseEmissionRailWay_BM() throws SQLException, IOException { SHPRead.importTable(connection, TableLoaderTest.class.getResource("Test/BM/RailTrack.shp").getFile()); DBFRead.importTable(connection, TableLoaderTest.class.getResource("Test/BM/RailTrain.dbf").getFile()); + // Update using new string-based identifiers + connection.createStatement().execute("ALTER TABLE RAILTRACK ALTER COLUMN ROUGHNESS VARCHAR"); + connection.createStatement().execute("ALTER TABLE RAILTRACK ALTER COLUMN TRANSFER VARCHAR"); + connection.createStatement().execute("UPDATE RAILTRACK SET ROUGHNESS = CONCAT('SNCF', ROUGHNESS)"); + connection.createStatement().execute("UPDATE RAILTRACK SET TRANSFER = CONCAT('SNCF', TRANSFER)"); + HashMap Resultats = new HashMap<>(); - RailWayLWIterator railWayLWIterator = new RailWayLWIterator(connection,"RAILTRACK", "RAILTRAIN","RailwayVehiclesCnossos.json","RailwayTrainsets.json", "RailwayCnossosSNCF_2021.json"); + RailWayLWIterator railWayLWIterator = new RailWayLWIterator(connection,"RAILTRACK", "RAILTRAIN","RailwayVehiclesCnossos.json","RailwayTrainsets.json", "RailwayEmissionCnossos.json"); double resD,resE,resN; while (railWayLWIterator.hasNext()) { @@ -231,7 +288,13 @@ public void testNoiseEmissionRailWay_Section556() throws SQLException, IOExcepti SHPRead.importTable(connection, TableLoaderTest.class.getResource("Test/556/RAIL_SECTIONS.shp").getFile()); DBFRead.importTable(connection, TableLoaderTest.class.getResource("Test/556/RAIL_TRAFIC.dbf").getFile()); - HashMap Resultats = new HashMap<>(); + // Update using new string-based identifiers + connection.createStatement().execute("ALTER TABLE RAIL_SECTIONS ALTER COLUMN ROUGHNESS VARCHAR"); + connection.createStatement().execute("ALTER TABLE RAIL_SECTIONS ALTER COLUMN TRANSFER VARCHAR"); + connection.createStatement().execute("UPDATE RAIL_SECTIONS SET ROUGHNESS = CONCAT('SNCF', ROUGHNESS)"); + connection.createStatement().execute("UPDATE RAIL_SECTIONS SET TRANSFER = CONCAT('SNCF', TRANSFER)"); + + HashMap results = new HashMap<>(); RailWayLWIterator railWayLWIterator = new RailWayLWIterator(connection,"RAIL_SECTIONS", "RAIL_TRAFIC"); @@ -281,9 +344,13 @@ public void testNoiseEmissionRailWay_Section556() throws SQLException, IOExcepti String idSection = v.getIdSection(); - Resultats.put(idSection,new double[]{resD, resE, resN}); + results.put(idSection,new double[]{resD, resE, resN}); } + + // check results + + } @@ -291,9 +358,14 @@ public void testNoiseEmissionRailWay_Section556() throws SQLException, IOExcepti public void testNoiseEmissionRailWayForPropa() throws SQLException, IOException { SHPRead.importTable(connection, TableLoaderTest.class.getResource("PropaRail/Rail_Section2.shp").getFile()); DBFRead.importTable(connection, TableLoaderTest.class.getResource("PropaRail/Rail_Traffic.dbf").getFile()); + // Update using new string-based identifiers + connection.createStatement().execute("ALTER TABLE RAIL_SECTION2 ALTER COLUMN ROUGHNESS VARCHAR"); + connection.createStatement().execute("ALTER TABLE RAIL_SECTION2 ALTER COLUMN TRANSFER VARCHAR"); + connection.createStatement().execute("UPDATE RAIL_SECTION2 SET ROUGHNESS = CONCAT('SNCF', ROUGHNESS)"); + connection.createStatement().execute("UPDATE RAIL_SECTION2 SET TRANSFER = CONCAT('SNCF', TRANSFER)"); EmissionTableGenerator.makeTrainLWTable(connection, "Rail_Section2", "Rail_Traffic", - "LW_RAILWAY", "HZ"); + "LW_RAILWAY", "HZ", RailWayLWIterator.RAILWAY_VEHICLES_CNOSSOS_JSON, RailWayLWIterator.RAILWAY_TRAINSETS_JSON, RailWayLWIterator.RAILWAY_EMISSION_CNOSSOS_JSON); // Get Class to compute LW RailWayLWIterator railWayLWIterator = new RailWayLWIterator(connection,"Rail_Section2", "Rail_Traffic"); @@ -392,7 +464,7 @@ public void testReadFrequencies() throws SQLException, IOException { noiseMap.setFrequencyFieldPrepend("LW"); - noiseMap.initialize(connection, new EmptyProgressVisitor()); + noiseMap.initialize(connection); DefaultTableLoader tableLoader = (DefaultTableLoader)noiseMap.getTableLoader(); @@ -421,7 +493,7 @@ public void testRegression1() throws SQLException, IOException { "LW_ROADS_FENCE", "RECEIVERS"); - noiseMapByReceiverMaker.initialize(connection, new EmptyProgressVisitor()); + noiseMapByReceiverMaker.initialize(connection); Map populatedCells = noiseMapByReceiverMaker.searchPopulatedCells(connection); @@ -429,4 +501,22 @@ public void testRegression1() throws SQLException, IOException { assertEquals(nbReceivers, populatedCells.values().stream().reduce(Integer::sum).orElse(0)); } + @Test + public void testRoadNoiseEmission() throws SQLException, IOException { + try(Statement statement = connection.createStatement()) { + statement.execute("CREATE TABLE IF NOT EXISTS TRAFFIC_TEST (PK SERIAL, LV_D REAL, LV_SPD_D REAL, HGV_D REAL, HGV_SPD_D REAL, PVMT VARCHAR);\n" + + "INSERT INTO TRAFFIC_TEST(LV_D, LV_SPD_D, HGV_D, HGV_SPD_D, PVMT) VALUES (3747.23, 50, 479.02, 50, 'FR_R2');"); + } + Map sourceEmissionFieldsCache = new HashMap<>(); + double globalLevel = 0; + try(SpatialResultSet rs = connection.createStatement().executeQuery("SELECT * FROM TRAFFIC_TEST").unwrap(SpatialResultSet.class)) { + assertTrue(rs.next()); + // new double[][] {ld, le, ln} + double[][] lw = EmissionTableGenerator.computeLw(rs, 1, sourceEmissionFieldsCache); + double[] dbLw = AcousticIndicatorsFunctions.wToDb(lw[0]); + double[] dbALw = AcousticIndicatorsFunctions.sumArray(dbLw, aWeightingArray); + globalLevel = AcousticIndicatorsFunctions.sumArray(AcousticIndicatorsFunctions.dBToW(dbALw)); // add day value only + } + assertEquals(89.6, AcousticIndicatorsFunctions.wToDb(globalLevel), 0.1); + } } \ No newline at end of file diff --git a/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/utils/DatabaseUtilitiesTest.java b/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/utils/DatabaseUtilitiesTest.java new file mode 100644 index 000000000..5c9312aa3 --- /dev/null +++ b/noisemodelling-jdbc/src/test/java/org/noise_planet/noisemodelling/jdbc/utils/DatabaseUtilitiesTest.java @@ -0,0 +1,43 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

+ * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

+ * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.jdbc.utils; + +import org.h2gis.functions.factory.H2GISDBFactory; +import org.h2gis.utilities.JDBCUtilities; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; + +import java.sql.Connection; +import java.sql.SQLException; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class DatabaseUtilitiesTest { + + private Connection connection; + @BeforeEach + public void tearUp() throws Exception { + connection = JDBCUtilities.wrapConnection(H2GISDBFactory.createSpatialDataBase(DatabaseUtilitiesTest.class.getSimpleName(), true, "")); + } + + @AfterEach + public void tearDown() throws Exception { + if(connection != null) { + connection.close(); + } + } + + @org.junit.jupiter.api.Test + public void testIsMetric() throws SQLException { + assertTrue(DataBaseUtilities.isSridMetric(connection, 2154)); + assertFalse(DataBaseUtilities.isSridMetric(connection, 4326)); + assertTrue(DataBaseUtilities.isSridMetric(connection, 3857)); + } +} diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/SPARSE_BUILDINGS.geojson b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/SPARSE_BUILDINGS.geojson new file mode 100644 index 000000000..ba2593ca6 --- /dev/null +++ b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/SPARSE_BUILDINGS.geojson @@ -0,0 +1,17 @@ +{ +"type": "FeatureCollection", +"name": "SPARSE_BUILDINGS", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::25830" } }, +"features": [ +{ "type": "Feature", "properties": { "PK": 10969, "HEIGHT": 6.0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 80161.860002701054327, 4833066.852778820320964 ], [ 80169.869061314035207, 4833066.454220755025744 ], [ 80169.470503664633725, 4833058.445162490010262 ], [ 80161.471440037305001, 4833058.84299670625478 ], [ 80161.860002701054327, 4833066.852778820320964 ] ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 11051, "HEIGHT": 6.0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 80177.683659280999564, 4833031.285758446902037 ], [ 80177.965240004006773, 4833036.289069429971278 ], [ 80183.469026502978522, 4833035.981329499743879 ], [ 80184.437674048764165, 4833052.981722740456462 ], [ 80190.441935708629899, 4833052.64782256539911 ], [ 80189.190984554530587, 4833030.63412518799305 ], [ 80177.683659280999564, 4833031.285758446902037 ] ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 52002, "HEIGHT": 6.0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 56080.236868263222277, 4771893.160226408392191 ], [ 56071.475574310403317, 4771894.732260803692043 ], [ 56073.798237371724099, 4771907.660668190568686 ], [ 56073.951942767540459, 4771908.544082844629884 ], [ 56075.092216819466557, 4771915.065067369490862 ], [ 56076.800851418287493, 4771924.89189463108778 ], [ 56085.436129299399909, 4771921.721435539424419 ], [ 56121.4263957234798, 4771908.54138657823205 ], [ 56119.843596900755074, 4771899.48942793905735 ], [ 56117.505210357252508, 4771886.4817562289536 ], [ 56110.360772794287186, 4771887.757118243724108 ], [ 56110.06837262964109, 4771886.059562499634922 ], [ 56109.254101179947611, 4771881.424673886038363 ], [ 56094.737408430024516, 4771884.021859549917281 ], [ 56095.62673041888047, 4771889.003113359212875 ], [ 56095.864077237143647, 4771890.352873080410063 ], [ 56080.236868263222277, 4771893.160226408392191 ] ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 77856, "HEIGHT": 12.0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -5218.092880871030502, 4775419.805283922702074 ], [ -5215.316854651377071, 4775426.827393616549671 ], [ -5207.989677675417624, 4775423.536711522378027 ], [ -5210.928724291734397, 4775416.204454878345132 ], [ -5215.211501885496546, 4775418.331643437035382 ], [ -5218.092880871030502, 4775419.805283922702074 ] ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 80384, "HEIGHT": 6.0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -5211.023607755894773, 4775497.437510111369193 ], [ -5210.515927983098663, 4775495.25897079333663 ], [ -5218.052182536222972, 4775493.526026429608464 ], [ -5218.342819418874569, 4775494.663189637474716 ], [ -5218.325772261829115, 4775494.669511063024402 ], [ -5212.272412438818719, 4775496.964290008880198 ], [ -5211.023607755894773, 4775497.437510111369193 ] ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 80385, "HEIGHT": 9.0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -5204.591646414715797, 4775479.26609661616385 ], [ -5204.784337604069151, 4775477.278537680394948 ], [ -5217.863189820549451, 4775478.617902361787856 ], [ -5216.697159170755185, 4775489.979351364076138 ], [ -5214.980472064577043, 4775489.796010376885533 ], [ -5214.859439565509092, 4775490.923792188055813 ], [ -5213.332861687638797, 4775490.754072255454957 ], [ -5213.46246613265248, 4775489.647018854506314 ], [ -5200.064147841418162, 4775488.27470603492111 ], [ -5200.501085560128558, 4775483.860769413411617 ], [ -5205.422447767690755, 4775484.37429179623723 ], [ -5206.058906577178277, 4775479.421509193256497 ], [ -5204.591646414715797, 4775479.26609661616385 ] ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 80386, "HEIGHT": 12.0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -5204.591646414715797, 4775479.26609661616385 ], [ -5206.058906577178277, 4775479.421509193256497 ], [ -5205.422447767690755, 4775484.37429179623723 ], [ -5200.501085560128558, 4775483.860769413411617 ], [ -5201.016758459329139, 4775478.909390083514154 ], [ -5204.591646414715797, 4775479.26609661616385 ] ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 82367, "HEIGHT": 6.0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -5167.123484180134255, 4775458.006084401160479 ], [ -5172.095585513277911, 4775425.807474149391055 ], [ -5182.086837074253708, 4775427.42846579477191 ], [ -5176.837472065701149, 4775459.426186511293054 ], [ -5167.123484180134255, 4775458.006084401160479 ] ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 123899, "HEIGHT": 9.0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 23612.718799001420848, 4739509.195243808440864 ], [ 23617.618566322664265, 4739512.495669572614133 ], [ 23618.74634156859247, 4739510.826934972777963 ], [ 23622.10431598010473, 4739513.081025155261159 ], [ 23630.959969657997135, 4739499.933520769700408 ], [ 23622.702017646224704, 4739494.368965859524906 ], [ 23619.000866809568834, 4739499.860254124738276 ], [ 23612.718799001420848, 4739509.195243808440864 ] ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 124200, "HEIGHT": 9.0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 23610.638181187445298, 4739494.095555815845728 ], [ 23605.538662376406137, 4739501.542769785039127 ], [ 23605.342303414014168, 4739501.827689703553915 ], [ 23608.902476637915242, 4739504.217678520828485 ], [ 23607.765669232525397, 4739505.858404481783509 ], [ 23612.718799001420848, 4739509.195243808440864 ], [ 23619.000866809568834, 4739499.860254124738276 ], [ 23621.84367823402863, 4739495.642519230023026 ], [ 23622.702017646224704, 4739494.368965859524906 ], [ 23614.440120165236294, 4739488.544310073368251 ], [ 23613.609550614026375, 4739489.756068754941225 ], [ 23610.638181187445298, 4739494.095555815845728 ] ] ] ] } } +] +} diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/SPARSE_ROADS.geojson b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/SPARSE_ROADS.geojson new file mode 100644 index 000000000..90cd47a4e --- /dev/null +++ b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/SPARSE_ROADS.geojson @@ -0,0 +1,13 @@ +{ +"type": "FeatureCollection", +"name": "SPARSE_ROADS", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::25830" } }, +"features": [ +{ "type": "Feature", "properties": { "PK": 743, "LWD63": 80.3486155561326, "LWD125": 82.104336191012351, "LWD250": 80.78996746676458, "LWD500": 81.836515280118135, "LWD1000": 88.225840704315488, "LWD2000": 85.913447656227987, "LWD4000": 77.314256600968577, "LWD8000": 68.30124722811469, "LWE63": 80.076866302497066, "LWE125": 81.168523384491465, "LWE250": 80.077806804601323, "LWE500": 81.322883569696259, "LWE1000": 87.118596162986591, "LWE2000": 84.682493246479964, "LWE4000": 76.171564437338318, "LWE8000": 67.422480142111255, "LWN63": 74.632789126841459, "LWN125": 75.132279956060032, "LWN250": 74.26054232775536, "LWN500": 75.682530319356644, "LWN1000": 80.898352918914881, "LWN2000": 78.319617447395672, "LWN4000": 69.911339583674419, "LWN8000": 61.444236920757042 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 56052.517237801752344, 4772072.618361883796751, 0.05 ], [ 56047.884300000034273, 4771896.700200000777841, 0.05 ], [ 55970.999863491582801, 4771581.933159243315458, 0.05 ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 7107, "LWD63": 84.598149266889038, "LWD125": 79.113372452136659, "LWD250": 77.8589530401606, "LWD500": 78.441370335238474, "LWD1000": 81.751359167933828, "LWD2000": 78.414936879637565, "LWD4000": 70.805957145654347, "LWD8000": 63.309246099924721, "LWE63": 80.091537453027598, "LWE125": 74.846067618433082, "LWE250": 73.548395677861549, "LWE500": 74.228234577527161, "LWE1000": 78.056763989040164, "LWE2000": 74.84237869700334, "LWE4000": 67.012684863547378, "LWE8000": 59.223075815425616, "LWN63": 74.018401076213308, "LWN125": 69.141077717876385, "LWN250": 67.780588269503539, "LWN500": 68.599800820575936, "LWN1000": 73.060477331307411, "LWN2000": 69.972764248012538, "LWN4000": 61.908460874110474, "LWN8000": 53.76543902767483 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -5257.488900000229478, 4774948.592000000178814, 0.05 ], [ -5213.488800000399351, 4775309.595300000160933, 0.05 ], [ -5197.320968560166875, 4775444.958329167217016, 0.05 ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 7108, "LWD63": 84.598149266889038, "LWD125": 79.113372452136659, "LWD250": 77.8589530401606, "LWD500": 78.441370335238474, "LWD1000": 81.751359167933828, "LWD2000": 78.414936879637565, "LWD4000": 70.805957145654347, "LWD8000": 63.309246099924721, "LWE63": 80.091537453027598, "LWE125": 74.846067618433082, "LWE250": 73.548395677861549, "LWE500": 74.228234577527161, "LWE1000": 78.056763989040164, "LWE2000": 74.84237869700334, "LWE4000": 67.012684863547378, "LWE8000": 59.223075815425616, "LWN63": 74.018401076213308, "LWN125": 69.141077717876385, "LWN250": 67.780588269503539, "LWN500": 68.599800820575936, "LWN1000": 73.060477331307411, "LWN2000": 69.972764248012538, "LWN4000": 61.908460874110474, "LWN8000": 53.76543902767483 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -5197.320968560166875, 4775444.958329167217016, 0.05 ], [ -5170.489900000393391, 4775669.597899999469519, 0.05 ], [ -5076.786293628678322, 4775926.825857835821807, 0.05 ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 8440, "LWD63": 73.22441312882448, "LWD125": 66.343761542383547, "LWD250": 64.815629033394956, "LWD500": 65.236295458784753, "LWD1000": 67.725736434380451, "LWD2000": 64.121563640174756, "LWD4000": 57.244764210956077, "LWD8000": 49.86582315885709, "LWE63": 71.235132207640376, "LWE125": 64.302225825760601, "LWE250": 62.720487511378948, "LWE500": 63.322831913053925, "LWE1000": 66.472676902151392, "LWE2000": 62.994942650837757, "LWE4000": 55.850840020706968, "LWE8000": 48.152492104930602, "LWN63": 62.121388874725916, "LWN125": 54.985455812221396, "LWN250": 53.182334133593578, "LWN500": 54.483799094073369, "LWN1000": 59.368384544460959, "LWN2000": 56.133591827991829, "LWN4000": 48.449543544266767, "LWN8000": 39.945860560070322 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 23301.010099999606609, 4739127.30519999936223, 0.05 ], [ 23451.011400000192225, 4739357.307, 0.05 ], [ 23610.073733090513997, 4739517.01789503917098, 0.05 ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 8441, "LWD63": 73.22441312882448, "LWD125": 66.343761542383547, "LWD250": 64.815629033394956, "LWD500": 65.236295458784753, "LWD1000": 67.725736434380451, "LWD2000": 64.121563640174756, "LWD4000": 57.244764210956077, "LWD8000": 49.86582315885709, "LWE63": 71.235132207640376, "LWE125": 64.302225825760601, "LWE250": 62.720487511378948, "LWE500": 63.322831913053925, "LWE1000": 66.472676902151392, "LWE2000": 62.994942650837757, "LWE4000": 55.850840020706968, "LWE8000": 48.152492104930602, "LWN63": 62.121388874725916, "LWN125": 54.985455812221396, "LWN250": 53.182334133593578, "LWN500": 54.483799094073369, "LWN1000": 59.368384544460959, "LWN2000": 56.133591827991829, "LWN4000": 48.449543544266767, "LWN8000": 39.945860560070322 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 23610.073733090513997, 4739517.01789503917098, 0.05 ], [ 23800.424599999561906, 4739708.144899999722838, 0.05 ], [ 23916.336500000208616, 4739900.904400000348687, 0.05 ], [ 23918.969178123097663, 4739905.5361303742975, 0.05 ] ] ] } }, +{ "type": "Feature", "properties": { "PK": 10941, "LWD63": 87.828961208847133, "LWD125": 83.643041037189093, "LWD250": 82.350232552383716, "LWD500": 82.711616780159559, "LWD1000": 87.352956832089859, "LWD2000": 84.767909994842967, "LWD4000": 76.653055939564695, "LWD8000": 68.526339120124902, "LWE63": 88.509302532662204, "LWE125": 83.719278028229795, "LWE250": 82.513353790589733, "LWE500": 82.848522595280542, "LWE1000": 86.682160312701853, "LWE2000": 83.88426948939815, "LWE4000": 76.04011824560142, "LWE8000": 68.348526892483505, "LWN63": 83.518153310686628, "LWN125": 78.334266791290091, "LWN250": 77.190774653296472, "LWN500": 77.507331324692345, "LWN1000": 80.656222093991687, "LWN2000": 77.633069914846203, "LWN4000": 70.07163521081813, "LWN8000": 62.767922150702489 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 80163.17578007587872, 4832824.531530040316284, 0.05 ], [ 80150.767599999904633, 4833080.2511, 0.05 ], [ 80170.591018238148536, 4833323.424005336128175, 0.05 ] ] ] } } +] +} diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/delaunaytest/buildings.geojson.gz b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/delaunaytest/buildings.geojson.gz new file mode 100644 index 000000000..1fde10332 Binary files /dev/null and b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/delaunaytest/buildings.geojson.gz differ diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/delaunaytest/sources.geojson.gz b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/delaunaytest/sources.geojson.gz new file mode 100644 index 000000000..ebb449cf5 Binary files /dev/null and b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/delaunaytest/sources.geojson.gz differ diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrack.cpg b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrack.cpg rename to noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.cpg diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.dbf b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.dbf new file mode 100644 index 000000000..9391869ed Binary files /dev/null and b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.dbf differ diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.prj b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.prj new file mode 100644 index 000000000..12f46005d --- /dev/null +++ b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.prj @@ -0,0 +1 @@ +PROJCS["WGS_1984_UTM_Zone_33N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",15.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.qmd b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.qmd new file mode 100644 index 000000000..d686fc086 --- /dev/null +++ b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.qmd @@ -0,0 +1,27 @@ + + + + + + dataset + + + + + + + + + PROJCRS["WGS 84 / UTM zone 33N",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["UTM zone 33N",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",15,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Navigation and medium accuracy spatial referencing."],AREA["Between 12°E and 18°E, northern hemisphere between equator and 84°N, onshore and offshore. Austria. Bosnia and Herzegovina. Cameroon. Central African Republic. Chad. Congo. Croatia. Czechia. Democratic Republic of the Congo (Zaire). Gabon. Germany. Hungary. Italy. Libya. Malta. Niger. Nigeria. Norway. Poland. San Marino. Slovakia. Slovenia. Svalbard. Sweden. Vatican City State."],BBOX[0,12,84,18]],ID["EPSG",32633]] + +proj=utm +zone=33 +datum=WGS84 +units=m +no_defs + 3117 + 32633 + EPSG:32633 + WGS 84 / UTM zone 33N + utm + EPSG:7030 + false + + + + diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.shp b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.shp new file mode 100644 index 000000000..79bc27ba1 Binary files /dev/null and b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.shp differ diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.shx b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.shx new file mode 100644 index 000000000..332262646 Binary files /dev/null and b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/buldings_test.shx differ diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/buildings2.cpg b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/buildings2.cpg rename to noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.cpg diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.dbf b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.dbf new file mode 100644 index 000000000..8ba7eda24 Binary files /dev/null and b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.dbf differ diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.prj b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.prj new file mode 100644 index 000000000..12f46005d --- /dev/null +++ b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.prj @@ -0,0 +1 @@ +PROJCS["WGS_1984_UTM_Zone_33N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",15.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.qmd b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.qmd new file mode 100644 index 000000000..d686fc086 --- /dev/null +++ b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.qmd @@ -0,0 +1,27 @@ + + + + + + dataset + + + + + + + + + PROJCRS["WGS 84 / UTM zone 33N",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["UTM zone 33N",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",15,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Navigation and medium accuracy spatial referencing."],AREA["Between 12°E and 18°E, northern hemisphere between equator and 84°N, onshore and offshore. Austria. Bosnia and Herzegovina. Cameroon. Central African Republic. Chad. Congo. Croatia. Czechia. Democratic Republic of the Congo (Zaire). Gabon. Germany. Hungary. Italy. Libya. Malta. Niger. Nigeria. Norway. Poland. San Marino. Slovakia. Slovenia. Svalbard. Sweden. Vatican City State."],BBOX[0,12,84,18]],ID["EPSG",32633]] + +proj=utm +zone=33 +datum=WGS84 +units=m +no_defs + 3117 + 32633 + EPSG:32633 + WGS 84 / UTM zone 33N + utm + EPSG:7030 + false + + + + diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.shp b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.shp new file mode 100644 index 000000000..a56535aee Binary files /dev/null and b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.shp differ diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.shx b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.shx new file mode 100644 index 000000000..c5a763612 Binary files /dev/null and b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/receivers_test.shx differ diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/receivers_Railway_.cpg b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/receivers_Railway_.cpg rename to noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.cpg diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.dbf b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.dbf new file mode 100644 index 000000000..4d2277170 Binary files /dev/null and b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.dbf differ diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.prj b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.prj new file mode 100644 index 000000000..12f46005d --- /dev/null +++ b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.prj @@ -0,0 +1 @@ +PROJCS["WGS_1984_UTM_Zone_33N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",15.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.qmd b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.qmd new file mode 100644 index 000000000..4af55e635 --- /dev/null +++ b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.qmd @@ -0,0 +1,44 @@ + + + + + + dataset + + + + + + + + + + + + + + + + + + PROJCRS["WGS 84 / UTM zone 33N",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["UTM zone 33N",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",15,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Navigation and medium accuracy spatial referencing."],AREA["Between 12°E and 18°E, northern hemisphere between equator and 84°N, onshore and offshore. Austria. Bosnia and Herzegovina. Cameroon. Central African Republic. Chad. Congo. Croatia. Czechia. Democratic Republic of the Congo (Zaire). Gabon. Germany. Hungary. Italy. Libya. Malta. Niger. Nigeria. Norway. Poland. San Marino. Slovakia. Slovenia. Svalbard. Sweden. Vatican City State."],BBOX[0,12,84,18]],ID["EPSG",32633]] + +proj=utm +zone=33 +datum=WGS84 +units=m +no_defs + 3117 + 32633 + EPSG:32633 + WGS 84 / UTM zone 33N + utm + EPSG:7030 + false + + + + + + + + + + + + diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.shp b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.shp new file mode 100644 index 000000000..2595f7372 Binary files /dev/null and b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.shp differ diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.shx b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.shx new file mode 100644 index 000000000..693082172 Binary files /dev/null and b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/dynamicConfMaxErrorTest/sources_test.shx differ diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/scenario_skip_far_source.sql b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/scenario_skip_far_source.sql index 0d0cabd37..26225ccea 100644 --- a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/scenario_skip_far_source.sql +++ b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/scenario_skip_far_source.sql @@ -37,7 +37,7 @@ VALUES(7482, 'SRID=2154; LINESTRING Z(376800.1 6667058.5 0.05, 376839.2 6667115. DROP TABLE IF EXISTS RECEIVERS; CREATE TABLE RECEIVERS(the_geom GEOMETRY(POINTZ), GID SERIAL PRIMARY KEY); -INSERT INTO RECEIVERS(the_geom) VALUES ('SRID=2154; POINTZ(375773.1272896934 6667129.820221064 4)'); +INSERT INTO RECEIVERS(the_geom) VALUES ('SRID=2154; POINTZ(375821.14511295804 6667083.880145698 4)'); CREATE TABLE PUBLIC.BUILDINGS ( diff --git a/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/testGeometryWithLWFields.sql b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/testGeometryWithLWFields.sql new file mode 100644 index 000000000..5f0a8a340 --- /dev/null +++ b/noisemodelling-jdbc/src/test/resources/org/noise_planet/noisemodelling/jdbc/testGeometryWithLWFields.sql @@ -0,0 +1,47 @@ +CREATE CACHED TABLE "PUBLIC"."SOURCES"( + "PK" INTEGER NOT NULL PRIMARY KEY, + "THE_GEOM" GEOMETRY, + "HZ50" DOUBLE PRECISION, + "HZ63" DOUBLE PRECISION, + "HZ80" DOUBLE PRECISION, + "HZ100" DOUBLE PRECISION, + "HZ125" DOUBLE PRECISION, + "HZ160" DOUBLE PRECISION, + "HZ200" DOUBLE PRECISION, + "HZ250" DOUBLE PRECISION, + "HZ315" DOUBLE PRECISION, + "HZ400" DOUBLE PRECISION, + "HZ500" DOUBLE PRECISION, + "HZ630" DOUBLE PRECISION, + "HZ800" DOUBLE PRECISION, + "HZ1000" DOUBLE PRECISION, + "HZ1250" DOUBLE PRECISION, + "HZ1600" DOUBLE PRECISION, + "HZ2000" DOUBLE PRECISION, + "HZ2500" DOUBLE PRECISION, + "HZ3150" DOUBLE PRECISION, + "HZ4000" DOUBLE PRECISION, + "HZ5000" DOUBLE PRECISION, + "HZ6300" DOUBLE PRECISION, + "HZ8000" DOUBLE PRECISION, + "HZ10000" DOUBLE PRECISION +); + +INSERT INTO SOURCES VALUES (1, 'POINTZ (304149 2252906 0.2)', 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100); + +-- Buildings table +drop table if exists buildings; +create table buildings ( the_geom GEOMETRY, height double ); +insert into buildings values +('POLYGON ((304081.971140762 2252842.2377583543, 304087.2927055786 2252852.3894956196, 304120.9740158394 2252833.548805693, 304115.1308573535 2252825.994945729, 304111.00898608495 2252828.2631819816, 304109.4290281007 2252825.6481492408, 304098.86882524966 2252831.967185081, 304100.45122728107 2252834.281990951, 304081.971140762 2252842.2377583543))', 18), +('POLYGON ((304066.507676677 2252934.287102647, 304066.8030005697 2252934.890006138, 304080.97572407214 2252927.3994797524, 304076.9437141237 2252918.6594214477, 304071.7177355701 2252921.3189708022, 304070.2378479165 2252918.7047548825, 304067.5243737129 2252920.0837501315, 304069.2019599965 2252922.9998262255, 304066.58774516406 2252924.4797140043, 304065.2079349268 2252921.866315325, 304062.0925250804 2252923.4421931794, 304061.1885783817 2252923.8351413365, 304066.507676677 2252934.287102647))', 6), +('POLYGON ((304116.64878738014 2252885.2559329206, 304110.6548854257 2252883.905929764, 304107.2804970879 2252892.685601917, 304111.92112771556 2252900.4298086576, 304118.5497980566 2252897.5815475294, 304112.3680011234 2252894.728779357, 304116.64878738014 2252885.2559329206))', 4), +('POLYGON ((304116.8496270616 2252909.677588094, 304135.2385924306 2252900.620172194, 304130.6061355095 2252891.875211711, 304116.6486897959 2252885.2559239715, 304112.3678984563 2252894.7287699394, 304118.54969539 2252897.5815381147, 304111.9210250483 2252900.42979924, 304116.8496270616 2252909.677588094))', 14), +('POLYGON ((304147.06500050006 2252935.3451201664, 304148.63721490436 2252926.6508168606, 304144.60684562515 2252917.710608132, 304115.06539856613 2252932.0814030115, 304121.1687605225 2252944.541408861, 304142.47134331334 2252934.106631618, 304147.06500050006 2252935.3451201664))', 15), +('POLYGON ((304025.02294641937 2252903.723622542, 304025.4158539388 2252904.6275655366, 304026.60040863417 2252906.6388771087, 304028.6742245948 2252910.05859954, 304055.60392891726 2252896.867466023, 304063.6704399612 2252914.0473602274, 304065.45140236564 2252916.56395479, 304073.6910965696 2252912.527862693, 304054.0027388107 2252872.33428636, 304018.5265914384 2252890.3596659536, 304025.02294641937 2252903.723622542))', 14); + +-- Receivers table + +CREATE TABLE RECEIVERS(the_geom GEOMETRY(POINTZ), GID SERIAL PRIMARY KEY); +INSERT INTO RECEIVERS(the_geom) VALUES ('POINTZ(304100 2252900 1.6)'); \ No newline at end of file diff --git a/noisemodelling-pathfinder/pom.xml b/noisemodelling-pathfinder/pom.xml index 555cd047c..79dd91ec8 100644 --- a/noisemodelling-pathfinder/pom.xml +++ b/noisemodelling-pathfinder/pom.xml @@ -10,7 +10,7 @@ org.noise-planet noisemodelling-parent - 5.0.2-SNAPSHOT + 6.0.1-SNAPSHOT ../pom.xml Compute sound propagation rays. diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/PathFinder.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/PathFinder.java index 4133597ce..1cc1defc1 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/PathFinder.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/PathFinder.java @@ -24,10 +24,8 @@ import org.noise_planet.noisemodelling.pathfinder.path.MirrorReceiversCompute; import org.noise_planet.noisemodelling.pathfinder.path.MirrorReceiver; import org.noise_planet.noisemodelling.pathfinder.profilebuilder.*; -import org.noise_planet.noisemodelling.pathfinder.utils.geometry.CurvedProfileGenerator; import org.noise_planet.noisemodelling.pathfinder.utils.geometry.Orientation; import org.noise_planet.noisemodelling.pathfinder.utils.geometry.JTSUtility; -import org.noise_planet.noisemodelling.pathfinder.utils.geometry.QueryRTree; import org.noise_planet.noisemodelling.pathfinder.utils.profiler.ProfilerThread; import org.noise_planet.noisemodelling.pathfinder.utils.profiler.ReceiverStatsMetric; import org.slf4j.Logger; @@ -42,7 +40,6 @@ import static java.lang.Double.isNaN; import static java.lang.Math.*; import static org.noise_planet.noisemodelling.pathfinder.PathFinder.ComputationSide.LEFT; -import static org.noise_planet.noisemodelling.pathfinder.PathFinder.ComputationSide.RIGHT; /** * @author Nicolas Fortin @@ -489,8 +486,6 @@ public List computeSideHull(boolean left, Coordinate p1, Coordinate int indexp1 = 0; int indexp2 = 0; - boolean convexHullIntersects = true; - input.add(p1); input.add(p2); @@ -506,81 +501,57 @@ public List computeSideHull(boolean left, Coordinate p1, Coordinate data.profileBuilder.getWallsOnPath(p1, p2, buildingIntersectionPathVisitor); int k; - while (convexHullIntersects) { - ConvexHull convexHull = new ConvexHull(input.toArray(new Coordinate[0]), GEOMETRY_FACTORY); - Geometry convexhull = convexHull.getConvexHull(); - - coordinates = convexhull.getCoordinates(); - // for the length we do not count the return ray from receiver to source (closed polygon here) - double convexHullLength = Length.ofLine( - CoordinateArraySequenceFactory.instance() - .create(Arrays.copyOfRange(coordinates, 0, coordinates.length - 1))); - if (convexHullLength / p1.distance(p2) > MAX_RATIO_HULL_DIRECT_PATH || - convexHullLength >= data.maxSrcDist) { - return new ArrayList<>(); - } - convexHullIntersects = false; + ConvexHull convexHull = new ConvexHull(input.toArray(new Coordinate[0]), GEOMETRY_FACTORY); + Geometry convexhull = convexHull.getConvexHull(); - input.clear(); - input.addAll(Arrays.asList(coordinates)); - - indexp1 = -1; - for (int i = 0; i < coordinates.length - 1; i++) { - if (coordinates[i].equals(p1)) { - indexp1 = i; - break; - } - } - if (indexp1 == -1) { - // P1 does not belong to convex vertices, cannot compute diffraction - // TODO handle concave path - return new ArrayList<>(); - } - // Transform array to set p1 at index=0 - Coordinate[] coordinatesShifted = new Coordinate[coordinates.length]; - // Copy from P1 to end in beginning of new array - int len = (coordinates.length - 1) - indexp1; - System.arraycopy(coordinates, indexp1, coordinatesShifted, 0, len); - // Copy from 0 to P1 in the end of array - System.arraycopy(coordinates, 0, coordinatesShifted, len, coordinates.length - len - 1); - coordinatesShifted[coordinatesShifted.length - 1] = coordinatesShifted[0]; - coordinates = coordinatesShifted; - indexp1 = 0; - indexp2 = -1; - for (int i = 1; i < coordinates.length - 1; i++) { - if (coordinates[i].equals(p2)) { - indexp2 = i; - break; - } - } - if (indexp2 == -1) { - // P2 does not belong to convex vertices, cannot compute diffraction - // TODO handle concave path - return new ArrayList<>(); - } - for (k = 0; k < coordinates.length - 1; k++) { - LineSegment freeFieldTestSegment = new LineSegment(coordinates[k], coordinates[k + 1]); - - // Ignore intersection if iterating over other side (not parts of what is returned) - if (left && k < indexp2 || !left && k >= indexp2) { - if (!freeFieldSegments.contains(freeFieldTestSegment)) { - - int inputPointsBefore = input.size(); + coordinates = convexhull.getCoordinates(); + // for the length we do not count the return ray from receiver to source (closed polygon here) + double convexHullLength = Length.ofLine( + CoordinateArraySequenceFactory.instance() + .create(Arrays.copyOfRange(coordinates, 0, coordinates.length - 1))); + if (convexHullLength / p1.distance(p2) > MAX_RATIO_HULL_DIRECT_PATH || + convexHullLength >= data.maxSrcDist) { + return new ArrayList<>(); + } - // Visit buildings that are between the provided hull points - data.profileBuilder.getWallsOnPath(coordinates[k], coordinates[k + 1], buildingIntersectionPathVisitor); + input.clear(); + input.addAll(Arrays.asList(coordinates)); - if (inputPointsBefore == input.size()) { - freeFieldSegments.add(freeFieldTestSegment); - } else { - convexHullIntersects = true; - break; - } - } - } + indexp1 = -1; + for (int i = 0; i < coordinates.length - 1; i++) { + if (coordinates[i].equals(p1)) { + indexp1 = i; + break; } } + if (indexp1 == -1) { + // P1 does not belong to convex vertices, cannot compute diffraction + // TODO handle concave path + return new ArrayList<>(); + } + // Transform array to set p1 at index=0 + Coordinate[] coordinatesShifted = new Coordinate[coordinates.length]; + // Copy from P1 to end in beginning of new array + int len = (coordinates.length - 1) - indexp1; + System.arraycopy(coordinates, indexp1, coordinatesShifted, 0, len); + // Copy from 0 to P1 in the end of array + System.arraycopy(coordinates, 0, coordinatesShifted, len, coordinates.length - len - 1); + coordinatesShifted[coordinatesShifted.length - 1] = coordinatesShifted[0]; + coordinates = coordinatesShifted; + indexp1 = 0; + indexp2 = -1; + for (int i = 1; i < coordinates.length - 1; i++) { + if (coordinates[i].equals(p2)) { + indexp2 = i; + break; + } + } + if (indexp2 == -1) { + // P2 does not belong to convex vertices, cannot compute diffraction + // TODO handle concave path + return new ArrayList<>(); + } // restore coordinates order from source to receiver if (left) { @@ -830,11 +801,14 @@ public static double splitLineStringIntoPoints(LineString geom, double segmentSi // Return mid point Coordinate[] points = geom.getCoordinates(); double segmentLength = 0; - final double targetSegmentSize = geomLength / 2.0; + final double targetSegmentSize = geomLength / 2.0; // take middle point for (int i = 0; i < points.length - 1; i++) { Coordinate a = points[i]; final Coordinate b = points[i + 1]; double length = a.distance3D(b); + if(Double.isNaN(length)) { + length = a.distance(b); + } if (length + segmentLength > targetSegmentSize) { double segmentLengthFraction = (targetSegmentSize - segmentLength) / length; Coordinate midPoint = new Coordinate(a.x + segmentLengthFraction * (b.x - a.x), @@ -847,7 +821,7 @@ public static double splitLineStringIntoPoints(LineString geom, double segmentSi } return geom.getLength(); } else { - double targetSegmentSize = geomLength / ceil(geomLength / segmentSizeConstraint); + double targetSegmentSize = Math.max(1, geomLength / ceil(geomLength / segmentSizeConstraint)); Coordinate[] points = geom.getCoordinates(); double segmentLength = 0.; @@ -897,110 +871,6 @@ public static double splitLineStringIntoPoints(LineString geom, double segmentSi } - /** - * Apply a linestring over the digital elevation model by offsetting the z value with the ground elevation. - * @param lineString - * @param profileBuilder - * @param epsilon ignore elevation point where linear interpolation distance is inferior that this value - * @return computed lineString - */ - private static LineString splitLineSource(LineString lineString, ProfileBuilder profileBuilder, double epsilon) { - boolean warned = false; - ArrayList newGeomCoordinates = new ArrayList<>(); - Coordinate[] coordinates = lineString.getCoordinates(); - for(int idPoint = 0; idPoint < coordinates.length - 1; idPoint++) { - Coordinate p0 = coordinates[idPoint]; - Coordinate p1 = coordinates[idPoint + 1]; - List groundProfileCoordinates = new ArrayList<>(); - profileBuilder.fetchTopographicProfile(groundProfileCoordinates, p0, p1, false); - newGeomCoordinates.ensureCapacity(newGeomCoordinates.size() + groundProfileCoordinates.size()); - if(groundProfileCoordinates.size() < 2) { - if(profileBuilder.hasDem()) { - if(!warned) { - LOGGER.warn( "Source line out of DEM area {}", - new WKTWriter(3).write(lineString)); - warned = true; - } - } - newGeomCoordinates.add(p0); - newGeomCoordinates.add(p1); - } else { - if (idPoint == 0) { - newGeomCoordinates.add(new Coordinate(p0.x, p0.y, p0.z + groundProfileCoordinates.get(0).z)); - } - Coordinate previous = groundProfileCoordinates.get(0); - for (int groundPoint = 1; groundPoint < groundProfileCoordinates.size() - 1; groundPoint++) { - final Coordinate current = groundProfileCoordinates.get(groundPoint); - final Coordinate next = groundProfileCoordinates.get(groundPoint + 1); - // Do not add topographic points which are simply the linear interpolation between two points - // triangulation add a lot of interpolated lines from line segment DEM - if (CGAlgorithms3D.distancePointSegment(current, previous, next) >= epsilon) { - // interpolate the Z (height) values of the source then add the altitude - previous = current; - newGeomCoordinates.add( - new Coordinate(current.x, current.y, current.z + Vertex.interpolateZ(current, p0, p1))); - } - } - newGeomCoordinates.add(new Coordinate(p1.x, p1.y, p1.z + - groundProfileCoordinates.get(groundProfileCoordinates.size() - 1).z)); - } - } - return GEOMETRY_FACTORY.createLineString(newGeomCoordinates.toArray(new Coordinate[0])); - } - - /** - * Update ground Z coordinates of sound sources absolute to sea levels - */ - public void makeSourceRelativeZToAbsolute() { - List sourceCopy = new ArrayList<>(data.sourceGeometries.size()); - for (Geometry source : data.sourceGeometries) { - Geometry offsetGeometry; - if (source instanceof LineString) { - offsetGeometry = splitLineSource((LineString) source, data.profileBuilder, ProfileBuilder.MILLIMETER); - } else if (source instanceof MultiLineString) { - LineString[] newGeom = new LineString[source.getNumGeometries()]; - for (int idGeom = 0; idGeom < source.getNumGeometries(); idGeom++) { - newGeom[idGeom] = splitLineSource((LineString) source.getGeometryN(idGeom), - data.profileBuilder, ProfileBuilder.MILLIMETER); - } - offsetGeometry = GEOMETRY_FACTORY.createMultiLineString(newGeom); - } else if (source instanceof Point) { - Coordinate sourceCoord = source.getCoordinate(); - offsetGeometry = GEOMETRY_FACTORY.createPoint(new Coordinate(sourceCoord.x, sourceCoord.y, - sourceCoord.z + data.profileBuilder.getZGround(sourceCoord))); - // Check if the source is into a building - Building building = data.profileBuilder.getBuildingAtCoordinate(sourceCoord); - if(building != null && building.getHeight() >= sourceCoord.z) { - LOGGER.warn("Point source has been ignored as it is inside a building (building height {} m), it should be moved higher SOURCE: {}", - building.getHeight(),new WKTWriter(3).write(source)); - continue; - } - } else { - throw new IllegalArgumentException("Unsupported source geometry " + source.getGeometryType()); - } - // Offset the geometry with value of elevation for each coordinate - sourceCopy.add(offsetGeometry); - } - data.setSources(sourceCopy); - } - - /** - * Update ground Z coordinates of sound sources and receivers absolute to sea levels - */ - public void makeRelativeZToAbsolute() { - makeSourceRelativeZToAbsolute(); - makeReceiverRelativeZToAbsolute(); - } - - /** - * Update ground Z coordinates of receivers absolute to sea levels - */ - public void makeReceiverRelativeZToAbsolute() { - for(Coordinate receiver : data.receivers) { - receiver.setZ(receiver.getZ() + data.profileBuilder.getZGround(receiver)); - } - } - /** * Compute li to equation 4.1 NMPB 2008 (June 2009) * @param source @@ -1012,9 +882,9 @@ public void makeReceiverRelativeZToAbsolute() { private void addLineSource(LineString source, Coordinate receiverCoord, int srcIndex, List sourceList) { ArrayList pts = new ArrayList<>(); Coordinate nearestPoint = JTSUtility.getNearestPoint(receiverCoord, source); - double segmentSizeConstraint = max(1, receiverCoord.distance3D(nearestPoint) / 2.0); + double segmentSizeConstraint = max(1, receiverCoord.distance3D(nearestPoint) / this.data.lineSourceSpacingRatio); if (isNaN(segmentSizeConstraint)) { - segmentSizeConstraint = max(1, receiverCoord.distance(nearestPoint) / 2.0); + segmentSizeConstraint = max(1, receiverCoord.distance(nearestPoint) / this.data.lineSourceSpacingRatio); } double li = splitLineStringIntoPoints(source, segmentSizeConstraint, pts); for (int ptIndex = 0; ptIndex < pts.size(); ptIndex++) { diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/delaunay/LayerTinfour.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/delaunay/LayerTinfour.java index 4fc28b710..d30355e2a 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/delaunay/LayerTinfour.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/delaunay/LayerTinfour.java @@ -12,37 +12,55 @@ import org.locationtech.jts.algorithm.Orientation; import org.locationtech.jts.geom.*; +import org.locationtech.jts.geom.prep.PreparedPolygon; import org.locationtech.jts.index.quadtree.Quadtree; +import org.locationtech.jts.index.strtree.STRtree; +import org.locationtech.jts.io.ParseException; +import org.locationtech.jts.io.WKTReader; import org.locationtech.jts.io.WKTWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.tinfour.common.*; +import org.tinfour.common.IConstraint; +import org.tinfour.common.LinearConstraint; +import org.tinfour.common.PolygonConstraint; +import org.tinfour.common.SimpleTriangle; +import org.tinfour.common.Vertex; import org.tinfour.standard.IncrementalTin; -import org.tinfour.utils.TriangleCollector; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.util.*; +import java.util.stream.IntStream; +import java.util.stream.StreamSupport; public class LayerTinfour implements LayerDelaunay { private double epsilon = 0.001; // merge of Vertex instances below this distance private static final Logger LOGGER = LoggerFactory.getLogger(LayerTinfour.class); public String dumpFolder = ""; - List constraints = new ArrayList<>(); - List constraintIndex = new ArrayList<>(); - Quadtree ptsIndex = new Quadtree(); private boolean computeNeighbors = false; private double maxArea = 0; - + private boolean verbose = true; // Output data - private List vertices = new ArrayList(); - private List triangles = new ArrayList(); - private List neighbors = new ArrayList(); // The first neighbor triangle is opposite the first corner of triangle i + private List vertices = new ArrayList<>(); + private final List triangles = new ArrayList(); + private final List neighbors = new ArrayList(); // The first neighbor triangle is opposite the first corner of triangle i + /** + * RTree for polygon spatial index + */ + private final STRtree polygonRtree = new STRtree(); + /** + * Use PreparedPolygon for faster point-in-polygon tests + */ + private final Map polygonMap = new HashMap<>(); + public boolean isVerbose() { + return verbose; + } + + public void setVerbose(boolean verbose) { + this.verbose = verbose; + } /** * @@ -71,18 +89,6 @@ private Vertex addCoordinate(Coordinate coordinate, int index) { } - /** - * - * @param incrementalTin - * @return - */ - private List computeTriangles(IncrementalTin incrementalTin) { - ArrayList triangles = new ArrayList<>(incrementalTin.countTriangles().getCount()); - Triangle.TriangleBuilder triangleBuilder = new Triangle.TriangleBuilder(triangles); - TriangleCollector.visitSimpleTriangles(incrementalTin, triangleBuilder); - return triangles; - } - /** * @return When an exception occur, this folder with receiver the input data */ @@ -127,11 +133,11 @@ private static Coordinate getCentroid(SimpleTriangle triangle) { return new Coordinate( cx, cy, cz); } - public void dumpData() { + public void dumpData(File destinationCsv) { GeometryFactory factory = new GeometryFactory(); WKTWriter wktWriter = new WKTWriter(3); try { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(dumpFolder, "tinfour_dump.csv")))) { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(destinationCsv))) { for(Object vObj : ptsIndex.queryAll()) { if(vObj instanceof Vertex) { final Vertex v = (Vertex)vObj; @@ -174,72 +180,111 @@ public void dumpData() { } } + /** + * Find polygon index by point + * @param point Point to search + * @return Polygon index or -1 if not found + */ + public int findPolygonIndexByPoint(Point point) { + for(Integer polygonIndex : (List)polygonRtree.query(point.getEnvelopeInternal())) { + PreparedPolygon polygon = polygonMap.get(polygonIndex); + if(polygon.contains(point)) { + return polygonIndex; + } + } + return -1; + } + + /** + * Read dump file + * @param dumpPath Path to dump file + * @throws IOException Read error + * @throws LayerDelaunayError Error in delaunay processing + * @throws ParseException Error in WKT parsing + */ + public void readDump(File dumpPath) throws IOException, LayerDelaunayError, ParseException { + WKTReader wktReader = new WKTReader(); + try(BufferedReader reader = new BufferedReader(new FileReader(dumpPath))) { + String line; + int index = 0; + while ((line = reader.readLine()) != null) { + Geometry obj = wktReader.read(line); + if(obj instanceof Point) { + addVertex(obj.getCoordinate()); + } else if(obj instanceof Polygon) { + addPolygon((Polygon)obj, index++); + } else if (obj instanceof LineString) { + addLineString((LineString)obj, index++); + } + } + } + } + /** * Launch delaunay process */ @Override public void processDelaunay() throws LayerDelaunayError { + polygonRtree.build(); // build the rtree as it must not be built when using a multi-thread query triangles.clear(); vertices.clear(); - List meshPoints = ptsIndex.queryAll(); - IncrementalTin tin; boolean refine; - List simpleTriangles = new ArrayList<>(); - do { - // Triangulate - tin = new IncrementalTin(); - // Add points - tin.add(meshPoints, null); - // Add constraints - try { - tin.addConstraints(constraints, false); - }catch (IllegalStateException ex) { - // Got error - // Dump input data - if(!dumpFolder.isEmpty()) { - dumpData(); - } - throw new LayerDelaunayError(ex); + // Triangulate + tin = new IncrementalTin(epsilon); + // Add points + tin.add(ptsIndex.queryAll(), null); + // Add constraints + try { + tin.addConstraints(constraints, false); + }catch (IllegalStateException ex) { + // Got error + // Dump input data + if(!dumpFolder.isEmpty()) { + dumpData(new File(dumpFolder, "tinfour_dump.csv")); } - refine = false; + throw new LayerDelaunayError(ex); + } - simpleTriangles = computeTriangles(tin); + do { + refine = false; // Will triangulate multiple time if refinement is necessary - if(maxArea > 0) { - for (SimpleTriangle triangle : simpleTriangles) { - if(triangle.getArea() > maxArea) { - // Insert steiner point in circumcircle - Coordinate centroid = getCentroid(triangle); - meshPoints.add(new Vertex(centroid.x, centroid.y, centroid.z)); - refine = true; + if (maxArea > 0) { + ArrayList newSteinerPoints = StreamSupport.stream(tin.triangles().spliterator(), true) + .filter(triangle -> triangle.getArea() > maxArea) + .map(SimpleTriangle::getCentroid) + .collect(java.util.stream.Collectors.toCollection(ArrayList::new)); + if (!newSteinerPoints.isEmpty()) { + tin.add(newSteinerPoints, null); + refine = true; + if (verbose) { + LOGGER.info("Refining Delaunay with {} points", newSteinerPoints.size()); } } } } while (refine); List verts = tin.getVertices(); - vertices = new ArrayList<>(verts.size()); Map vertIndex = new HashMap<>(); - for(Vertex v : verts) { - vertIndex.put(v, vertices.size()); - vertices.add(toCoordinate(v)); + this.vertices = new ArrayList<>(verts.size()); + for (int i = 0; i < verts.size(); i++) { + Vertex v = verts.get(i); + vertIndex.put(v, i); + this.vertices.add(toCoordinate(v)); } + // Collect triangles but with tin index of vertices Map edgeIndexToTriangleIndex = new HashMap<>(); - for(SimpleTriangle t : simpleTriangles) { - int triangleAttribute = 0; - if(t.getContainingRegion() != null) { - if(t.getContainingRegion().getConstraintIndex() < constraintIndex.size()) { - triangleAttribute = constraintIndex.get(t.getContainingRegion().getConstraintIndex()); - } + for(SimpleTriangle t : tin.triangles()) { + Triangle newTriangle = new Triangle(vertIndex.get(t.getVertexA()), vertIndex.get(t.getVertexB()), vertIndex.get(t.getVertexC()), 0); + triangles.add(newTriangle); + if(computeNeighbors) { + edgeIndexToTriangleIndex.put(t.getEdgeA().getIndex(), triangles.size() - 1); + edgeIndexToTriangleIndex.put(t.getEdgeB().getIndex(), triangles.size() - 1); + edgeIndexToTriangleIndex.put(t.getEdgeC().getIndex(), triangles.size() - 1); } - triangles.add(new Triangle(vertIndex.get(t.getVertexA()), vertIndex.get(t.getVertexB()),vertIndex.get(t.getVertexC()), triangleAttribute)); - edgeIndexToTriangleIndex.put(t.getEdgeA().getIndex(), triangles.size() - 1); - edgeIndexToTriangleIndex.put(t.getEdgeB().getIndex(), triangles.size() - 1); - edgeIndexToTriangleIndex.put(t.getEdgeC().getIndex(), triangles.size() - 1); } if(computeNeighbors) { - for(SimpleTriangle t : simpleTriangles) { + for(SimpleTriangle t : tin.triangles()) { Integer neighA = edgeIndexToTriangleIndex.get(t.getEdgeA().getDual().getIndex()); Integer neighB = edgeIndexToTriangleIndex.get(t.getEdgeB().getDual().getIndex()); Integer neighC = edgeIndexToTriangleIndex.get(t.getEdgeC().getDual().getIndex()); @@ -248,8 +293,24 @@ public void processDelaunay() throws LayerDelaunayError { neighC != null ? neighC : -1)); } } + // Update triangle polygon association + if(!polygonMap.isEmpty()) { + GeometryFactory gf = new GeometryFactory(); + IntStream.range(0, triangles.size()).parallel().forEach(i -> { + Triangle triangle = triangles.get(i); + // Look for associated polygon area + Coordinate inCenter = org.locationtech.jts.geom.Triangle.inCentre(toCoordinate(verts.get(triangle.getA())), + toCoordinate(verts.get(triangle.getB())), toCoordinate(verts.get(triangle.getC()))); + Point inCenterPoint = gf.createPoint(inCenter); + int polygonIndex = findPolygonIndexByPoint(inCenterPoint); + if (polygonIndex != -1) { + triangle.setAttribute(polygonIndex); + } + }); + } } + /** * Append a polygon into the triangulation * @@ -272,27 +333,27 @@ public void addPolygon(Polygon newPoly, int buildingId) throws LayerDelaunayErro polygonConstraint.complete(); if(polygonConstraint.isValid()) { constraints.add(polygonConstraint); - constraintIndex.add(buildingId); - } - } - // Append holes - final int holeCount = newPoly.getNumInteriorRing(); - for (int holeIndex = 0; holeIndex < holeCount; holeIndex++) { - LineString holeLine = newPoly.getInteriorRingN(holeIndex); - final Coordinate[] hCoordinates = holeLine.getCoordinates(); - // Holes must be CW - if(Orientation.isCCW(hCoordinates)) { - CoordinateArrays.reverse(hCoordinates); - } - List vertexList = new ArrayList<>(hCoordinates.length); - for(int vId = 0; vId < hCoordinates.length - 1 ; vId++) { - vertexList.add(addCoordinate(hCoordinates[vId], buildingId)); - } - PolygonConstraint polygonConstraint = new PolygonConstraint(vertexList); - polygonConstraint.complete(); - if(polygonConstraint.isValid()) { - constraints.add(polygonConstraint); - constraintIndex.add(buildingId); + polygonRtree.insert(newPoly.getEnvelopeInternal(), buildingId); + polygonMap.put(buildingId, new PreparedPolygon(newPoly)); + // Append holes + final int holeCount = newPoly.getNumInteriorRing(); + for (int holeIndex = 0; holeIndex < holeCount; holeIndex++) { + LineString holeLine = newPoly.getInteriorRingN(holeIndex); + final Coordinate[] hCoordinates = holeLine.getCoordinates(); + // Holes must be CW + if(Orientation.isCCW(hCoordinates)) { + CoordinateArrays.reverse(hCoordinates); + } + vertexList = new ArrayList<>(hCoordinates.length); + for(int vId = 0; vId < hCoordinates.length - 1 ; vId++) { + vertexList.add(addCoordinate(hCoordinates[vId], buildingId)); + } + polygonConstraint = new PolygonConstraint(vertexList); + polygonConstraint.complete(); + if(polygonConstraint.isValid()) { + constraints.add(polygonConstraint); + } + } } } } @@ -356,7 +417,6 @@ public void addLineString(LineString lineToProcess, int buildingID) throws Layer linearConstraint.complete(); if(linearConstraint.isValid()) { constraints.add(linearConstraint); - constraintIndex.add(buildingID); } } //add buildingID to edge property and to points property diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/delaunay/Triangle.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/delaunay/Triangle.java index 7d099c079..7eaeb4e59 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/delaunay/Triangle.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/delaunay/Triangle.java @@ -9,6 +9,8 @@ package org.noise_planet.noisemodelling.pathfinder.delaunay; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Polygon; import org.tinfour.common.SimpleTriangle; import java.util.ArrayList; @@ -16,93 +18,101 @@ /** * A triangle built from the combination of the 3 vertices index. - * + * * @author Nicolas Fortin */ public class Triangle { - private int a = 0; - private int b = 0; - private int c = 0; - private int attribute =-1; + private int a = 0; + private int b = 0; + private int c = 0; + private int attribute = -1; + + public int getA() { + return a; + } + + public int get(int id) { + switch (id) { + case 0: + return a; + case 1: + return b; + default: + return c; + } + } - public int getA() { - return a; - } + public int getAttribute() { + return this.attribute; + } - public int get(int id) { - switch (id) { - case 0: - return a; - case 1: - return b; - default: - return c; - } + /** + * @param attribute new Attribute value for this triangle + */ + public void setAttribute(int attribute) { + this.attribute = attribute; } - public int getAttribute(){ - return this.attribute; + + public void set(int id, int index) { + switch (id) { + case 0: + a = index; + break; + case 1: + b = index; + break; + default: + c = index; } - - - public void set(int id,int index) { - switch (id) { - case 0: - a=index; - break; - case 1: - b=index; - break; - default: - c=index; - } - } + } - public void setA(int a) { - this.a = a; - } + public void setA(int a) { + this.a = a; + } - public int getB() { - return b; - } + public int getB() { + return b; + } - public void setB(int b) { - this.b = b; - } + public void setB(int b) { + this.b = b; + } - public int getC() { - return c; - } + public int getC() { + return c; + } - public void setC(int c) { - this.c = c; - } + public void setC(int c) { + this.c = c; + } - public Triangle(int a, int b, int c, int attribute) { - super(); - this.a = a; - this.b = b; - this.c = c; - this.attribute = attribute; - } - - public Triangle(int a, int b, int c) { - super(); - this.a = a; - this.b = b; - this.c = c; - - } - public static class TriangleBuilder implements Consumer { - ArrayList triangles; + public Triangle(int a, int b, int c, int attribute) { + super(); + this.a = a; + this.b = b; + this.c = c; + this.attribute = attribute; + } - public TriangleBuilder(ArrayList triangles) { - this.triangles = triangles; - } + public Triangle(int a, int b, int c) { + super(); + this.a = a; + this.b = b; + this.c = c; - @Override - public void accept(SimpleTriangle triangle) { - triangles.add(triangle); - } - } + } + + public static class TriangleBuilder implements Consumer { + ArrayList triangles; + + public TriangleBuilder(ArrayList triangles) { + this.triangles = triangles; + } + + @Override + public void accept(SimpleTriangle triangle) { + triangles.add(triangle); + } + } } diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/path/Scene.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/path/Scene.java index 34fabf182..82cc94988 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/path/Scene.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/path/Scene.java @@ -59,6 +59,12 @@ public class Scene { public int reflexionOrder = 1; public double defaultGroundAttenuation = 0; + /** + * dictates the density of source points created from a line sound source; + * a higher value means more points and finer discretization + * sourcePointDistance = DistanceSourceReceiver / lineSourceSpacingRatio + */ + public double lineSourceSpacingRatio = 2; public Scene() { this.profileBuilder = new ProfileBuilder(); @@ -89,6 +95,8 @@ public void setBodyBarrier(boolean bodyBarrier) { public double maxSrcDist = DEFAULT_MAX_PROPAGATION_DISTANCE; /** Maximum reflection wall distance from receiver to source line */ public double maxRefDist = DEFAULT_MAXIMUM_REF_DIST; + /** Maximum receiver-to-wall horizontal distance for the optional reflection cut profile filter */ + private double closeReceiverReflectionWallDistance = 0; /** @@ -121,19 +129,6 @@ public void addSource(Long pk, Geometry geom, Orientation orientation) { sourceOrientation.put(pk, orientation); } - /** - * Replace the sources by the given list - * @param sourceGeometries - */ - public void setSources(List sourceGeometries) { - sourcesIndex = new QueryRTree(); - int i = 0; - for(Geometry source : sourceGeometries) { - sourcesIndex.appendGeometry(source, i++); - } - this.sourceGeometries = sourceGeometries; - } - /** * * @param receiver @@ -171,6 +166,14 @@ public void setDefaultGroundAttenuation(double gS) { this.defaultGroundAttenuation = gS; } + public double getCloseReceiverReflectionWallDistance() { + return closeReceiverReflectionWallDistance; + } + + public void setCloseReceiverReflectionWallDistance(double closeReceiverReflectionWallDistance) { + this.closeReceiverReflectionWallDistance = closeReceiverReflectionWallDistance; + } + public void clearSources() { sourceGeometries.clear(); sourceOrientation.clear(); diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/BuildingIntersectionPathVisitor.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/BuildingIntersectionPathVisitor.java index f289c385a..3ac064ad9 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/BuildingIntersectionPathVisitor.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/BuildingIntersectionPathVisitor.java @@ -136,8 +136,6 @@ public void addItem(int id) { if (!roofPoints.isEmpty()) { input.addAll(roofPoints); pushedBuildingsWideAnglePoints.add(processedWall.originId); - // Stop iterating bounding boxes - throw new IllegalStateException(); } } else if(processedWall.type == ProfileBuilder.IntersectionType.WALL) { // A wall not related to a building (polygon) @@ -172,8 +170,6 @@ public void addItem(int id) { if (!roofPoints.isEmpty()) { pushedWallsPoints.add(processedWall.originId); input.addAll(roofPoints); - // Stop iterating bounding boxes - throw new IllegalStateException(); } } } diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/CutPointReflection.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/CutPointReflection.java index c40766c79..3384a8f3d 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/CutPointReflection.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/CutPointReflection.java @@ -70,6 +70,19 @@ public void setWallAlpha(List wallAlpha) { this.wallAlpha = wallAlpha; } + @Override + public CutPoint clone() { + CutPointReflection cloned = (CutPointReflection) super.clone(); + // Deep copy the wall LineSegment + if (this.wall != null) { + cloned.wall = new LineSegment( + new Coordinate(this.wall.p0), + new Coordinate(this.wall.p1) + ); + } + return cloned; + } + @Override public String toString() { return "CutPointReflection{" + diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/CutProfile.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/CutProfile.java index 137a528b3..4e8ae5eab 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/CutProfile.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/CutProfile.java @@ -15,6 +15,7 @@ import org.locationtech.jts.geom.CoordinateSequence; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.LineSegment; import org.noise_planet.noisemodelling.pathfinder.path.Scene; import org.noise_planet.noisemodelling.pathfinder.utils.geometry.CurvedProfileGenerator; import org.noise_planet.noisemodelling.pathfinder.utils.geometry.JTSUtility; @@ -177,6 +178,43 @@ public double getGPath() { } } + /** + * Compute the G coefficient for path segment using indices instead of CutPoint references. + * This avoids indexOf() calls that fail when using transformed CutPoints. + * @param i0 Index of first CutPoint in segment + * @param i1 Index of last CutPoint in segment + * @param buildingRoofG Ground absorption coefficient for building roofs + * @return Weighted average of ground absorption coefficients along the segment + */ + @JsonIgnore + public double getGPathByIndex(int i0, int i1, double buildingRoofG) { + if(i0 == -1 || i1 == -1 || i1 < i0 || i0 >= cutPoints.size() || i1 >= cutPoints.size()) { + return 0.0; + } + + double totalLength = 0; + double rsLength = 0.0; + + boolean aboveRoof = false; + for(int index = 0; index < i1; index++) { + CutPoint current = cutPoints.get(index); + if(current instanceof CutPointWall) { + CutPointWall currentWall = (CutPointWall) current; + if(!aboveRoof && currentWall.intersectionType.equals(CutPointWall.INTERSECTION_TYPE.BUILDING_ENTER)) { + aboveRoof = true; + } else if(aboveRoof && currentWall.intersectionType.equals(CutPointWall.INTERSECTION_TYPE.BUILDING_EXIT)) { + aboveRoof = false; + } + } + if(index >= i0) { + double segmentLength = current.getCoordinate().distance(cutPoints.get(index + 1).getCoordinate()); + rsLength += segmentLength * (aboveRoof ? buildingRoofG : current.getGroundCoefficient()); + totalLength += segmentLength; + } + } + return rsLength / totalLength; + } + /** * * @return @@ -186,6 +224,34 @@ public boolean isFreeField() { return !hasBuildingIntersection && !hasTopographyIntersection; } + /** + * @param maximumReceiverWallDistance Maximum horizontal receiver-to-wall distance in meters + * @return True if this reflection profile contains a last reflection before the receiver and the receiver + * is closer than the provided distance to that reflective wall, even if other events occur afterwards + */ + @JsonIgnore + public boolean hasCloseReflectionBeforeReceiver(double maximumReceiverWallDistance) { + if(profileType != PROFILE_TYPE.REFLECTION || cutPoints.size() < 3 || maximumReceiverWallDistance < 0) { + return false; + } + CutPointReceiver receiver = getReceiver(); + if(receiver == null) { + return false; + } + CutPointReflection lastReflectionBeforeReceiver = null; + for(int i = cutPoints.size() - 2; i >= 1; i--) { + CutPoint cutPoint = cutPoints.get(i); + if(cutPoint instanceof CutPointReflection) { + lastReflectionBeforeReceiver = (CutPointReflection) cutPoint; + break; + } + } + if(lastReflectionBeforeReceiver == null || lastReflectionBeforeReceiver.wall == null) { + return false; + } + return lastReflectionBeforeReceiver.wall.distance(receiver.coordinate) < maximumReceiverWallDistance; + } + @Override public String toString() { @@ -210,10 +276,25 @@ public List computePts2DGround() { * @return @return the computed coordinate list */ public List computePts2D(boolean curvedPath) { + return computePts2D(curvedPath, null); + } + + /** + * Compute 2D coordinates, optionally applying curved transformation + * @param curvedPath Whether to apply curved transformation + * @param transformedCutPointsOut If not null and curvedPath is true, will be populated with transformed CutPoints + * @return The computed 2D coordinate list + */ + public List computePts2D(boolean curvedPath, List transformedCutPointsOut) { List pts2D; if(curvedPath) { - pts2D = CurvedProfileGenerator.applyTransformation(cutPoints - , false).stream() + List transformedCutPoints = CurvedProfileGenerator.applyTransformation(cutPoints, false); + // If caller wants the transformed cut points, populate the output list + if (transformedCutPointsOut != null) { + transformedCutPointsOut.clear(); + transformedCutPointsOut.addAll(transformedCutPoints); + } + pts2D = transformedCutPoints.stream() .map(CutPoint::getCoordinate) .collect(Collectors.toList()); } else { @@ -233,6 +314,11 @@ public List computePts2D() { } public List getConvexHullIndices(List coordinates2d) { + return getConvexHullIndices(coordinates2d, false); + } + + + public List getConvexHullIndices(List coordinates2d, boolean ignoreWall) { if(coordinates2d.size() != cutPoints.size()) { throw new IllegalArgumentException("Coordinates size must be equal to cut points size"); } @@ -246,7 +332,7 @@ public List getConvexHullIndices(List coordinates2d) { // We only add the point at the top of the wall, not the point at the bottom of the wall if(currentPoint instanceof CutPointTopography || (currentPoint instanceof CutPointWall - && Double.compare(currentPoint.getCoordinate().z, currentPoint.getzGround()) != 0)) { + && Double.compare(currentPoint.getCoordinate().z, currentPoint.getzGround()) != 0 && !ignoreWall)) { convexHullInput.add(coordinates2d.get(idPoint)); } } diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/ProfileBuilder.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/ProfileBuilder.java index f15eb5714..e0cbce114 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/ProfileBuilder.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/profilebuilder/ProfileBuilder.java @@ -13,6 +13,7 @@ import org.locationtech.jts.algorithm.CGAlgorithms3D; import org.locationtech.jts.geom.*; import org.locationtech.jts.index.strtree.STRtree; +import org.locationtech.jts.io.WKTWriter; import org.locationtech.jts.math.Vector2D; import org.locationtech.jts.math.Vector3D; import org.locationtech.jts.operation.distance.DistanceOp; @@ -282,6 +283,131 @@ public ProfileBuilder addBuilding(Coordinate[] coords, double height, int id) { return addBuilding(coords, height, new ArrayList<>(), id); } + + /** + * Apply a linestring over the digital elevation model by offsetting the z value with the ground elevation. + * @param lineString + * @param epsilon ignore elevation point where linear interpolation distance is inferior that this value + * @return computed lineString + */ + public LineString splitGeometryLineToDem(LineString lineString, double epsilon) { + boolean warned = false; + ArrayList newGeomCoordinates = new ArrayList<>(); + Coordinate[] coordinates = lineString.getCoordinates(); + for(int idPoint = 0; idPoint < coordinates.length - 1; idPoint++) { + Coordinate p0 = coordinates[idPoint]; + Coordinate p1 = coordinates[idPoint + 1]; + List groundProfileCoordinates = new ArrayList<>(); + fetchTopographicProfile(groundProfileCoordinates, p0, p1, false); + newGeomCoordinates.ensureCapacity(newGeomCoordinates.size() + groundProfileCoordinates.size()); + if(groundProfileCoordinates.size() < 2) { + if(hasDem()) { + if(!warned) { + LOGGER.warn( "Source line out of DEM area {}", + new WKTWriter(3).write(lineString)); + warned = true; + } + } + newGeomCoordinates.add(p0); + newGeomCoordinates.add(p1); + } else { + if (idPoint == 0) { + newGeomCoordinates.add(new Coordinate(p0.x, p0.y, p0.z + groundProfileCoordinates.get(0).z)); + } + Coordinate previous = groundProfileCoordinates.get(0); + for (int groundPoint = 1; groundPoint < groundProfileCoordinates.size() - 1; groundPoint++) { + final Coordinate current = groundProfileCoordinates.get(groundPoint); + final Coordinate next = groundProfileCoordinates.get(groundPoint + 1); + // Do not add topographic points which are simply the linear interpolation between two points + // triangulation add a lot of interpolated lines from line segment DEM + if (CGAlgorithms3D.distancePointSegment(current, previous, next) >= epsilon) { + // interpolate the Z (height) values of the source then add the altitude + previous = current; + newGeomCoordinates.add( + new Coordinate(current.x, current.y, current.z + Vertex.interpolateZ(current, p0, p1))); + } + } + newGeomCoordinates.add(new Coordinate(p1.x, p1.y, p1.z + + groundProfileCoordinates.get(groundProfileCoordinates.size() - 1).z)); + } + } + return lineString.getFactory().createLineString(newGeomCoordinates.toArray(new Coordinate[0])); + } + + /** + * Update ground Z coordinates of sound sources absolute to sea levels + * @param geometry Geometry to offset the Z value + * @param checkForBuildingVolumes If true, this function will print a warning if the geometry contain at least one point under a building roof + */ + public Geometry makeGeometryRelativeZToAbsolute(Geometry geometry, boolean checkForBuildingVolumes) { + Geometry offsetGeometry; + if (geometry instanceof LineString) { + offsetGeometry = splitGeometryLineToDem((LineString) geometry, ProfileBuilder.MILLIMETER); + if (checkForBuildingVolumes) { + Coordinate[] coordinates = offsetGeometry.getCoordinates(); + logWarningIfCoordinatesIntoBuildings(coordinates); + } + } else if (geometry instanceof MultiLineString) { + LineString[] newGeom = new LineString[geometry.getNumGeometries()]; + for (int idGeom = 0; idGeom < geometry.getNumGeometries(); idGeom++) { + newGeom[idGeom] = splitGeometryLineToDem((LineString) geometry.getGeometryN(idGeom), + MILLIMETER); + } + offsetGeometry = geometry.getFactory().createMultiLineString(newGeom); + if (checkForBuildingVolumes) { + Coordinate[] coordinates = offsetGeometry.getCoordinates(); + logWarningIfCoordinatesIntoBuildings(coordinates); + } + } else if (geometry instanceof Point) { + Coordinate geometryCoordinate = geometry.getCoordinate(); + offsetGeometry = geometry.getFactory().createPoint(offsetCoordinateToAltitudeUsingDigitalElevationModel(geometryCoordinate, checkForBuildingVolumes)); + } else { + throw new IllegalArgumentException("Unsupported source geometry " + geometry.getGeometryType()); + } + return offsetGeometry; + } + + /** + * Update ground Z coordinates of sound sources absolute to sea levels + * @param geometryCoordinates Geometry coordinates to offset the Z value + * @param checkForBuildingVolumes If true, this function will print a warning if the geometry contain at least one point under a building roof + */ + public Coordinate[] offsetCoordinatesToAltitudeUsingDigitalElevationModel(Coordinate[] geometryCoordinates, boolean checkForBuildingVolumes) { + Coordinate[] offsetCoordinates = new Coordinate[geometryCoordinates.length]; + for (int i = 0; i < geometryCoordinates.length; i++) { + offsetCoordinates[i] = offsetCoordinateToAltitudeUsingDigitalElevationModel(geometryCoordinates[i], checkForBuildingVolumes); + } + return offsetCoordinates; + } + + /** + * Offset a coordinate to altitude using the digital elevation model. The Z value of the coordinate is updated with the ground elevation at this point. + * @param geometryCoordinate Coordinate to offset + * @param checkForBuildingVolumes If true, this function will print a warning if the geometry contain at least one point under a building roof + * @return + */ + public Coordinate offsetCoordinateToAltitudeUsingDigitalElevationModel(Coordinate geometryCoordinate, boolean checkForBuildingVolumes) { + Coordinate offsetCoordinate = new Coordinate(geometryCoordinate.x, geometryCoordinate.y, geometryCoordinate.z + getZGround(geometryCoordinate)); + if(checkForBuildingVolumes) { + logWarningIfCoordinatesIntoBuildings(geometryCoordinate); + } + return offsetCoordinate; + } + + private void logWarningIfCoordinatesIntoBuildings(Coordinate... coordinates) { + for (Coordinate coordinate : coordinates) { + // Check if the source is into a building + Building building = getBuildingAtCoordinate(coordinate); + if (building != null && building.getHeight() >= coordinate.z) { + LOGGER.warn("Geometry (Source point or Receiver point) has been defined inside a building" + + " (building height {} m), it should be moved higher Geometry: {}", + building.getHeight(), new WKTWriter(3).write(new GeometryFactory().createPoint(coordinate))); + break; + } + } + } + + /** * Add the given {@link Geometry} footprint, height and alphas (absorption coefficients) as building. * @param geom Building footprint. @@ -398,15 +524,6 @@ public ProfileBuilder addWall(Coordinate[] coords, double height, int id) { return addWall(FACTORY.createLineString(coords), height, new ArrayList<>(), id); } - /** - * Add the given {@link Geometry} footprint, height, alphas (absorption coefficients) and a database id as wall. - * @param geom Wall footprint. - * @param id Database key. - */ - /*public ProfileBuilder addWall(LineString geom, int id) { - return addWall(geom, 0.0, new ArrayList<>(), id); - }*/ - /** * Add the given {@link Geometry} footprint, height, alphas (absorption coefficients) and a database id as wall. * @param coords Wall footprint coordinates. diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/utils/geometry/CurvedProfileGenerator.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/utils/geometry/CurvedProfileGenerator.java index 103546f41..eab650c87 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/utils/geometry/CurvedProfileGenerator.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/utils/geometry/CurvedProfileGenerator.java @@ -11,7 +11,9 @@ package org.noise_planet.noisemodelling.pathfinder.utils.geometry; import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.LineSegment; import org.noise_planet.noisemodelling.pathfinder.profilebuilder.CutPoint; +import org.noise_planet.noisemodelling.pathfinder.profilebuilder.CutPointReflection; import java.util.List; import java.util.ArrayList; @@ -58,6 +60,23 @@ public static List applyTransformation(List flatProfile, boo CutPoint newCp = cp.clone(); newCp.setZGround(groundCoords[i].z); newCp.setCoordinate(curvedCoords[i]); + + // If this is a reflection point, also transform the wall coordinates + if (newCp instanceof CutPointReflection) { + CutPointReflection reflectionPoint = (CutPointReflection) newCp; + if (reflectionPoint.wall != null) { + // Transform wall endpoints using the same curved transformation + Coordinate[] wallCoords = new Coordinate[]{ + new Coordinate(reflectionPoint.wall.p0), + new Coordinate(reflectionPoint.wall.p1) + }; + Coordinate[] transformedWallCoords = applyTransformation(cs, cr, wallCoords, inversed); + + // Create a NEW LineSegment with transformed coordinates + reflectionPoint.wall = new LineSegment(transformedWallCoords[0], transformedWallCoords[1]); + } + } + curvedProfile.add(newCp); } return curvedProfile; @@ -75,7 +94,7 @@ public static Coordinate[] applyTransformation(Coordinate cs, Coordinate cr, Coo Coordinate[] curvedProfile = new Coordinate[flatProfile.length]; // Calculate projected distance between source and receiver on the vertical plane - double d = cs.distance3D(cr); + double d = cs.distance(cr); // Calculate radius of curvature (Γ) double radius = Math.max(1000, 8 * d); @@ -87,7 +106,7 @@ public static Coordinate[] applyTransformation(Coordinate cs, Coordinate cr, Coo // Apply equation (4) for z coordinate transformation double z = base - - Math.sqrt(radius * radius - Math.pow(p.distance3D(cs) - d/2, 2)); + Math.sqrt(radius * radius - Math.pow(p.distance(cs) - d/2, 2)); if(inverse) { z = -z; diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/utils/profiler/DefaultProgressVisitor.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/utils/profiler/DefaultProgressVisitor.java index 72c71322c..30d3db739 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/utils/profiler/DefaultProgressVisitor.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/utils/profiler/DefaultProgressVisitor.java @@ -57,6 +57,7 @@ public int getStepCount() { @Override public void endOfProgress() { + pushProgression(subprocessSize - subprocessDone); } @Override diff --git a/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC15_Right.json b/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC15_Right.json index 66a16d37e..a3821ea39 100644 --- a/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC15_Right.json +++ b/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC15_Right.json @@ -42,6 +42,52 @@ }, "zGround" : 0.0, "groundCoefficient" : 0.5 + }, { + "type" : "Wall", + "coordinate" : { + "x" : 92.81851301610914, + "y" : 10.240289036493747, + "z" : 10.0 + }, + "zGround" : 0.0, + "groundCoefficient" : 0.5, + "wall" : { + "p0" : { + "x" : 88.86, + "y" : 2.9, + "z" : 10.0 + }, + "p1" : { + "x" : 94.9, + "y" : 14.1, + "z" : 10.0 + } + }, + "wallAlpha" : [ 0.004918209037966988, 0.008088162780793065, 0.013267721240171722, 0.02168493917994337, 0.03525564533465828, 0.056883929412881944, 0.09077715686040604, 0.14258583864393162 ], + "intersectionType" : "BUILDING_ENTER" + }, { + "type" : "Wall", + "coordinate" : { + "x" : 96.9374845595576, + "y" : 12.970240933322229, + "z" : 10.0 + }, + "zGround" : 0.0, + "groundCoefficient" : 0.5, + "wall" : { + "p0" : { + "x" : 94.9, + "y" : 14.1, + "z" : 10.0 + }, + "p1" : { + "x" : 98.02, + "y" : 12.37, + "z" : 10.0 + } + }, + "wallAlpha" : [ 0.004918209037966988, 0.008088162780793065, 0.013267721240171722, 0.02168493917994337, 0.03525564533465828, 0.056883929412881944, 0.09077715686040604, 0.14258583864393162 ], + "intersectionType" : "BUILDING_EXIT" }, { "type" : "GroundEffect", "coordinate" : { diff --git a/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC15_Right_Curved.json b/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC15_Right_Curved.json index 5fe3836be..ed40007d2 100644 --- a/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC15_Right_Curved.json +++ b/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC15_Right_Curved.json @@ -42,6 +42,52 @@ }, "zGround" : 0.0, "groundCoefficient" : 0.5 + }, { + "type" : "Wall", + "coordinate" : { + "x" : 92.81851301610914, + "y" : 10.240289036493747, + "z" : 10.0 + }, + "zGround" : 0.0, + "groundCoefficient" : 0.5, + "wall" : { + "p0" : { + "x" : 88.86, + "y" : 2.9, + "z" : 10.0 + }, + "p1" : { + "x" : 94.9, + "y" : 14.1, + "z" : 10.0 + } + }, + "wallAlpha" : [ 0.004918209037966988, 0.008088162780793065, 0.013267721240171722, 0.02168493917994337, 0.03525564533465828, 0.056883929412881944, 0.09077715686040604, 0.14258583864393162 ], + "intersectionType" : "BUILDING_ENTER" + }, { + "type" : "Wall", + "coordinate" : { + "x" : 96.9374845595576, + "y" : 12.970240933322229, + "z" : 10.0 + }, + "zGround" : 0.0, + "groundCoefficient" : 0.5, + "wall" : { + "p0" : { + "x" : 94.9, + "y" : 14.1, + "z" : 10.0 + }, + "p1" : { + "x" : 98.02, + "y" : 12.37, + "z" : 10.0 + } + }, + "wallAlpha" : [ 0.004918209037966988, 0.008088162780793065, 0.013267721240171722, 0.02168493917994337, 0.03525564533465828, 0.056883929412881944, 0.09077715686040604, 0.14258583864393162 ], + "intersectionType" : "BUILDING_EXIT" }, { "type" : "GroundEffect", "coordinate" : { diff --git a/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC19_Left.json b/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC19_Left.json index d557d8598..d6d74b593 100644 --- a/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC19_Left.json +++ b/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC19_Left.json @@ -19,25 +19,62 @@ "type" : "GroundEffect", "coordinate" : { "x" : 50.0, - "y" : 18.894651178790934, + "y" : 16.063775909003617, "z" : 0.0 }, "zGround" : 0.0, "groundCoefficient" : 0.5 }, { - "type" : "VEdgeDiffraction", + "type" : "Wall", "coordinate" : { - "x" : 99.9893933982822, - "y" : 30.010606601717797, - "z" : 7.232234504389141 + "x" : 102.35169775461208, + "y" : 24.0, + "z" : 12.0 }, "zGround" : 0.0, - "groundCoefficient" : 0.5 + "groundCoefficient" : 0.5, + "wall" : { + "p0" : { + "x" : 118.0, + "y" : 24.0, + "z" : 12.0 + }, + "p1" : { + "x" : 100.0, + "y" : 24.0, + "z" : 12.0 + } + }, + "wallAlpha" : [ 0.004918209037966988, 0.008088162780793065, 0.013267721240171722, 0.02168493917994337, 0.03525564533465828, 0.056883929412881944, 0.09077715686040604, 0.14258583864393162 ], + "intersectionType" : "BUILDING_ENTER" + }, { + "type" : "Wall", + "coordinate" : { + "x" : 118.0, + "y" : 26.372194954309762, + "z" : 12.0 + }, + "zGround" : 0.0, + "groundCoefficient" : 0.5, + "wall" : { + "p0" : { + "x" : 118.0, + "y" : 30.0, + "z" : 12.0 + }, + "p1" : { + "x" : 118.0, + "y" : 24.0, + "z" : 12.0 + } + }, + "wallAlpha" : [ 0.004918209037966988, 0.008088162780793065, 0.013267721240171722, 0.02168493917994337, 0.03525564533465828, 0.056883929412881944, 0.09077715686040604, 0.14258583864393162 ], + "intersectionType" : "BUILDING_EXIT" }, { "type" : "Topography", "coordinate" : { "x" : 120.0, - "y" : 31.344902798584958, + "y" : 26.67538374975994, "z" : 0.0 }, "zGround" : 0.0, @@ -46,10 +83,10 @@ "type" : "GroundEffect", "coordinate" : { "x" : 150.0, - "y" : 33.34528623036851, - "z" : 4.615384615384615 + "y" : 31.223215681512652, + "z" : 4.615384615384616 }, - "zGround" : 4.615384615384615, + "zGround" : 4.615384615384616, "groundCoefficient" : 0.2 }, { "type" : "VEdgeDiffraction", diff --git a/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC19_Left_Curved.json b/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC19_Left_Curved.json index d66bbaaac..845a2b622 100644 --- a/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC19_Left_Curved.json +++ b/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC19_Left_Curved.json @@ -19,25 +19,62 @@ "type" : "GroundEffect", "coordinate" : { "x" : 50.0, - "y" : 18.894651178790934, + "y" : 16.063775909003617, "z" : 0.0 }, "zGround" : 0.0, "groundCoefficient" : 0.5 }, { - "type" : "VEdgeDiffraction", + "type" : "Wall", "coordinate" : { - "x" : 99.9893933982822, - "y" : 30.010606601717797, - "z" : 7.232234504389141 + "x" : 102.35169775461208, + "y" : 24.0, + "z" : 12.0 }, "zGround" : 0.0, - "groundCoefficient" : 0.5 + "groundCoefficient" : 0.5, + "wall" : { + "p0" : { + "x" : 118.0, + "y" : 24.0, + "z" : 12.0 + }, + "p1" : { + "x" : 100.0, + "y" : 24.0, + "z" : 12.0 + } + }, + "wallAlpha" : [ 0.004918209037966988, 0.008088162780793065, 0.013267721240171722, 0.02168493917994337, 0.03525564533465828, 0.056883929412881944, 0.09077715686040604, 0.14258583864393162 ], + "intersectionType" : "BUILDING_ENTER" + }, { + "type" : "Wall", + "coordinate" : { + "x" : 118.0, + "y" : 26.372194954309762, + "z" : 12.0 + }, + "zGround" : 0.0, + "groundCoefficient" : 0.5, + "wall" : { + "p0" : { + "x" : 118.0, + "y" : 30.0, + "z" : 12.0 + }, + "p1" : { + "x" : 118.0, + "y" : 24.0, + "z" : 12.0 + } + }, + "wallAlpha" : [ 0.004918209037966988, 0.008088162780793065, 0.013267721240171722, 0.02168493917994337, 0.03525564533465828, 0.056883929412881944, 0.09077715686040604, 0.14258583864393162 ], + "intersectionType" : "BUILDING_EXIT" }, { "type" : "Topography", "coordinate" : { "x" : 120.0, - "y" : 31.344902798584958, + "y" : 26.67538374975994, "z" : 0.0 }, "zGround" : 0.0, @@ -46,10 +83,10 @@ "type" : "GroundEffect", "coordinate" : { "x" : 150.0, - "y" : 33.34528623036851, - "z" : 4.615384615384615 + "y" : 31.223215681512652, + "z" : 4.615384615384616 }, - "zGround" : 4.615384615384615, + "zGround" : 4.615384615384616, "groundCoefficient" : 0.2 }, { "type" : "VEdgeDiffraction", diff --git a/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC28_Left.json b/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC28_Left.json index e4a745bef..c17a4912c 100644 --- a/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC28_Left.json +++ b/noisemodelling-pathfinder/src/main/resources/org/noise_planet/noisemodelling/pathfinder/test_cases/TC28_Left.json @@ -24,6 +24,52 @@ }, "zGround" : 0.0, "groundCoefficient" : 0.5 + }, { + "type" : "Wall", + "coordinate" : { + "x" : 250.0, + "y" : 105.77403802834974, + "z" : 14.0 + }, + "zGround" : 0.0, + "groundCoefficient" : 0.5, + "wall" : { + "p0" : { + "x" : 250.0, + "y" : 70.0, + "z" : 14.0 + }, + "p1" : { + "x" : 250.0, + "y" : 180.0, + "z" : 14.0 + } + }, + "wallAlpha" : [ 0.004918209037966988, 0.008088162780793065, 0.013267721240171722, 0.02168493917994337, 0.03525564533465828, 0.056883929412881944, 0.09077715686040604, 0.14258583864393162 ], + "intersectionType" : "BUILDING_ENTER" + }, { + "type" : "Wall", + "coordinate" : { + "x" : 270.0, + "y" : 109.90491024993129, + "z" : 14.0 + }, + "zGround" : 0.0, + "groundCoefficient" : 0.5, + "wall" : { + "p0" : { + "x" : 270.0, + "y" : 180.0, + "z" : 14.0 + }, + "p1" : { + "x" : 270.0, + "y" : 70.0, + "z" : 14.0 + } + }, + "wallAlpha" : [ 0.004918209037966988, 0.008088162780793065, 0.013267721240171722, 0.02168493917994337, 0.03525564533465828, 0.056883929412881944, 0.09077715686040604, 0.14258583864393162 ], + "intersectionType" : "BUILDING_EXIT" }, { "type" : "VEdgeDiffraction", "coordinate" : { diff --git a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/LayerTinfourTest.java b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/LayerTinfourTest.java index f8df380c8..e149549c4 100644 --- a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/LayerTinfourTest.java +++ b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/LayerTinfourTest.java @@ -100,8 +100,7 @@ public void testPolygonHole() throws ParseException, LayerDelaunayError { layerTinfour.processDelaunay(); List triangleList = layerTinfour.getTriangles(); List vertices = layerTinfour.getVertices(); - // Test dump - layerTinfour.dumpData(); + Point hole1 = factory.createPoint(new Coordinate(222690.860,6758520.184)); Point hole2 = factory.createPoint(new Coordinate(222711.177,6758532.233)); Point inGeom = merged.getInteriorPoint(); diff --git a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/PathFinderTest.java b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/PathFinderTest.java index 45ce0bb0a..f2198c510 100644 --- a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/PathFinderTest.java +++ b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/PathFinderTest.java @@ -120,7 +120,7 @@ public static void assertCutProfile(InputStream expected, CutProfile got) throws public static void assertCutProfile(CutProfile expected, CutProfile got) { assertNotNull(expected); assertNotNull(got); - assertEquals(expected.cutPoints.size(), got.cutPoints.size(), "Not the same number of cut points"); + assertEquals(expected.cutPoints.size(), got.cutPoints.size(), got.getProfileType()+ " Not the same number of cut points"); assertEquals(expected.profileType, got.profileType, "Not the same profile type"); assertEquals(expected.curvedPath, got.curvedPath, "Not the same curved path attribute value"); @@ -811,7 +811,6 @@ public void TC14() throws Exception { /** * Test TC15 -- Flat ground with homogeneous acoustic properties and four buildings - * right : error in value of b cnossos table 149 right path */ @Test public void TC15() throws Exception { @@ -833,6 +832,12 @@ public void TC15() throws Exception { new Coordinate(93.3, 17.8, 10), new Coordinate(87.3, 6.6, 10), new Coordinate(84.1, 8.3, 10), + }) + .addBuilding(new Coordinate[]{ + new Coordinate(94.9, 14.1, 10), + new Coordinate(98.02, 12.37, 10), + new Coordinate(92.03, 1.2, 10), + new Coordinate(88.86, 2.9, 10), }); profileBuilder.addGroundEffect(0, 100, 0.0, 150, 0.5); profileBuilder.setzBuildings(true); @@ -856,7 +861,6 @@ public void TC15() throws Exception { //Run computation computeRays.run(propDataOut); - assertEquals(5, propDataOut.getCutProfiles().size()); assertCutProfiles("TC15", propDataOut.cutProfiles); @@ -1107,10 +1111,6 @@ public void TC19() throws Exception { assertEquals(5, propDataOut.getCutProfiles().size()); assertCutProfiles("TC19", propDataOut.cutProfiles); - - //Different value with the TC because their z-profile left seems to be false, it follows the building top - // border while it should not - // assertCutProfile("TC19_Left", propDataOut.cutProfiles.poll()); } /** @@ -1558,12 +1558,11 @@ public void TC28() throws Exception { new Coordinate(184, 91, 0), new Coordinate(196, 22, 0)}, 10, -1) -// this building is ignored in the test case -// .addBuilding(new Coordinate[]{ -// new Coordinate(250, 70, 0), -// new Coordinate(250, 180, 0), -// new Coordinate(270, 180, 0), -// new Coordinate(270, 70, 0)}, 14, -1) + .addBuilding(new Coordinate[]{ + new Coordinate(250, 70, 0), + new Coordinate(250, 180, 0), + new Coordinate(270, 180, 0), + new Coordinate(270, 70, 0)}, 14, -1) .addBuilding(new Coordinate[]{ new Coordinate(332, 32, 0), diff --git a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/ProfileBuilderTest.java b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/ProfileBuilderTest.java index d89ecedf1..bae2dcff2 100644 --- a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/ProfileBuilderTest.java +++ b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/ProfileBuilderTest.java @@ -286,10 +286,8 @@ public void testRelativeSourceLineProjection() throws ParseException { Scene scene = new Scene(profileBuilder); WKTReader wktReader = new WKTReader(); Geometry geometry = wktReader.read("MultiLineStringZ ((10 10 1, 200 50 1))"); - scene.addSource(1L, geometry); - PathFinder pathFinder = new PathFinder(scene); - assertEquals(2, scene.sourceGeometries.get(0).getNumPoints()); - pathFinder.makeSourceRelativeZToAbsolute(); + scene.addSource(1L, profileBuilder.makeGeometryRelativeZToAbsolute(geometry, false)); + assertEquals(2, geometry.getNumPoints()); // The source line should now be made of 4 points (2 points being created by the elevated DEM) assertEquals(4, scene.sourceGeometries.get(0).getNumPoints()); List expectedProfile = Arrays.asList( diff --git a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestPathFinder.java b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestPathFinder.java index cf51d5368..88f4c3cb1 100644 --- a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestPathFinder.java +++ b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestPathFinder.java @@ -10,17 +10,20 @@ package org.noise_planet.noisemodelling.pathfinder; +import org.h2gis.functions.spatial.linear_referencing.ST_LineInterpolatePoint; import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.*; import org.locationtech.jts.io.ParseException; import org.locationtech.jts.io.WKTReader; import org.noise_planet.noisemodelling.pathfinder.path.Scene; -import org.noise_planet.noisemodelling.pathfinder.profilebuilder.ProfileBuilder; +import org.noise_planet.noisemodelling.pathfinder.profilebuilder.*; import org.noise_planet.noisemodelling.pathfinder.utils.geometry.JTSUtility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.sql.SQLException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -70,60 +73,6 @@ public void testMeanPlane() { assertEquals(-2.33, intercept, 0.01); } - /** - * Test vertical edge diffraction ray computation - * - * @throws ParseException - */ - @Test - public void TestcomputeVerticalEdgeDiffraction() throws ParseException { - GeometryFactory factory = new GeometryFactory(); - WKTReader wktReader = new WKTReader(factory); - //Create obstruction test object - ProfileBuilder profileBuilder = new ProfileBuilder(); - profileBuilder.addBuilding(wktReader.read("POLYGON((5 6, 6 5, 7 5, 7 8, 6 8, 5 7, 5 6))"), 4, -1); - profileBuilder.addBuilding(wktReader.read("POLYGON((9 7, 11 7, 11 11, 9 11, 9 7))"), 4, -1); - profileBuilder.addBuilding(wktReader.read("POLYGON((12 8, 13 8, 13 10, 12 10, 12 8))"), 4, -1); - profileBuilder.addBuilding(wktReader.read("POLYGON((10 4, 11 4, 11 6, 10 6, 10 4))"), 4, -1); - profileBuilder.finishFeeding(); - - PathFinder computeRays = new PathFinder(new Scene(profileBuilder)); - Coordinate p1 = new Coordinate(2, 6.5, 1.6); - Coordinate p2 = new Coordinate(14, 6.5, 1.6); - - List ray = computeRays.computeSideHull(true, p1, p2); - int i = 0; - assertEquals(0, p1.distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(9, 11).distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(11, 11).distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(13, 10).distance(ray.get(i++)), 0.02); - assertEquals(0, p2.distance(ray.get(i)), 0.02); - - ray = computeRays.computeSideHull(false, p1, p2); - i = 0; - assertEquals(0, p1.distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(6, 5).distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(10, 4).distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(11, 4).distance(ray.get(i++)), 0.02); - assertEquals(0, p2.distance(ray.get(i)), 0.02); - - ray = computeRays.computeSideHull(false, p2, p1); - i = 0; - assertEquals(0, p2.distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(13, 10).distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(11, 11).distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(9, 11).distance(ray.get(i++)), 0.02); - assertEquals(0, p1.distance(ray.get(i)), 0.02); - - ray = computeRays.computeSideHull(true, p2, p1); - i = 0; - assertEquals(0, p2.distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(11, 4).distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(10, 4).distance(ray.get(i++)), 0.02); - assertEquals(0, new Coordinate(6, 5).distance(ray.get(i++)), 0.02); - assertEquals(0, p1.distance(ray.get(i)), 0.02); - } - @Test public void TestSplitLineSourceIntoPoints() { GeometryFactory factory = new GeometryFactory(); @@ -144,6 +93,31 @@ public void TestSplitLineSourceIntoPoints() { assertEquals(0, new Coordinate(4, 1.25, 0).distance3D(sourcePoints.get(1)), 1e-6); } + @Test + public void TestSplitLineSourceIntoPointsRegression() throws ParseException, SQLException { + WKTReader wktReader = new WKTReader(); + LineString lineSource = (LineString) wktReader.read("LINESTRING (171698.4427670392 177701.00951635558, 171706.8669046766 " + + "177687.91784651205, 171712.97191399403 177677.7644841401, 171720.4437829301 177663.66767532472, " + + "171728.96676823843 177647.13902381528, 171734.72943947717 177634.77051055804, 171739.0868822124 " + + "177625.43309380766, 171745.47147686878 177610.67544839345, 171753.22554062092 177591.36253726296, " + + "171759.58780549894 177571.8658362897, 171769.10714508523 177535.77365270816, 171772.756902288 177519" + + ".09122776985, 171776.23273920204 177500.27220100444, 171778.51597507883 177485.76444646623, 171780" + + ".4296797503 177467.1168851778, 171781.83025393772 177445.0297520226, 171789.99859531887 177262" + + ".8134907158, 171791.8784187642 177220.3374281656, 171793.76627182262 177175.94801528286, 171794" + + ".85835770285 177143.55845900718, 171796.33670644296 177099.5455712648, 171804.84062152542 176921" + + ".4135355642, 171805.81436789143 176907.24518988002, 171807.89555734128 176888.98771900777, 171813" + + ".93869655454 176851.86881521158, 171816.43073227373 176841.3444906231, 171819.2233892781 176829" + + ".58662367053, 171826.7446807982 176804.04324781243, 171836.06368822214 176775.90431953594, 171841" + + ".44715023096 176760.3082989417, 171842.8699331516 176756.52086056024, 171846.55237681692 176747" + + ".3253388824)"); + List sourcePoints = new ArrayList<>(); + splitLineStringIntoPoints(lineSource, 1550.50, sourcePoints); + assertEquals(1, sourcePoints.size()); + // Check if the point is the middle point of the line + Coordinate expectedPoint = ST_LineInterpolatePoint.execute(lineSource, 0.5).getCoordinate(); + assertEquals(0, expectedPoint.distance(sourcePoints.get(0)), 1e-6); + } + @Test public void TestSplitRegression() throws ParseException { LineString geom = (LineString)new WKTReader().read("LINESTRING (26.3 175.5 0.0000034909259558, 111.9 90.9 0, 123 -70.9 0, 345.2 -137.8 0)"); @@ -282,4 +256,27 @@ public void TestVerticalEdgeDiffractionAirplaneSource() throws ParseException { assertTrue(ray.isEmpty()); } + + @Test + public void testMegaHeight() { + // create cut profile + + CutProfile cutProfile = new CutProfile(); + cutProfile.cutPoints.add(new CutPointSource(new Coordinate(843938.5179467835, 6519642.72565055, 0.05))); + cutProfile.cutPoints.add(new CutPointWall(13489, new Coordinate(844060.5664716291, 6519616.108346815, 1649.0), + new LineSegment(new Coordinate(844062.998140139, 6519613.740667035, 1649.0), + new Coordinate(844060.4359994413, 6519616.235385661, 1649.0)), + Arrays.asList(0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1))); + cutProfile.cutPoints.add(new CutPointWall(13482, new Coordinate(844086.1833603203, 6519610.521613932, 1649.0), + new LineSegment(new Coordinate(844086.6283247864, 6519610.685363031, 1649.0), + new Coordinate(844083.275146627, 6519609.451377079, 1649.0)), + Arrays.asList(0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1))); + cutProfile.cutPoints.add(new CutPointReceiver(new Coordinate(844089.2305787631, 6519609.85705253, 4.0))); + cutProfile.hasBuildingIntersection = true; + + List pts2d = cutProfile.computePts2D(true); + for(Coordinate pt : pts2d) { + assertFalse(Double.isNaN(pt.y)); + } + } } \ No newline at end of file diff --git a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestWallReflection.java b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestWallReflection.java index a8b86d4e2..c4e637d5b 100644 --- a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestWallReflection.java +++ b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestWallReflection.java @@ -20,6 +20,7 @@ import org.noise_planet.noisemodelling.pathfinder.profilebuilder.CutPointReceiver; import org.noise_planet.noisemodelling.pathfinder.profilebuilder.CutPointReflection; import org.noise_planet.noisemodelling.pathfinder.profilebuilder.CutPointSource; +import org.noise_planet.noisemodelling.pathfinder.profilebuilder.CutPointTopography; import org.noise_planet.noisemodelling.pathfinder.profilebuilder.CutProfile; import org.noise_planet.noisemodelling.pathfinder.profilebuilder.ProfileBuilder; import org.noise_planet.noisemodelling.pathfinder.profilebuilder.Wall; @@ -31,11 +32,48 @@ import java.util.*; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertTrue; public class TestWallReflection { + @Test + public void testCloseReflectionBeforeReceiverEvenWithPointAfterReflection() { + CutProfile cutProfile = new CutProfile(); + cutProfile.setProfileType(CutProfile.PROFILE_TYPE.REFLECTION); + cutProfile.cutPoints.add(new CutPointSource(new Coordinate(11.49, 0.0, 2.0))); + + CutPoint reflectionBasePoint = new CutPoint(new Coordinate(1.0, 0.0, 2.0), 0.0, 0.0); + cutProfile.cutPoints.add(new CutPointReflection(reflectionBasePoint, + new LineSegment(new Coordinate(1.0, -2.5, 0.0), new Coordinate(1.0, 2.5, 5.0)), + Collections.emptyList())); + + // This point stands for a later event on the path (for example a diffraction-related point). + cutProfile.cutPoints.add(new CutPointTopography(new Coordinate(1.2, 0.0, 3.0))); + cutProfile.cutPoints.add(new CutPointReceiver(new Coordinate(1.49, 0.0, 2.0))); + + assertTrue(cutProfile.hasCloseReflectionBeforeReceiver(0.5), + "The last reflection before the receiver should trigger filtering even if another point follows it."); + } + + @Test + public void testReflectionOutsideReceiverWallDistanceThreshold() { + CutProfile cutProfile = new CutProfile(); + cutProfile.setProfileType(CutProfile.PROFILE_TYPE.REFLECTION); + cutProfile.cutPoints.add(new CutPointSource(new Coordinate(11.51, 0.0, 2.0))); + + CutPoint reflectionBasePoint = new CutPoint(new Coordinate(1.0, 0.0, 2.0), 0.0, 0.0); + cutProfile.cutPoints.add(new CutPointReflection(reflectionBasePoint, + new LineSegment(new Coordinate(1.0, -2.5, 0.0), new Coordinate(1.0, 2.5, 5.0)), + Collections.emptyList())); + + cutProfile.cutPoints.add(new CutPointReceiver(new Coordinate(1.50, 0.0, 2.0))); + + assertFalse(cutProfile.hasCloseReflectionBeforeReceiver(0.5), + "The optional filter must only reject reflections with a receiver-to-wall distance strictly below 0.5 m."); + } + @Test public void testWideWall() { Coordinate cA = new Coordinate(50, 100, 5); diff --git a/noisemodelling-propagation/pom.xml b/noisemodelling-propagation/pom.xml index 5935d6084..8dc046860 100644 --- a/noisemodelling-propagation/pom.xml +++ b/noisemodelling-propagation/pom.xml @@ -10,7 +10,7 @@ org.noise-planet noisemodelling-parent - 5.0.2-SNAPSHOT + 6.0.1-SNAPSHOT ../pom.xml Compute sound propagation rays. @@ -65,6 +65,11 @@ noisemodelling-emission ${project.version} + + org.junit.jupiter + junit-jupiter + test + diff --git a/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/AttenuationVisitor.java b/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/AttenuationVisitor.java index 06eee2646..595ad2a14 100644 --- a/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/AttenuationVisitor.java +++ b/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/AttenuationVisitor.java @@ -37,6 +37,10 @@ public AttenuationVisitor(AttenuationComputeOutput multiThreadParent) { @Override public PathSearchStrategy onNewCutPlane(CutProfile cutProfile) { final SceneWithAttenuation scene = multiThreadParent.scene; + if(scene.getCloseReceiverReflectionWallDistance() > 0 + && cutProfile.hasCloseReflectionBeforeReceiver(scene.getCloseReceiverReflectionWallDistance())) { + return PathSearchStrategy.CONTINUE; + } // Source surface reflectivity double gs = scene.sourceGs.getOrDefault(cutProfile.getSource().sourcePk, SceneWithAttenuation.DEFAULT_GS); for(CnossosPath cnossosPath : CnossosPathBuilder.computeCnossosPathsFromCutProfile(cutProfile, scene.isBodyBarrier(), @@ -115,4 +119,4 @@ public void finalizeReceiver(PathFinder.ReceiverPointInfo receiver) { receiverAttenuationLevels.clear(); } -} \ No newline at end of file +} diff --git a/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/SceneWithAttenuation.java b/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/SceneWithAttenuation.java index 067beac4e..1c1de6f5a 100644 --- a/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/SceneWithAttenuation.java +++ b/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/SceneWithAttenuation.java @@ -34,10 +34,6 @@ public class SceneWithAttenuation extends Scene { */ public Map sourceGs = new HashMap<>(); - /** - * Cached source table fields - */ - public Map sourceFieldNames = new HashMap<>(); /** * If {@link #cnossosParametersPerPeriod} is empty, attenuation visitor will use this default settings and output @@ -109,7 +105,7 @@ public void setDirectionAttributes(Map directionAttr * @param geom Source geometry * @param rs Additional attributes fetched from database */ - public void addSource(Long pk, Geometry geom, SpatialResultSet rs) throws SQLException { + public void addSource(Long pk, Geometry geom, SpatialResultSet rs, Map sourceFieldNames) throws SQLException { if(sourceFieldNames.isEmpty()) { List fieldNames = JDBCUtilities.getColumnNames(rs.getMetaData()); for(int idField = 0; idField < fieldNames.size(); idField++) { @@ -186,7 +182,6 @@ public double[] getSourceAttenuation(int srcIndex, double[] frequencies, double public void clearSources() { super.clearSources(); sourceEmissionAttenuation.clear(); - sourceFieldNames.clear(); sourceGs.clear(); directionAttributes.clear(); } diff --git a/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/AttenuationCnossos.java b/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/AttenuationCnossos.java index 90c0e7f02..fb536a1b4 100644 --- a/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/AttenuationCnossos.java +++ b/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/AttenuationCnossos.java @@ -182,10 +182,10 @@ private static double getAGroundMin(SegmentPath segmentPath, CnossosPath pathPar if (pathParameters.isFavourable()) { // The lower bound of Aground,F (calculated with unmodified heights) depends on the geometry of the path - if (segmentPath.testFormF <= 1) { + if (segmentPath.testFormH <= 1) { aGroundMin = -3 * (1 - segmentPath.gm); } else { - aGroundMin = -3 * (1 - segmentPath.gm) * (1 + 2 * (1 - (1 / segmentPath.testFormF))); + aGroundMin = -3 * (1 - segmentPath.gm) * (1 + 2 * (1 - (1 / segmentPath.testFormH))); } } else { aGroundMin = -3; @@ -231,7 +231,8 @@ public static double[] aAtm(double[] alphaAtmosphericKm, double distance) { */ private static boolean isValidRcrit(CnossosPath pp, int freq) { double lambda = 340.0/freq; - return pp.delta > -lambda / 20 && pp.delta > lambda / 4 - pp.deltaPrime || pp.delta > 0; + // Eq 2.5.21: if delta >= 0, diffraction always applies; Rayleigh criterion only for delta < 0 + return pp.delta >= 0 || (pp.delta > -lambda / 20 && pp.delta > lambda / 4 - pp.deltaPrime); } /** @@ -306,8 +307,8 @@ public static double[] deltaRetrodif(CnossosPath reflect, AttenuationParameters s = pointPath.coordinate; } else if (pointPath.type.equals(REFL)) { // Look for the next DIFH of the receiver - for(int idPointNext=0; idPointNext= -2 ? 10 * ch * log10(3 + testForm) : 0; // 2.5.37 retroDiff[i] = dLRetro; @@ -377,14 +379,11 @@ private static double aDif(CnossosPath proPathParameters, AttenuationParameters (1+pow(5*lambda/ proPathParameters.e, 2))/(1./3+pow(5*lambda/ proPathParameters.e, 2)); double _delta = proPathParameters.delta; - double deltaDStar = (proPathParameters.getSegmentList().get(0).dPrime + - proPathParameters.getSegmentList().get(proPathParameters.getSegmentList().size() - 1).dPrime - - proPathParameters.getSRSegment().dPrime); double deltaDiffSR = 0; double testForm = 40 / lambda * cSecond * _delta; - if(_delta >= 0 || (_delta > -lambda/20 && _delta > lambda/4 - deltaDStar)) { + if(_delta >= 0 || (_delta > -lambda/20 && _delta > lambda/4 - proPathParameters.deltaPrime)) { deltaDiffSR = testForm>=-2 ? 10*ch*log10(3+testForm) : 0; } else if(type.equals(DIFH)) { return 0; @@ -409,8 +408,31 @@ private static double aDif(CnossosPath proPathParameters, AttenuationParameters double aGroundOR = proPathParameters.isFavourable() ? aGroundF(proPathParameters, last, data, frequencyIndex, true) : aGroundH(proPathParameters, last, data, frequencyIndex, true); //If the source or the receiver are under the mean plane, change the computation of deltaDffSR and deltaGround - double deltaGroundSO = -20*log10(1+(pow(10, -aGroundSO/20)-1)*pow(10, -(deltaDiffSPrimeR-deltaDiffSR)/20)); - double deltaGroundOR = -20*log10(1+(pow(10, -aGroundOR/20)-1)*pow(10, -(deltaDiffSRPrime-deltaDiffSR)/20)); + // + double deltaGroundSO; + double deltaGroundOR; + if(first.s.y >= first.sMeanPlane.y) { + // If the source is above the mean plane + deltaGroundSO = -20 * log10(1 + (pow(10, -aGroundSO / 20) - 1) * pow(10, + -(deltaDiffSPrimeR - deltaDiffSR) / 20)); + } else { + // Source is below the mean plane + //equation 2.5.31 et 2.5.33 + //https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:02002L0049-20210729 + deltaGroundSO = aGroundSO; + deltaDiffSR = deltaDiffSPrimeR; + } + if(last.r.y >= last.rMeanPlane.y) { + // If the receiver is above the mean plane + deltaGroundOR = -20 * log10(1 + (pow(10, -aGroundOR / 20) - 1) * pow(10, + -(deltaDiffSRPrime - deltaDiffSR) / 20)); + } else { + // Receiver is below the mean plane + // equation 2.5.31 et 2.5.33 + // https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:02002L0049-20210729 + deltaGroundOR = aGroundOR; + deltaDiffSR = deltaDiffSRPrime; + } //Double check NaN values if(Double.isNaN(deltaGroundSO)){ @@ -419,7 +441,7 @@ private static double aDif(CnossosPath proPathParameters, AttenuationParameters } if(Double.isNaN(deltaGroundOR)){ deltaGroundOR = aGroundOR; - deltaDiffSR = deltaDiffSPrimeR; + deltaDiffSR = deltaDiffSRPrime; } double aDiff = min(25, max(0, deltaDiffSR)) + deltaGroundSO + deltaGroundOR; diff --git a/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/CnossosPath.java b/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/CnossosPath.java index 908f3a663..57ce1a234 100644 --- a/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/CnossosPath.java +++ b/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/CnossosPath.java @@ -34,6 +34,9 @@ public class CnossosPath extends Path { public double[] aGlobalRaw = new double[0]; public double[] aDif = new double[0]; public double[] aSource = new double[0]; // directivity attenuation + /** + * Step delta, in meters, between the receiver-source line and the top of the diffraction point in the path. + */ public double delta = Double.MAX_VALUE; public double deltaPrime= Double.MAX_VALUE;; public double deltaSPrimeR= Double.MAX_VALUE; diff --git a/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/CnossosPathBuilder.java b/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/CnossosPathBuilder.java index 41ac584f1..a97b9eced 100644 --- a/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/CnossosPathBuilder.java +++ b/noisemodelling-propagation/src/main/java/org/noise_planet/noisemodelling/propagation/cnossos/CnossosPathBuilder.java @@ -20,7 +20,6 @@ import java.util.stream.Collectors; import static java.lang.Math.*; -import static java.lang.Math.max; import static org.noise_planet.noisemodelling.pathfinder.utils.geometry.CurvedProfileGenerator.toCurve; import static org.noise_planet.noisemodelling.propagation.cnossos.PointPath.POINT_TYPE.*; import static org.noise_planet.noisemodelling.pathfinder.utils.geometry.GeometryUtils.projectPointOnLine; @@ -43,6 +42,11 @@ public static void computeRayleighDiff(SegmentPath srSeg, CutProfile cutProfile, CutPoint srcCut = cutProfile.getSource(); CutPoint rcvCut = cutProfile.getReceiver(); for (int i0Cut = 1; i0Cut < cuts.size() - 1; i0Cut++) { + // Skip reflection points — they are not terrain obstacles and should not + // create Rayleigh diffraction points + if(cuts.get(i0Cut) instanceof CutPointReflection) { + continue; + } int iO = cut2DGroundIndex.get(i0Cut); Coordinate o = pts2DGround[iO]; @@ -114,7 +118,7 @@ public static void computeRayleighDiff(SegmentPath srSeg, CutProfile cutProfile, pathParameters.deltaPrime = toCurve(seg1.dPrime, srSeg.dPrime) + toCurve(seg2.dPrime, srSeg.dPrime) - toCurve(srSeg.dPrime, srSeg.dPrime); } else { Coordinate pA = dSPrimeRPrime.pointAlong((o.x-srcPrime.x)/(rcvPrime.x-srcPrime.x)); - pathParameters.deltaPrime =2*toCurve(srcPrime.distance(pA), srSeg.dPrime) + 2*toCurve(pA.distance(srcPrime), srSeg.dPrime) - toCurve(seg1.dPrime, srSeg.dPrime) - toCurve(seg2.dPrime, srSeg.d) - toCurve(srSeg.dPrime, srSeg.dPrime); + pathParameters.deltaPrime =2*toCurve(srcPrime.distance(pA), srSeg.dPrime) + 2*toCurve(pA.distance(rcvPrime), srSeg.dPrime) - toCurve(seg1.dPrime, srSeg.dPrime) - toCurve(seg2.dPrime, srSeg.dPrime) - toCurve(srSeg.dPrime, srSeg.dPrime); } } @@ -220,11 +224,12 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile (cutProfile.profileType == CutProfile.PROFILE_TYPE.LEFT || cutProfile.profileType == CutProfile.PROFILE_TYPE.RIGHT) && !cutProfile.isCurvedPath()) { - // TODO reflection cut planes should be also done on curved profile throw new IllegalArgumentException("A favourable path cannot be computed using lateral non curved cut profile"); } List segments = new ArrayList<>(); List points = new ArrayList<>(); + + // Use original cutPoints for all calculations (no transformation) final List cutProfilePoints = cutProfile.cutPoints; List pts2D = cutProfile.computePts2D(); @@ -238,6 +243,39 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile Coordinate firstPts2D = pts2D.get(0); Coordinate lastPts2D = pts2D.get(pts2D.size()-1); SegmentPath srPath = computeSegment(firstPts2D, lastPts2D, meanPlane, cutProfile.getGPath(), cutProfile.getSource().groundCoefficient); + // Directive 2002/49/EC, section 2.5.3 "Significant heights above the ground": + // "If the equivalent height of a point becomes negative, i.e. if the point is located + // below the mean ground plane, a null height is retained, and the equivalent point is + // then identical with its possible image." + // Applied here only to DIRECT/REFLECTION SR segments. Lateral (LEFT/RIGHT) paths are + // excluded because their 2D cut plane geometry differs from the vertical plane and + // applying this rule there causes regressions (e.g. TC14). + if(cutProfile.profileType == CutProfile.PROFILE_TYPE.DIRECT || + cutProfile.profileType == CutProfile.PROFILE_TYPE.REFLECTION) { + double slopeNorm = Math.sqrt(1 + meanPlane[0] * meanPlane[0]); + double signedZsH = (firstPts2D.y - (meanPlane[0] * firstPts2D.x + meanPlane[1])) / slopeNorm; + double signedZrH = (lastPts2D.y - (meanPlane[0] * lastPts2D.x + meanPlane[1])) / slopeNorm; + boolean needsRecompute = false; + if(signedZsH < 0) { + srPath.zsH = 0.0; + needsRecompute = true; + } + if(signedZrH < 0) { + srPath.zrH = 0.0; + needsRecompute = true; + } + if(needsRecompute && (srPath.zsH + srPath.zrH) > 0) { + double gPath = cutProfile.getGPath(); + srPath.testFormH = srPath.dp / (30 * (srPath.zsH + srPath.zrH)); + srPath.gPathPrime = srPath.testFormH <= 1 ? gPath * srPath.testFormH + gS * (1 - srPath.testFormH) : gPath; + double deltaZT = 6e-3 * srPath.dp / (srPath.zsH + srPath.zrH); + double deltaZS = ALPHA0 * pow((srPath.zsH / (srPath.zsH + srPath.zrH)), 2) * (srPath.dp * srPath.dp / 2); + srPath.zsF = srPath.zsH + deltaZS + deltaZT; + double deltaZR = ALPHA0 * pow((srPath.zrH / (srPath.zsH + srPath.zrH)), 2) * (srPath.dp * srPath.dp / 2); + srPath.zrF = srPath.zrH + deltaZR + deltaZT; + srPath.testFormF = srPath.dp / (30 * (srPath.zsF + srPath.zrF)); + } + } srPath.setPoints2DGround(pts2DGround); srPath.dc = CGAlgorithms3D.distance(cutProfile.getReceiver().getCoordinate(), cutProfile.getSource().getCoordinate()); @@ -248,15 +286,59 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile cnossosPath.setSRSegment(srPath); cnossosPath.init(exactFrequencyArray.size()); List hullPts2D = pts2D; - if(favourable && cutProfile.profileType != CutProfile.PROFILE_TYPE.REFLECTION) { + if(favourable) { // Compute the altered profile for favourable path hullPts2D = cutProfile.computePts2D(true); } + boolean ignoreBuildingsInConvexHull = (cutProfile.profileType == CutProfile.PROFILE_TYPE.LEFT || + cutProfile.profileType == CutProfile.PROFILE_TYPE.RIGHT); + // Compute convex hull of the profile - List hullPointsIndices = cutProfile.getConvexHullIndices(hullPts2D); + List hullPointsIndices = cutProfile.getConvexHullIndices(hullPts2D, ignoreBuildingsInConvexHull); // Src if perceived source position from the receiver point of view Coordinate src = cutProfile.getSource().getCoordinate(); + + // For reflection paths without diffraction points, check if reflection is valid + // In favorable conditions, the wall is effectively lowered, and we need to verify + // the reflection point is actually on the transformed wall, not above it + if (favourable && cutProfile.profileType == CutProfile.PROFILE_TYPE.REFLECTION && hullPointsIndices.size() == 2) { + // No diffraction points, just source -> reflection -> receiver + // Compute transformed coordinates for favorable conditions to check reflection validity + List transformedCutPoints = new ArrayList<>(); + cutProfile.computePts2D(true, transformedCutPoints); + + if (!transformedCutPoints.isEmpty()) { + for (int i = 0; i < transformedCutPoints.size(); i++) { + CutPoint transformedPoint = transformedCutPoints.get(i); + if (transformedPoint instanceof CutPointReflection && + Double.compare(transformedPoint.getCoordinate().z, transformedPoint.getzGround()) != 0) { + CutPointReflection cutPointReflection = (CutPointReflection) transformedPoint; + + // Get the transformed wall altitude at the reflection point + double transformedWallAltitude = Vertex.interpolateZ(transformedPoint.coordinate, + cutPointReflection.wall.p0, cutPointReflection.wall.p1); + + // Get the direct line altitude from source to receiver at this reflection position + // Use ORIGINAL coordinates for the source and receiver + Coordinate srcCoord = cutProfile.cutPoints.get(0).getCoordinate(); + Coordinate rcvCoord = cutProfile.cutPoints.get(cutProfile.cutPoints.size() - 1).getCoordinate(); + double reflectionX = pts2D.get(i).x; + double srcX = pts2D.get(0).x; + double rcvX = pts2D.get(cutProfile.cutPoints.size() - 1).x; + double t = (reflectionX - srcX) / (rcvX - srcX); + double directLineAltitude = srcCoord.z + t * (rcvCoord.z - srcCoord.z); + + // If the direct line clears the transformed wall (goes above it), reject the reflection + if (directLineAltitude > transformedWallAltitude + EPSILON) { + // Ray passes over the wall, reflection is not valid in favorable conditions + return null; + } + } + } + } + } + // Move then check reflection height if there is diffraction on the path if(hullPointsIndices.size() > 2) { for (int i = 1; i < hullPointsIndices.size(); i++) { @@ -264,18 +346,22 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile int i1 = hullPointsIndices.get(i); LineSegment segmentHull = new LineSegment(pts2D.get(hullPointsIndices.get(i - 1)), pts2D.get(hullPointsIndices.get(i))); for (int pointIndex = i0 + 1; pointIndex < i1; pointIndex++) { - final CutPoint currentPoint = cutProfilePoints.get(pointIndex); + // Always use ORIGINAL cutPoints for wall altitude checks, not transformed ones + final CutPoint originalPoint = cutProfile.cutPoints.get(pointIndex); // If the current point is the reflection point (not on the ground level) - if (currentPoint instanceof CutPointReflection && - Double.compare(currentPoint.getCoordinate().z, currentPoint.getzGround()) != 0) { - CutPointReflection cutPointReflection = (CutPointReflection) currentPoint; + if (originalPoint instanceof CutPointReflection && + Double.compare(originalPoint.getCoordinate().z, originalPoint.getzGround()) != 0) { + CutPointReflection cutPointReflection = (CutPointReflection) originalPoint; Coordinate interpolatedReflectionPoint = segmentHull.closestPoint(pts2D.get(pointIndex)); - // Check if the new elevation of the reflection point is not higher than the wall - double wallAltitudeAtReflexionPoint = Vertex.interpolateZ(currentPoint.coordinate, + + // Get the actual wall altitude at the reflection point using ORIGINAL coordinates + double wallAltitudeAtReflexionPoint = Vertex.interpolateZ(originalPoint.coordinate, cutPointReflection.wall.p0, cutPointReflection.wall.p1); + + // Check if the new elevation of the reflection point is not higher than the wall if(wallAltitudeAtReflexionPoint + EPSILON >= interpolatedReflectionPoint.y) { - // update the reflection position - currentPoint.getCoordinate().setZ(interpolatedReflectionPoint.y); + // update the reflection position in BOTH original cutPoint AND pts2D + originalPoint.getCoordinate().setZ(interpolatedReflectionPoint.y); pts2D.get(pointIndex).setY(interpolatedReflectionPoint.y); } else { // Reflection is not valid, so the whole path is not valid @@ -292,8 +378,9 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile int i1 = hullPointsIndices.get(i); int i0Ground = cut2DGroundIndex.get(i0); int i1Ground = cut2DGroundIndex.get(i1); - final CutPoint cutPt0 = cutProfilePoints.get(i0); - final CutPoint cutPt1 = cutProfilePoints.get(i1); + // Always use ORIGINAL cutPoints for geometric calculations, not transformed ones + final CutPoint cutPt0 = cutProfile.cutPoints.get(i0); + final CutPoint cutPt1 = cutProfile.cutPoints.get(i1); // ground index may be near the diffraction point // Depending on the range, we have to pick the bottom of the wall or the top of the wall point if (i1Ground - 1 > i0Ground && cutPt1 instanceof CutPointWall) { @@ -308,9 +395,9 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile // First segment, add the source point in the array points.add(new PointPath(pts2D.get(i0), cutPt0.getzGround(), SRCE)); // look for the first reflection before the first diffraction, the source orientation is to the first reflection point - Coordinate targetPosition = cutProfilePoints.get(i1).getCoordinate(); + Coordinate targetPosition = cutProfile.cutPoints.get(i1).getCoordinate(); for (int pointIndex = i0 + 1; pointIndex < i1; pointIndex++) { - final CutPoint currentPoint = cutProfilePoints.get(pointIndex); + final CutPoint currentPoint = cutProfile.cutPoints.get(pointIndex); if ((currentPoint instanceof CutPointReflection || currentPoint instanceof CutPointVEdgeDiffraction) && Double.compare(currentPoint.getCoordinate().z, currentPoint.getzGround()) != 0) { @@ -321,16 +408,16 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile } } Orientation emissionDirection = computeOrientation(cutProfile.getSource().orientation, - cutProfilePoints.get(i0).getCoordinate(), targetPosition); + cutProfile.cutPoints.get(i0).getCoordinate(), targetPosition); points.get(0).orientation = emissionDirection; - // TODO what about favourable path with curved profile ? cnossosPath.raySourceReceiverDirectivity = emissionDirection; src = pts2D.get(i0); } // Add reflection/vertical edge diffraction points/segments between i0 i1 int previousPivotPoint = i0; + int previousPivotGround = i0Ground; for (int pointIndex = i0 + 1; pointIndex < i1; pointIndex++) { - final CutPoint currentPoint = cutProfilePoints.get(pointIndex); + final CutPoint currentPoint = cutProfile.cutPoints.get(pointIndex); if (currentPoint instanceof CutPointReflection && Double.compare(currentPoint.getCoordinate().z, currentPoint.getzGround()) != 0) { // If the current point is a reflection and not before/after the reflection @@ -346,11 +433,12 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile PointPath diffractionPoint = new PointPath(pts2D.get(pointIndex),currentPoint.getzGround(), new ArrayList<>(), DIFV); points.add(diffractionPoint); // Compute additional segment - Coordinate[] segmentGroundPoints = Arrays.copyOfRange(pts2DGround, i0Ground,cut2DGroundIndex.get(pointIndex) + 1); + Coordinate[] segmentGroundPoints = Arrays.copyOfRange(pts2DGround, previousPivotGround, cut2DGroundIndex.get(pointIndex) + 1); meanPlane = JTSUtility.getMeanPlaneCoefficients(segmentGroundPoints); SegmentPath seg = computeSegment(pts2D.get(previousPivotPoint), pts2D.get(pointIndex), - meanPlane, cutProfile.getGPath(cutPt0, cutProfilePoints.get(pointIndex), Scene.DEFAULT_G_BUILDING), gS); + meanPlane, cutProfile.getGPathByIndex(previousPivotPoint, pointIndex, Scene.DEFAULT_G_BUILDING), gS); seg.setPoints2DGround(segmentGroundPoints); + previousPivotGround = cut2DGroundIndex.get(pointIndex); previousPivotPoint = pointIndex; segments.add(seg); } @@ -360,10 +448,10 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile // we added segments before i1 vertical plane diffraction point, but it is the last vertical plane // diffraction point and we must add the remaining segment between the last horizontal diffraction point // and the last point - Coordinate[] segmentGroundPoints = Arrays.copyOfRange(pts2DGround, i1Ground, pts2DGround.length); + Coordinate[] segmentGroundPoints = Arrays.copyOfRange(pts2DGround, previousPivotGround, pts2DGround.length); meanPlane = JTSUtility.getMeanPlaneCoefficients(segmentGroundPoints); SegmentPath seg = computeSegment(pts2D.get(previousPivotPoint), pts2D.get(pts2D.size() - 1), - meanPlane, cutProfile.getGPath(cutPt1, cutProfilePoints.get(cutProfilePoints.size() - 1), Scene.DEFAULT_G_BUILDING), + meanPlane, cutProfile.getGPathByIndex(previousPivotPoint, cutProfile.cutPoints.size() - 1, Scene.DEFAULT_G_BUILDING), gS); seg.setPoints2DGround(segmentGroundPoints); segments.add(seg); @@ -375,8 +463,8 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile Coordinate[] segmentGroundPoints = Arrays.copyOfRange(pts2DGround, i0Ground,i1Ground + 1); meanPlane = JTSUtility.getMeanPlaneCoefficients(segmentGroundPoints); SegmentPath path = computeSegment(pts2D.get(i0), pts2D.get(i1), meanPlane, - cutProfile.getGPath(cutProfilePoints.get(i0), cutProfilePoints.get(i1), Scene.DEFAULT_G_BUILDING), - cutProfilePoints.get(i0).groundCoefficient); + cutProfile.getGPathByIndex(i0, i1, Scene.DEFAULT_G_BUILDING), + cutProfile.cutPoints.get(i0).groundCoefficient); path.dc = cutPt0.getCoordinate().distance3D(cutPt1.getCoordinate()); path.setPoints2DGround(segmentGroundPoints); segments.add(path); @@ -488,8 +576,14 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile if (sr.orientationIndex(c0) == 1) { cnossosPath.delta = toCurve(seg1.d, srPath.d) + toCurve(cnossosPath.e, srPath.d) + toCurve(seg2.d, srPath.d) - toCurve(srPath.d, srPath.d); } else { - Coordinate pA = sr.pointAlong((c0.x - srcPrime.x) / (rcvPrime.x - srcPrime.x)); - cnossosPath.delta = 2 * toCurve(srcPrime.distance(pA), srPath.dPrime) + 2 * toCurve(pA.distance(rcvPrime), srPath.dPrime) - toCurve(seg1.dPrime, srPath.dPrime) - toCurve(seg2.dPrime, srPath.dPrime) - toCurve(srPath.dPrime, srPath.dPrime); + Coordinate pA = sr.pointAlong((c0.x - src.x) / (rcv.x - src.x)); + cnossosPath.delta = + 2 * toCurve(src.distance(pA), srPath.d) + + 2 * toCurve(pA.distance(rcv), srPath.d) - + toCurve(seg1.d, srPath.d) - + toCurve(cnossosPath.e, srPath.d) - + toCurve(seg2.d, srPath.d) - + toCurve(srPath.d, srPath.d); } } @@ -497,10 +591,10 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile cnossosPath.deltaPrime = dSPrimeRPrime.orientationIndex(c0) * (seg1.dPrime + cnossosPath.e + seg2.dPrime - srPath.dPrime); } else { if(dSPrimeRPrime.orientationIndex(c0) == 1) { - cnossosPath.deltaPrime = toCurve(seg1.dPrime, srPath.dPrime) + toCurve(seg2.dPrime, srPath.dPrime) - toCurve(srPath.dPrime, srPath.dPrime); + cnossosPath.deltaPrime = toCurve(seg1.dPrime, srPath.dPrime) + toCurve(cnossosPath.e, srPath.dPrime) + toCurve(seg2.dPrime, srPath.dPrime) - toCurve(srPath.dPrime, srPath.dPrime); } else { Coordinate pA = dSPrimeRPrime.pointAlong((c0.x-srcPrime.x)/(rcvPrime.x-srcPrime.x)); - cnossosPath.deltaPrime =2*toCurve(srcPrime.distance(pA), srPath.dPrime) + 2*toCurve(pA.distance(srcPrime), srPath.dPrime) - toCurve(seg1.dPrime, srPath.dPrime) - toCurve(seg2.dPrime, srPath.d) - toCurve(srPath.dPrime, srPath.dPrime); + cnossosPath.deltaPrime =2*toCurve(srcPrime.distance(pA), srPath.dPrime) + 2*toCurve(pA.distance(rcvPrime), srPath.dPrime) - toCurve(seg1.dPrime, srPath.dPrime) - toCurve(cnossosPath.e, srPath.dPrime) - toCurve(seg2.dPrime, srPath.dPrime) - toCurve(srPath.dPrime, srPath.dPrime); } } return cnossosPath; @@ -508,11 +602,11 @@ public static CnossosPath computeCnossosPathFromCutProfile(CutProfile cutProfile /** - * - * @param sourceOrientation - * @param src - * @param next - * @return + * Compute the orientation from a source orientation and two coordinates + * @param sourceOrientation Source orientation + * @param src Source coordinate + * @param next Next coordinate + * @return The computed orientation or null if the source orientation is null */ private static Orientation computeOrientation(Orientation sourceOrientation, Coordinate src, Coordinate next){ if(sourceOrientation == null) { diff --git a/noisemodelling-propagation/src/test/java/org/noise_planet/noisemodelling/propagation/AttenuationComputeOutputCnossosTest.java b/noisemodelling-propagation/src/test/java/org/noise_planet/noisemodelling/propagation/AttenuationComputeOutputCnossosTest.java index cc14e49c8..d9fbd4004 100644 --- a/noisemodelling-propagation/src/test/java/org/noise_planet/noisemodelling/propagation/AttenuationComputeOutputCnossosTest.java +++ b/noisemodelling-propagation/src/test/java/org/noise_planet/noisemodelling/propagation/AttenuationComputeOutputCnossosTest.java @@ -26,7 +26,9 @@ import org.slf4j.LoggerFactory; import java.io.*; +import java.net.URL; import java.util.*; +import java.util.stream.Collectors; import java.util.stream.IntStream; import static java.lang.Double.NaN; @@ -95,15 +97,20 @@ private static void writeResultsToRst(String fileName, String testName, String v } - private static CutProfile loadCutProfile(String utName) throws IOException { - String testCaseFileName = utName + ".json"; - try(InputStream inputStream = PathFinder.class.getResourceAsStream("test_cases/"+testCaseFileName)) { - ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(inputStream, CutProfile.class); - } + private static CutProfile loadCutProfile(InputStream inputStream) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(inputStream, CutProfile.class); + } + + private static AttenuationComputeOutput computeCnossosPath(String... utNames) throws IOException { + URL[] urls = Arrays.stream(utNames) + .map(utName -> PathFinder.class.getResource("test_cases/" + utName + ".json")) + .toArray(URL[]::new); // <--- This is the key change + + return computeCnossosPath(urls); } - private static AttenuationComputeOutput computeCnossosPath(String... utNames) + private static AttenuationComputeOutput computeCnossosPath(URL... cutProfileUrls) throws IOException { //Create profile builder ProfileBuilder profileBuilder = new ProfileBuilder() @@ -124,8 +131,11 @@ private static AttenuationComputeOutput computeCnossosPath(String... utNames) CutPlaneVisitor cutPlaneVisitor = propDataOut.subProcess(new EmptyProgressVisitor()); PathFinder.ReceiverPointInfo lastReceiver = new PathFinder.ReceiverPointInfo(-1,-1,new Coordinate()); - for (String utName : utNames) { - CutProfile cutProfile = loadCutProfile(utName); + for (URL cutProfileUrl : cutProfileUrls) { + CutProfile cutProfile; + try(InputStream inputStream = cutProfileUrl.openStream()) { + cutProfile = loadCutProfile(inputStream); + } cutPlaneVisitor.onNewCutPlane(cutProfile); if(lastReceiver.receiverPk != -1 && cutProfile.getReceiver().receiverPk != lastReceiver.receiverPk) { // merge attenuation per receiver @@ -825,12 +835,14 @@ public void TC07() throws IOException { double[] expectedDeltaGroundORF = new double[]{-1.18, -0.96, -0.81, -0.71, -0.65, -0.61, -0.60, -0.59}; double[] expectedADiffF = new double[]{3.36, 4.33, 5.69, 7.50, 9.74, 12.30, 15.06, 17.94}; - double[] expectedWH = new double[]{1.1e-04, 6.0e-04, 3.4e-03, Double.NaN, Double.NaN, 0.53, 2.70, 12.70}; - double[] expectedCfH = new double[]{200.89, 217.45, 220.41, Double.NaN, Double.NaN, 1.88, 0.37, 0.08}; - double[] expectedAGroundH = new double[]{-1.32, -1.32, -1.32, Double.NaN, -Double.NaN, -1.32, -1.32, -1.32}; + // W/Cf/Aground(S,R) not provided in ISO for homogeneous case (diffraction dominates) + // In homogeneous atmosphere, WH==WF and CfH==CfF (same SR segment computation) + double[] expectedWH = new double[]{0.00, 0.00, 0.00, 0.01, 0.08, 0.42, 2.16, 10.35}; + double[] expectedCfH = new double[]{199.59, 214.11, 225.39, 131.90, 22.89, 2.42, 0.46, 0.10}; + double[] expectedAGroundH = new double[]{-1.48, -1.48, -1.48, 0.95, 5.74, -1.48, -1.48, -1.48}; double[] expectedWF = new double[]{0.00, 0.00, 0.00, 0.01, 0.08, 0.42, 2.16, 10.35}; double[] expectedCfF = new double[]{199.59, 214.11, 225.39, 131.90, 22.89, 2.42, 0.46, 0.10}; - double[] expectedAGroundF = new double[]{-1.32, -1.32, -1.29, -1.05, -1.32, -1.32, -1.32, -1.32}; + double[] expectedAGroundF = new double[]{-2.16, -2.16, -2.16, -2.16, -0.99, -2.16, -2.16, -2.16}; double[] expectedAlphaAtm = new double[]{0.12, 0.41, 1.04, 1.93, 3.66, 9.66, 32.77, 116.88}; double[] expectedAAtm = new double[]{0.02, 0.08, 0.20, 0.37, 0.71, 1.88, 6.36, 22.70}; @@ -879,9 +891,9 @@ public void TC07() throws IOException { assertDoubleArrayEquals("DeltaGroundORH", expectedDeltaGroundORH, actualDeltaGroundORH, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("ADiffH", expectedADiffH, actualADiffH, ERROR_EPSILON_VERY_LOW); - assertDoubleArrayEquals("WH", expectedWH, actualWH, ERROR_EPSILON_HIGH); - assertDoubleArrayEquals("CfH", expectedCfH, actualCfH, ERROR_EPSILON_VERY_HIGH); - assertDoubleArrayEquals("AGroundH", expectedAGroundH, actualAGroundH, ERROR_EPSILON_MEDIUM); + assertDoubleArrayEquals("WH", expectedWH, actualWH, ERROR_EPSILON_LOWEST); + assertDoubleArrayEquals("CfH", expectedCfH, actualCfH, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("AGroundH", expectedAGroundH, actualAGroundH, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("AlphaAtm", expectedAlphaAtm, actualAlphaAtm, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("AAtm", expectedAAtm, actualAAtm, ERROR_EPSILON_LOWEST); @@ -922,7 +934,7 @@ public void TC07() throws IOException { assertDoubleArrayEquals("WF", expectedWF, actualWF, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("CfF", expectedCfF, actualCfF, ERROR_EPSILON_LOW); - assertDoubleArrayEquals("AGroundF", expectedAGroundF, actualAGroundF, ERROR_EPSILON_HIGH); + assertDoubleArrayEquals("AGroundF", expectedAGroundF, actualAGroundF, ERROR_EPSILON_LOWEST); double[] actualLF = addArray(cnossosPath.aGlobalRaw, SOUND_POWER_LEVELS); assertDoubleArrayEquals("LF", expectedLF, actualLF, ERROR_EPSILON_LOWEST); @@ -1217,7 +1229,7 @@ public void TC08() throws IOException { assertDoubleArrayEquals("LF - left lateral", expectedLF, actualLF, ERROR_EPSILON_VERY_LOW); double[] L = addArray(propDataOut.getVerticesSoundLevel().get(0).levels, new double[]{93-26.2,93-16.1,93-8.6,93-3.2,93,93+1.2,93+1.0,93-1.1}); - assertArrayEquals( new double[]{8.17,16.86,22.51,25.46,24.87,23.44,15.93,-5.43},L, ERROR_EPSILON_VERY_LOW); + assertArrayEquals( new double[]{8.17,16.86,22.51,25.46,24.87,23.44,15.93,-5.43},L, ERROR_EPSILON_LOWEST); } // public static void addGroundAttenuationTC5(ProfileBuilder profileBuilder) { @@ -1528,7 +1540,7 @@ public void TC09() throws IOException { double[] L = addArray(propDataOut.getVerticesSoundLevel().get(0).levels, new double[]{93-26.2,93-16.1,93-8.6,93-3.2,93,93+1.2,93+1.0,93-1.1}); - assertArrayEquals( new double[]{6.41,14.50,19.52,22.09,22.16,19.28,11.62,-9.31},L, ERROR_EPSILON_VERY_LOW); + assertArrayEquals( new double[]{6.41,14.50,19.52,22.09,22.16,19.28,11.62,-9.31},L, ERROR_EPSILON_LOWEST); } /** @@ -1661,10 +1673,11 @@ public void TC10() throws IOException { double[] actualLA = sumArray(actualL, A_WEIGHTING); //Assertions - assertEquals(0.00, cnossosPathDirectH.getSRSegment().sPrime.x, ERROR_EPSILON_MEDIUM); - assertEquals(-1.00, cnossosPathDirectH.getSRSegment().sPrime.y, ERROR_EPSILON_HIGHEST); - assertEquals(20.00, cnossosPathDirectH.getSRSegment().rPrime.x, ERROR_EPSILON_LOW); - assertEquals(-4.00, cnossosPathDirectH.getSRSegment().rPrime.y, ERROR_EPSILON_HIGHEST); + // Table 76 - Mirror points are on sub-segments, not SR segment + assertEquals(0.00, cnossosPathDirectH.getSegmentList().get(0).sPrime.x, ERROR_EPSILON_LOWEST); + assertEquals(-1.00, cnossosPathDirectH.getSegmentList().get(0).sPrime.y, ERROR_EPSILON_LOWEST); + assertEquals(20.00, cnossosPathDirectH.getSegmentList().get(2).rPrime.x, ERROR_EPSILON_LOWEST); + assertEquals(-4.00, cnossosPathDirectH.getSegmentList().get(2).rPrime.y, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("DeltaDiffSRH - vertical plane", expectedDeltaDiffSRH, actualDeltaDiffSRH, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("AGroundSOH - vertical plane", expectedAGroundSOH, actualAGroundSOH, ERROR_EPSILON_VERY_LOW); @@ -1941,10 +1954,11 @@ public void TC11() throws IOException { double[] actualLA = sumArray(actualL,A_WEIGHTING); //Assertions - assertEquals(0.00, cnossosPathDirectH.getSRSegment().sPrime.x, ERROR_EPSILON_HIGH); - assertEquals(-1.00, cnossosPathDirectH.getSRSegment().sPrime.y, ERROR_EPSILON_HIGHEST); - assertEquals(5.10, cnossosPathDirectH.getSRSegment().rPrime.x, ERROR_EPSILON_HIGHEST); - assertEquals(-1.76, cnossosPathDirectH.getSRSegment().rPrime.y, ERROR_EPSILON_HIGHEST); + // Table 87 - Mirror points are on sub-segments, not SR segment + assertEquals(0.00, cnossosPathDirectH.getSegmentList().get(0).sPrime.x, ERROR_EPSILON_LOWEST); + assertEquals(-1.00, cnossosPathDirectH.getSegmentList().get(0).sPrime.y, ERROR_EPSILON_LOWEST); + assertEquals(5.10, cnossosPathDirectH.getSegmentList().get(1).rPrime.x, ERROR_EPSILON_LOWEST); + assertEquals(-1.76, cnossosPathDirectH.getSegmentList().get(1).rPrime.y, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("DeltaDiffSRH - vertical plane", expectedDeltaDiffSRH, actualDeltaDiffSRH, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("AGroundSOH - vertical plane", expectedAGroundSOH, actualAGroundSOH, ERROR_EPSILON_VERY_LOW); @@ -2041,7 +2055,7 @@ public void TC11() throws IOException { assertDoubleArrayEquals("AGroundF", expectedAGroundF, actualAGroundF, ERROR_EPSILON_VERY_LOW); double[] L = addArray(propDataOut.getVerticesSoundLevel().get(0).levels, sumArray(SOUND_POWER_LEVELS, A_WEIGHTING)); - assertArrayEquals( new double[]{21.28,28.39,32.47,34.51,34.54,33.37,32.14,27.73},L, ERROR_EPSILON_VERY_LOW); + assertArrayEquals( new double[]{21.28,28.39,32.47,34.51,34.54,33.37,32.14,27.73},L, ERROR_EPSILON_LOWEST); } /** @@ -2565,7 +2579,7 @@ public void TC13() throws IOException { assertDoubleArrayEquals("LH - right lateral", expectedLH, actualLH, ERROR_EPSILON_VERY_LOW); double[] L = addArray(propDataOut.getVerticesSoundLevel().get(0).levels, new double[]{93-26.2,93-16.1,93-8.6,93-3.2,93,93+1.2,93+1.0,93-1.1}); - assertArrayEquals( new double[]{5.14,12.29,16.39,18.47,18.31,15.97,9.72,-9.92},L, ERROR_EPSILON_VERY_LOW); + assertArrayEquals( new double[]{5.14,12.29,16.39,18.47,18.31,15.97,9.72,-9.92},L, ERROR_EPSILON_LOWEST); } /** @@ -2906,7 +2920,7 @@ public void TC15() throws IOException { getSRSegment().getPoints2DGround())); assertPlanes(segmentsMeanPlanes0, cnossosPathDirectH.getSegmentList()); assertPlanes(segmentsMeanPlanes2, cnossosPathLeftH.getSRSegment()); // left - //assertPlanes(segmentsMeanPlanes1, propDataOut.getPropagationPaths().get(1).getSRSegment()); // right : error in value of b cnossos + assertPlanes(segmentsMeanPlanes1, cnossosPathRightH.getSRSegment()); // right //Expected values //Path0 : vertical plane @@ -2983,7 +2997,7 @@ public void TC15() throws IOException { //Expected values - right lateral double[] expectedWH = new double[]{0.00, 0.00, 0.00, 0.01, 0.07, 0.37, 1.92, 9.32}; double[] expectedCfH = new double[]{55.20, 56.69, 61.53, 61.63, 29.93, 4.28, 0.52, 0.11}; - double[] expectedAGroundH = new double[]{-1.56, -1.56, -1.32, -1.32, -1.56, -1.56, -1.56, -1.56}; + double[] expectedAGroundH = new double[]{-1.56, -1.56, -1.32, -1.23, -1.56, -1.56, -1.56, -1.56}; double[] expectedWF = new double[]{0.00, 0.00, 0.00, 0.01, 0.06, 0.33, 1.69, 8.30}; double[] expectedCfF = new double[]{55.15, 56.48, 61.02, 62.61, 33.11, 5.18, 0.59, 0.12}; double[] expectedAGroundF = new double[]{-1.56, -1.30, -1.08, -1.56, -1.56, -1.56, -1.56, -1.56}; @@ -2991,7 +3005,7 @@ public void TC15() throws IOException { expectedAlphaAtm = new double[]{0.12, 0.41, 1.04, 1.93, 3.66, 9.66, 32.77, 116.88}; expectedAAtm = new double[]{0.01, 0.02, 0.06, 0.11, 0.20, 0.53, 1.80, 6.41}; expectedADiv = new double[]{45.05, 45.05, 45.05, 45.05, 45.05, 45.05, 45.05, 45.05}; - expectedDeltaDiffSRH = new double[]{17.54, 20.82, 25.57, 28.82, 31.9, 34.91, 37.92, 40.93}; + expectedDeltaDiffSRH = new double[]{17.54, 21.82, 25.57, 28.82, 31.89, 34.91, 37.92, 40.93}; expectedLH = new double[]{31.97, 27.66, 23.64, 20.26, 17.42, 14.07, 9.79, 2.17}; //Actual values @@ -3011,20 +3025,20 @@ public void TC15() throws IOException { actualLH = addArray(cnossosPathRightH.aGlobalRaw, SOUND_POWER_LEVELS); //Assertions - assertDoubleArrayEquals("WH - right lateral", expectedWH, actualWH, ERROR_EPSILON_MEDIUM); - assertDoubleArrayEquals("CfH - right lateral", expectedCfH, actualCfH, ERROR_EPSILON_HIGH); - assertDoubleArrayEquals("AGroundH - right lateral", expectedAGroundH, actualAGroundH, ERROR_EPSILON_MEDIUM); - assertDoubleArrayEquals("WF - right lateral", expectedWF, actualWF, ERROR_EPSILON_HIGH); - assertDoubleArrayEquals("CfF - right lateral", expectedCfF, actualCfF, ERROR_EPSILON_VERY_HIGH); - assertDoubleArrayEquals("AGroundF - right lateral", expectedAGroundF, actualAGroundF, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("WH - right lateral", expectedWH, actualWH, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("CfH - right lateral", expectedCfH, actualCfH, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("AGroundH - right lateral", expectedAGroundH, actualAGroundH, ERROR_EPSILON_LOWEST); + assertDoubleArrayEquals("WF - right lateral", expectedWF, actualWF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("CfF - right lateral", expectedCfF, actualCfF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("AGroundF - right lateral", expectedAGroundF, actualAGroundF, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("AlphaAtm - right lateral", expectedAlphaAtm, actualAlphaAtm, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("AAtm - right lateral", expectedAAtm, actualAAtm, ERROR_EPSILON_LOWEST); - assertDoubleArrayEquals("ADiv - right lateral", expectedADiv, actualADiv, ERROR_EPSILON_LOW); - assertDoubleArrayEquals("AGroundH - right lateral", expectedAGroundH, actualAGroundH, ERROR_EPSILON_LOW); - assertDoubleArrayEquals("AGroundF - right lateral", expectedAGroundF, actualAGroundF, ERROR_EPSILON_MEDIUM); - assertDoubleArrayEquals("DeltaDiffSRH - right lateral", expectedDeltaDiffSRH, actualDeltaDiffSRH, ERROR_EPSILON_HIGH); - assertDoubleArrayEquals("LH - right lateral", expectedLH, actualLH, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("ADiv - right lateral", expectedADiv, actualADiv, ERROR_EPSILON_LOWEST); + assertDoubleArrayEquals("AGroundH - right lateral", expectedAGroundH, actualAGroundH, ERROR_EPSILON_LOWEST); + assertDoubleArrayEquals("AGroundF - right lateral", expectedAGroundF, actualAGroundF, ERROR_EPSILON_LOWEST); + assertDoubleArrayEquals("DeltaDiffSRH - right lateral", expectedDeltaDiffSRH, actualDeltaDiffSRH, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("LH - right lateral", expectedLH, actualLH, ERROR_EPSILON_VERY_LOW); //Path2 : left lateral //Expected values - left lateral @@ -3066,11 +3080,11 @@ public void TC15() throws IOException { assertDoubleArrayEquals("AGroundF - left lateral", expectedAGroundF, actualAGroundF, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("AlphaAtm - left lateral", expectedAlphaAtm, actualAlphaAtm, ERROR_EPSILON_LOWEST); - assertDoubleArrayEquals("AAtm - left lateral", expectedAAtm, actualAAtm, ERROR_EPSILON_HIGH); + assertDoubleArrayEquals("AAtm - left lateral", expectedAAtm, actualAAtm, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("ADiv - left lateral", expectedADiv, actualADiv, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("AGroundH - left lateral", expectedAGroundH, actualAGroundH, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("AGroundF - left lateral", expectedAGroundF, actualAGroundF, ERROR_EPSILON_LOWEST); - assertDoubleArrayEquals("DeltaDiffSRH - left lateral", expectedDeltaDiffSRH, actualDeltaDiffSRH, ERROR_EPSILON_HIGH); + assertDoubleArrayEquals("DeltaDiffSRH - left lateral", expectedDeltaDiffSRH, actualDeltaDiffSRH, ERROR_EPSILON_VERY_LOW); assertDoubleArrayEquals("LH - left lateral", expectedLH, actualLH, ERROR_EPSILON_VERY_LOW); double[] L = addArray(propDataOut.getVerticesSoundLevel().get(0).levels, new double[]{93-26.2,93-16.1,93-8.6,93-3.2,93,93+1.2,93+1.0,93-1.1}); @@ -3711,7 +3725,7 @@ public void TC18() throws IOException { assertDoubleArrayEquals("L - reflexion", expectedL, actualL, ERROR_EPSILON_VERY_LOW); assertDoubleArrayEquals("LA - reflexion", expectedLA, actualLA, ERROR_EPSILON_VERY_LOW); - assertArrayEquals( new double[]{11.69,21.77,28.93,32.71,36.83,36.83,32.12,13.66},L, ERROR_EPSILON_VERY_LOW); + assertArrayEquals( new double[]{11.69,21.77,28.93,32.71,36.83,36.83,32.12,13.66},L, ERROR_EPSILON_LOWEST); } /** @@ -3722,7 +3736,7 @@ public void TC18() throws IOException { @Test public void TC19() throws IOException { //Out and computation settings - AttenuationComputeOutput propDataOut = computeCnossosPath("TC19_Direct", "TC19_Right", + AttenuationComputeOutput propDataOut = computeCnossosPath("TC19_Direct", "TC19_Right", "TC19_Right_Curved", "TC19_Left", "TC19_Left_Curved"); assertEquals(6, propDataOut.getPropagationPaths().size()); @@ -3807,16 +3821,16 @@ public void TC19() throws IOException { new Coordinate(192.38, 10)); /* Table 209 */ - double [][] segmentsMeanPlanes0 = new double[][]{ + double[][] segmentsMeanPlanes0 = new double[][]{ // a b zs zr dp Gp Gp' - {0.03, -1.09, 2.09, 10.89, 145.65, 0.57, 0.78}, - {0.02, 6.42, 4.76, 3.89, 19.38, 0.20, NaN} + {0.03, -1.09, 2.09, 10.89, 145.65, 0.57, 0.78}, + {0.02, 6.42, 4.76, 3.89, 19.38, 0.20, NaN} }; - double [][] segmentsMeanPlanes1 = new double[][]{ + double[][] segmentsMeanPlanes1 = new double[][]{ // a b zs zr dp Gp Gp' {0.06, -2.92, 3.92, 5.66, 196.38, 0.50, 0.62} }; - double [][] segmentsMeanPlanes2 = new double[][]{ + double[][] segmentsMeanPlanes2 = new double[][]{ // a b zs zr dp Gp Gp' {0.06, -2.01, 3.00, 5.00, 192.81, 0.46, 0.55} }; @@ -3824,13 +3838,11 @@ public void TC19() throws IOException { //Assertion assertZProfil(expectedZProfile, cnossosPathDirectH.getCutProfile().computePts2DGround()); assertZProfil(expectedZProfileRight, cnossosPathRightH.getCutProfile().computePts2DGround()); - // Error in ISO - // The iso is making the ray do a diffraction on the horizontal edge of the building then a diffraction on - // the last wall. The hull is ignoring the 12 meters building on the left side. - // assertZProfil(expectedZProfileLeft, propDataOut.getPropagationPaths().get(2).getCutProfile().computePts2DGround()); + assertZProfil(expectedZProfileLeft, cnossosPathLeftH.getCutProfile().computePts2DGround()); assertPlanes(segmentsMeanPlanes0, cnossosPathDirectH.getSegmentList()); assertPlanes(segmentsMeanPlanes1, cnossosPathRightH.getSRSegment()); + assertPlanes(segmentsMeanPlanes2, cnossosPathLeftH.getSRSegment()); // Error in ISO // The iso is making the ray do a diffraction on the horizontal edge of the building then a diffraction on @@ -3987,65 +3999,76 @@ public void TC19() throws IOException { //Path2 : lateral left // ISSUE path CNOSSOS error - //expectedWH = new double[]{0.00, 0.00, 0.00, 0.02, 0.10, 0.51, 2.61, 12.30}; - //expectedCfH = new double[]{198.93, 214.98, 219.72, 113.73, 17.06, 1.95, 0.38, 0.08}; - //expectedAGroundH = new double[]{-1.35, -1.35, -1.35, 1.32, -1.35, -1.35, -1.35, -1.35}; - //expectedWF = new double[]{0.00, 0.00, 0.00, 0.01, 0.06, 0.34, 1.77, 8.65}; - //expectedCfF = new double[]{196.96, 209.53, 225.50, 149.30, 30.69, 3.06, 0.56, 0.12}; - //expectedAGroundF = new double[]{-1.35, -1.35, -1.35, -1.35, -1.35, -1.35, -1.35, -1.35}; - // - //expectedAlphaAtm = new double[]{0.12, 0.41, 1.04, 1.93, 3.66, 9.66, 32.77, 116.88}; - //expectedAAtm = new double[]{0.02, 0.08, 0.20, 0.37, 0.71, 1.86, 6.32, 22.54}; - //expectedADiv = new double[]{56.64, 56.64, 56.64, 56.64, 56.64, 56.64, 56.64, 56.64}; - //expectedABoundaryH = new double[]{-1.35, -1.35, -1.35, 1.32, -1.35, -1.35, -1.35, -1.35}; - //expectedABoundaryF = new double[]{-1.35, -1.35, -1.35, -1.35, -1.35, -1.35, -1.35, -1.35}; - //expectedLH = new double[]{26.60, 24.10, 21.27, 15.57, 14.99, 10.86, 3.41, -15.80}; - //expectedLF = new double[]{26.60, 24.10, 21.27, 18.25, 14.99, 10.86, 3.41, -15.80}; - //actualL = addArray(proPath.aGlobal, SOUND_POWER_LEVELS); - //expectedLA = new double[]{0.40, 8.00, 12.67, 13.91, 14.99, 12.06, 4.41, -9.38}; - - //proPath = propDataOut.getPropagationPaths().get(2); - // - //actualWH = proPath.groundAttenuation.w; - //actualCfH = proPath.groundAttenuation.cf; - //actualAGroundH = proPath.groundAttenuation.aGround; - //actualWF = proPath.groundAttenuation.w; - //actualCfF = proPath.groundAttenuation.cf; - //actualAGroundF = proPath.groundAttenuation.aGround; - // - //actualAlphaAtm = propDataOut.scene.defaultCnossosParameters.getAlpha_atmo(); - //actualAAtm = cnossosPathDirectH.aAtm; - //actualADiv = cnossosPathDirectH.aDiv; - //actualABoundaryH = proPath.double_aBoundary; - //actualABoundaryF = proPath.double_aBoundary; - //actualLH = addArray(proPath.aGlobal, SOUND_POWER_LEVELS); - //actualLF = addArray(proPath.aGlobal, SOUND_POWER_LEVELS); - //actualLA = addArray(actualL, A_WEIGHTING); - //double[] leftLA = actualLA; - // - double[] LA = sumDbArray(directLA,rightLA); - - //Different value with the TC because their z-profile left seems to be false, it follows the building top - // border while it should not - - //assertDoubleArrayEquals("WH - lateral left", expectedWH, actualWH, ERROR_EPSILON_VERY_HIGH); - //assertDoubleArrayEquals("CfH - lateral left", expectedCfH, actualCfH, ERROR_EPSILON_HIGHEST); - //assertDoubleArrayEquals("AGroundH - lateral left", expectedAGroundH, actualAGroundH, ERROR_EPSILON_HIGH); - //assertDoubleArrayEquals("WF - lateral left", expectedWF, actualWF, ERROR_EPSILON_LOWEST); - //assertDoubleArrayEquals("CfF - lateral left", expectedCfF, actualCfF, ERROR_EPSILON_LOW); - //assertDoubleArrayEquals("AGroundF - lateral left", expectedAGroundF, actualAGroundF, ERROR_EPSILON_LOW); - // - //assertDoubleArrayEquals("AlphaAtm - lateral left", expectedAlphaAtm, actualAlphaAtm, ERROR_EPSILON_LOWEST); - //assertDoubleArrayEquals("AAtm - lateral left", expectedAAtm, actualAAtm, ERROR_EPSILON_LOWEST); - //assertDoubleArrayEquals("ADiv - lateral left", expectedADiv, actualADiv, ERROR_EPSILON_LOWEST); - //assertDoubleArrayEquals("ABoundaryH - lateral left", expectedABoundaryH, actualABoundaryH, ERROR_EPSILON_HIGHEST); - //assertDoubleArrayEquals("ABoundaryF - lateral left", expectedABoundaryF, actualABoundaryF, ERROR_EPSILON_HIGHEST); - //assertDoubleArrayEquals("LH - lateral left", expectedLH, actualLH, ERROR_EPSILON_HIGH); - //assertDoubleArrayEquals("LF - lateral left", expectedLF, actualLF, ERROR_EPSILON_LOW); - //assertDoubleArrayEquals("LA - lateral left", expectedLA, actualLA, ERROR_EPSILON_VERY_LOW); - - assertArrayEquals( new double[]{6.72, 14.66, 19.34, 21.58, 21.84, 19.00, 11.42, -9.38},LA, ERROR_EPSILON_HIGH); + expectedWH = new double[]{0.00, 0.00, 0.00, 0.02, 0.10, 0.51, 2.61, 12.30}; + expectedCfH = new double[]{198.93, 214.98, 219.72, 113.73, 17.06, 1.95, 0.38, 0.08}; + expectedAGroundH = new double[]{-1.35, -1.35, -1.35, 1.32, -1.35, -1.35, -1.35, -1.35}; + expectedWF = new double[]{0.00, 0.00, 0.00, 0.01, 0.06, 0.34, 1.77, 8.65}; + expectedCfF = new double[]{196.96, 209.53, 225.50, 149.30, 30.69, 3.06, 0.56, 0.12}; + expectedAGroundF = new double[]{-1.35, -1.35, -1.35, -1.35, -1.35, -1.35, -1.35, -1.35}; + + expectedAlphaAtm = new double[]{0.12, 0.41, 1.04, 1.93, 3.66, 9.66, 32.77, 116.88}; + expectedAAtm = new double[]{0.02, 0.08, 0.20, 0.37, 0.71, 1.86, 6.32, 22.54}; + expectedADiv = new double[]{56.64, 56.64, 56.64, 56.64, 56.64, 56.64, 56.64, 56.64}; + expectedLH = new double[]{26.60, 24.10, 21.27, 15.57, 14.99, 10.86, 3.41, -15.80}; + expectedLF = new double[]{26.60, 24.10, 21.27, 18.25, 14.99, 10.86, 3.41, -15.80}; + expectedLA = new double[]{0.40, 8.00, 12.67, 13.91, 14.99, 12.06, 4.41, -16.90}; + expectedADiffH = new double[]{11.08, 13.52, 16.24, 19.09, 22.02, 24.99, 27.98, 30.98}; + expectedADiffF = new double[]{11.08, 13.52, 16.24, 19.09, 22.02, 24.99, 27.98, 30.98}; + + actualWH = cnossosPathLeftH.groundAttenuation.w; + actualCfH = cnossosPathLeftH.groundAttenuation.cf; + actualAGroundH = cnossosPathLeftH.groundAttenuation.aGround; + actualWF = cnossosPathLeftF.groundAttenuation.w; + actualCfF = cnossosPathLeftF.groundAttenuation.cf; + actualAGroundF = cnossosPathLeftF.groundAttenuation.aGround; + actualADiffH = cnossosPathLeftH.aDif; + actualADiffF = cnossosPathLeftF.aDif; + + actualAlphaAtm = propDataOut.scene.defaultCnossosParameters.getAlpha_atmo(); + actualAAtm = cnossosPathLeftH.aAtm; + actualADiv = cnossosPathLeftH.aDiv; + actualLH = addArray(cnossosPathLeftH.aGlobalRaw, SOUND_POWER_LEVELS); + actualLF = addArray(cnossosPathLeftF.aGlobalRaw, SOUND_POWER_LEVELS); + actualL = addArray(sumDbArray(cnossosPathLeftH.aGlobal, cnossosPathLeftF.aGlobal), SOUND_POWER_LEVELS); + actualLA = addArray(actualL, A_WEIGHTING); + + assertEquals(2, cnossosPathLeftH.getSegmentList().size()); + assertEquals(167.27, cnossosPathLeftH.getSegmentList().get(0).d, ERROR_EPSILON_LOWEST); + assertEquals(25.55, cnossosPathLeftH.getSegmentList().get(1).d, ERROR_EPSILON_LOWEST); + assertEquals(0, cnossosPathLeftH.e, ERROR_EPSILON_LOWEST); + assertEquals(1.33, cnossosPathLeftH.delta, ERROR_EPSILON_LOWEST); + + assertEquals(2, cnossosPathLeftF.getSegmentList().size()); + assertEquals(167.27, cnossosPathLeftF.getSegmentList().get(0).d, ERROR_EPSILON_LOWEST); + assertEquals(25.55, cnossosPathLeftF.getSegmentList().get(1).d, ERROR_EPSILON_LOWEST); + assertEquals(0, cnossosPathLeftF.e, ERROR_EPSILON_LOWEST); + assertEquals(1.33, cnossosPathLeftF.delta, ERROR_EPSILON_LOWEST); + + assertDoubleArrayEquals("WH - lateral left", expectedWH, actualWH, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("CfH - lateral left", expectedCfH, actualCfH, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("AGroundH - lateral left", expectedAGroundH, actualAGroundH, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("AlphaAtm - lateral left", expectedAlphaAtm, actualAlphaAtm, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("AAtm - lateral left", expectedAAtm, actualAAtm, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("ADiv - lateral left", expectedADiv, actualADiv, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("ADiffH - lateral left", expectedADiffH, actualADiffH, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("LH - lateral left", expectedLH, actualLH, ERROR_EPSILON_LOW); + + + assertDoubleArrayEquals("WF - lateral left", expectedWF, actualWF, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("CfF - lateral left", expectedCfF, actualCfF, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("AGroundF - lateral left", expectedAGroundF, actualAGroundF, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("ADiffF - lateral left", expectedADiffF, actualADiffF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("LF - lateral left", expectedLF, actualLF, ERROR_EPSILON_LOW); + assertDoubleArrayEquals("LA - lateral left", expectedLA, actualLA, ERROR_EPSILON_LOW); + double[] LA = addArray(addArray(propDataOut.getVerticesSoundLevel().get(0).levels, SOUND_POWER_LEVELS), A_WEIGHTING); + + assertArrayEquals(new double[]{6.72, 14.66, 19.34, 21.58, 21.84, 19.00, 11.42, -9.38}, LA, ERROR_EPSILON_LOWEST); + + } + + private static double[] getAGlobal(CnossosPath cnossosPathLeftH) { + return cnossosPathLeftH.aGlobal; } /** @@ -4145,7 +4168,7 @@ public void TC20() throws IOException { double[] L = addArray(propDataOut.getVerticesSoundLevel().get(0).levels, new double[]{93-26.2,93-16.1,93-8.6,93-3.2,93,93+1.2,93+1.0,93-1.1}); - assertArrayEquals( new double[]{11.21,21.25,28.63,33.86,36.73,36.79,32.17,14},L, ERROR_EPSILON_VERY_LOW); + assertArrayEquals( new double[]{11.21,21.25,28.63,33.86,36.73,36.79,32.17,14},L, ERROR_EPSILON_LOWEST); } /** @@ -4710,7 +4733,7 @@ public void TC22() throws IOException { assertDoubleArrayEquals("LF - lateral left", expectedLF, actualLF, ERROR_EPSILON_VERY_LOW); double[] L = addArray(propDataOut.getVerticesSoundLevel().get(0).levels, new double[]{93-26.2,93-16.1,93-8.6,93-3.2,93,93+1.2,93+1.0,93-1.1}); - assertArrayEquals( new double[]{-2.96,3.56,6.73,11.17,13.85,13.86,9.48,-7.64},L, ERROR_EPSILON_VERY_LOW); + assertArrayEquals( new double[]{-2.96,3.56,6.73,11.17,13.85,13.86,9.48,-7.64},L, ERROR_EPSILON_LOWEST); } @@ -4781,8 +4804,6 @@ public void TC23() throws IOException { double[] expectedL = new double[]{38.90, 37.17, 36.26, 34.68, 31.42, 27.54, 22.75, 15.02}; double[] expectedLA = new double[]{12.70, 21.07, 27.66, 31.48, 31.42, 28.74, 23.75, 13.92}; - CnossosPath proPath = cnossosPathDirectH; - double[] actualDeltaDiffSRH = cnossosPathDirectH.aBoundary.deltaDiffSR; double[] actualAGroundSOH = cnossosPathDirectH.aBoundary.aGroundSO; double[] actualAGroundORH = cnossosPathDirectH.aBoundary.aGroundOR; @@ -4905,6 +4926,22 @@ public void TC24() throws IOException { }; assertPlanes(segmentsMeanPlanes0,cnossosPathDirectH.getSegmentList()); + /* Table 290 */ + double[][] segmentsMeanPlanesRefH = new double[][]{ + // a b zs zr dp Gp Gp' + {0.19, -1.17, 2.13, 1.94, 22.86, 0.37, 0.07}, + {-0.05, 2.8, 3.38, 4.72, 46.90, 0.18, NaN} + }; + assertPlanes(segmentsMeanPlanesRefH,cnossosPathReflectionH.getSegmentList()); + + /* Table 291 */ + double[][] segmentsMeanPlanesRefF = new double[][]{ + // a b zs zr dp Gp Gp' + {0.19, -1.17, 2.13, 1.94, 22.86, 0.37, 0.07}, + {-0.06, 3.41, 2.96, 4.90, 48.20, 0.20, NaN} + }; + assertPlanes(segmentsMeanPlanesRefF,cnossosPathReflectionF.getSegmentList()); + //Expected values //Path0 : vertical plane double[] expectedDeltaDiffSRH = new double[]{10.18, 13.64, 16.95, 20.02, 23.02, 26.01, 29.00, 32.01}; @@ -5057,26 +5094,31 @@ public void TC24() throws IOException { assertDoubleArrayEquals("DeltaGroundORH reflection plane", expectedDeltaGroundORH, actualDeltaGroundORH, ERROR_EPSILON_VERY_LOW); assertDoubleArrayEquals("actualADiffH reflection plane", expectedADiffH, actualADiffH, ERROR_EPSILON_VERY_LOW); - assertDoubleArrayEquals("DeltaDiffSRF reflection plane", expectedDeltaDiffSRF, actualDeltaDiffSRF, ERROR_EPSILON_VERY_HIGH); - assertDoubleArrayEquals("AGroundSOF reflection plane", expectedAGroundSOF, actualAGroundSOF, ERROR_EPSILON_VERY_HIGH); - assertDoubleArrayEquals("AGroundORF reflection plane", expectedAGroundORF, actualAGroundORF, ERROR_EPSILON_VERY_HIGH); - assertDoubleArrayEquals("DeltaDiffSPrimeRF reflection plane", expectedDeltaDiffSPrimeRF, actualDeltaDiffSPrimeRF, ERROR_EPSILON_VERY_HIGH); - assertDoubleArrayEquals("DeltaDiffSRPrimeF reflection plane", expectedDeltaDiffSRPrimeF, actualDeltaDiffSRPrimeF, ERROR_EPSILON_VERY_HIGH); - assertDoubleArrayEquals("DeltaGroundSOF reflection plane", expectedDeltaGroundSOF, actualDeltaGroundSOF, ERROR_EPSILON_VERY_HIGH); - assertDoubleArrayEquals("DeltaGroundORF reflection plane", expectedDeltaGroundORF, actualDeltaGroundORF, ERROR_EPSILON_VERY_HIGH); - assertDoubleArrayEquals("ADiffF reflection plane", expectedADiffF, actualADiffF, ERROR_EPSILON_VERY_HIGH); + assertEquals(0.29, cnossosPathReflectionF.delta, ERROR_EPSILON_LOWEST); + // curved ray goes above beam in favorable + assertEquals(0, cnossosPathReflectionF.e, ERROR_EPSILON_LOWEST); + assertDoubleArrayEquals("DeltaDiffSRF reflection plane", expectedDeltaDiffSRF, actualDeltaDiffSRF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("AGroundSOF reflection plane", expectedAGroundSOF, actualAGroundSOF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("AGroundORF reflection plane", expectedAGroundORF, actualAGroundORF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("DeltaDiffSPrimeRF reflection plane", expectedDeltaDiffSPrimeRF, actualDeltaDiffSPrimeRF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("DeltaDiffSRPrimeF reflection plane", expectedDeltaDiffSRPrimeF, actualDeltaDiffSRPrimeF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("DeltaGroundSOF reflection plane", expectedDeltaGroundSOF, actualDeltaGroundSOF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("DeltaGroundORF reflection plane", expectedDeltaGroundORF, actualDeltaGroundORF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("ADiffF reflection plane", expectedADiffF, actualADiffF, ERROR_EPSILON_LOW); assertDoubleArrayEquals("AlphaAtm reflection plane", expectedAlphaAtm, actualAlphaAtm, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("AAtm reflection plane", expectedAAtm, actualAAtm, ERROR_EPSILON_VERY_LOW); assertDoubleArrayEquals("ADiv reflection plane", expectedADiv, actualADiv, ERROR_EPSILON_VERY_LOW); assertDoubleArrayEquals("ABoundaryH reflection plane", expectedABoundaryH, actualABoundaryH, ERROR_EPSILON_VERY_LOW); - assertDoubleArrayEquals("ABoundaryF reflection plane", expectedABoundaryF, actualABoundaryF, ERROR_EPSILON_VERY_HIGH); + assertDoubleArrayEquals("ABoundaryF reflection plane", expectedABoundaryF, actualABoundaryF, ERROR_EPSILON_VERY_LOW); assertDoubleArrayEquals("LH - Reflection plane", expectedLH, actualLH, ERROR_EPSILON_VERY_LOW); - assertDoubleArrayEquals("LF reflection plane", expectedLF, actualLF, ERROR_EPSILON_VERY_HIGH); - assertDoubleArrayEquals("L reflection plane", expectedL, actualL, ERROR_EPSILON_HIGH); - assertDoubleArrayEquals("LA reflection plane", expectedLA, actualLA, ERROR_EPSILON_HIGH); + assertDoubleArrayEquals("LF reflection plane", expectedLF, actualLF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("L reflection plane", expectedL, actualL, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("LA reflection plane", expectedLA, actualLA, ERROR_EPSILON_VERY_LOW); + double[] L = addArray(propDataOut.getVerticesSoundLevel().get(0).levels, new double[]{93 - 26.2, 93 - 16.1, 93 - 8.6, 93 - 3.2, 93, 93 + 1.2, 93 + 1.0, 93 - 1.1}); + assertArrayEquals(new double[]{14.31, 21.69, 27.76, 31.52, 31.49, 29.18, 25.39, 16.58}, L, ERROR_EPSILON_LOWEST); } /** @@ -5420,14 +5462,17 @@ public void TC25() throws IOException { /** * TC26 – Road source with influence of retrodiffraction - * Issue we compute and add favourable contribution, on reflexion path but not in test case reference - * */ + * No favourable reflection path: in favorable conditions the curved ray passes over the wall. + * EU Directive 2002/49 (consolidated 29.07.2021), Annex II, §2.5.20: + * "le point de réflexion est construit à l'aide de lignes droites dans des conditions de propagation + * homogènes et de lignes courbes dans des conditions de propagation favorables" + */ @Test public void TC26() throws IOException { AttenuationComputeOutput propDataOut = computeCnossosPath("TC26_Direct", "TC26_Reflection"); - assertEquals(4, propDataOut.getPropagationPaths().size()); + assertEquals(3, propDataOut.getPropagationPaths().size()); final CnossosPath cnossosPathDirectH = propDataOut.getPropagationPaths().get(0); assertFalse(cnossosPathDirectH.isFavourable()); @@ -5440,10 +5485,6 @@ public void TC26() throws IOException { assertFalse(cnossosPathReflectionH.isFavourable()); assertEquals(CutProfile.PROFILE_TYPE.REFLECTION, cnossosPathReflectionH.getCutProfile().getProfileType()); - CnossosPath cnossosPathReflectionF = propDataOut.getPropagationPaths().get(3); - assertTrue(cnossosPathReflectionF.isFavourable()); - assertEquals(CutProfile.PROFILE_TYPE.REFLECTION, cnossosPathReflectionF.getCutProfile().getProfileType()); - //Expected values //Path0 : vertical plane double[] expectedWH = new double[]{0.00, 0.00, 0.00, 0.00, 0.00, 0.02, 0.12, 0.65}; @@ -5516,7 +5557,8 @@ public void TC26() throws IOException { actualADiv = cnossosPathReflectionH.aDiv; actualABoundaryH = cnossosPathReflectionH.double_aBoundary; actualLH = addArray(cnossosPathReflectionH.aGlobalRaw, SOUND_POWER_LEVELS); - actualL = addArray(sumDbArray(cnossosPathReflectionH.aGlobal, cnossosPathReflectionF.aGlobal), SOUND_POWER_LEVELS); + // No favorable reflection path, use aGlobal which accounts for p=0.5 weighting + actualL = addArray(cnossosPathReflectionH.aGlobal, SOUND_POWER_LEVELS); actualLA = addArray(actualL, A_WEIGHTING); assertDoubleArrayEquals("WH - reflexion", expectedWH, actualWH, ERROR_EPSILON_LOWEST); @@ -5527,19 +5569,18 @@ public void TC26() throws IOException { assertDoubleArrayEquals("ADiv - reflexion", expectedADiv, actualADiv, ERROR_EPSILON_VERY_LOW); assertDoubleArrayEquals("ABoundaryH - reflexion", expectedABoundaryH, actualABoundaryH, ERROR_EPSILON_VERY_LOW); assertDoubleArrayEquals("LH - reflexion", expectedLH, actualLH, ERROR_EPSILON_VERY_LOW); - assertDoubleArrayEquals("L - reflexion", expectedL, actualL, ERROR_EPSILON_HIGH); - assertDoubleArrayEquals("LA - reflexion", expectedLA, actualLA, ERROR_EPSILON_HIGH); + assertDoubleArrayEquals("L - reflexion", expectedL, actualL, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("LA - reflexion", expectedLA, actualLA, ERROR_EPSILON_VERY_LOW); double[] L = addArray(propDataOut.getVerticesSoundLevel().get(0).levels, new double[]{93-26.2,93-16.1,93-8.6,93-3.2,93,93+1.2,93+1.0,93-1.1}); - assertArrayEquals( new double[]{17.50,27.52,34.89,40.14,43.10,43.59,40.55,29.15},L, ERROR_EPSILON_LOW); + assertArrayEquals( new double[]{17.50,27.52,34.89,40.14,43.10,43.59,40.55,29.15},L, ERROR_EPSILON_VERY_LOW); } /** * TC27 – Road source with influence of retrodiffraction - * Issue with wrong agroundF for reflection path * */ @Test public void TC27() throws IOException { @@ -5595,7 +5636,6 @@ public void TC27() throws IOException { SegmentPath sr = cnossosPathReflectionF.getSRSegment(); assertMirrorPoint(expectedSPrimeSR,expectedRPrimeSR,sr.sPrime, sr.rPrime); - assertEquals(2, cnossosPathReflectionF.getSegmentList().size()); SegmentPath so = cnossosPathReflectionF.getSegmentList().get(0); SegmentPath or = cnossosPathReflectionF.getSegmentList().get(cnossosPathReflectionH.getSegmentList().size() - 1); @@ -5647,8 +5687,8 @@ public void TC27() throws IOException { expectedABoundaryF = new double[]{-0.59, -0.59, -0.59, -0.59, 4.43, 2.99, 0.42, -0.59}; double[] expectedDLabs = new double[] {-0.46, -0.97, -1.55, -2.22, -3.01, -3.98, -5.23, -3.01}; expectedLH = new double[]{35.56, 36.12, 38.09, 37.16, 32.44, 29.29, 25.96, 19.00}; - expectedLF = new double[]{37.83, 37.89, 38.82, 40.11, 34.12, 34.00, 32.98, 27.54}; - expectedLA = new double[]{10.64, 21.00, 29.97, 35.68, 33.36, 33.45, 31.76, 24.17}; + expectedLF = new double[]{37.83, 37.89, 38.82, 40.11, 34.12, 34.00, 32.98, 27.74}; + expectedLA = new double[]{10.64, 21.00, 29.87, 35.68, 33.36, 33.45, 31.76, 24.17}; actualAAtm = cnossosPathReflectionH.aAtm; actualADiv = cnossosPathReflectionH.aDiv; @@ -5660,21 +5700,20 @@ public void TC27() throws IOException { actualLA = addArray(actualL, A_WEIGHTING); double[] LA = sumDbArray(directLA, actualLA); double[] expectedFullLA = new double[]{16.84, 26.97, 34.79, 40.23, 38.57, 38.58, 39.36, 29.60}; - double[] diffLa = diffArray(expectedFullLA, LA); assertDoubleArrayEquals("AAtm - reflection", expectedAAtm, actualAAtm, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("ADiv - reflection", expectedADiv, actualADiv, ERROR_EPSILON_LOWEST); assertDoubleArrayEquals("ABoundaryH - reflection", expectedABoundaryH, actualABoundaryH, ERROR_EPSILON_LOWEST); - assertDoubleArrayEquals("ABoundaryF - reflection", expectedABoundaryF, actualABoundaryF, ERROR_EPSILON_HIGH); + assertDoubleArrayEquals("ABoundaryF - reflection", expectedABoundaryF, actualABoundaryF, ERROR_EPSILON_VERY_LOW); assertDoubleArrayEquals("dLabs - reflection", expectedDLabs, cnossosPathReflectionH.aRef, ERROR_EPSILON_LOWEST); - assertDoubleArrayEquals("LH - reflection", expectedLH, actualLH, ERROR_EPSILON_LOW); - assertDoubleArrayEquals("LF - reflection", expectedLF, actualLF, ERROR_EPSILON_HIGH); - assertDoubleArrayEquals("LA - reflection", expectedLA, actualLA, ERROR_EPSILON_HIGH); + assertDoubleArrayEquals("LH - reflection", expectedLH, actualLH, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("LF - reflection", expectedLF, actualLF, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("LA - reflection", expectedLA, actualLA, ERROR_EPSILON_VERY_LOW); - double[] L = addArray(propDataOut.getVerticesSoundLevel().get(0).levels, new double[]{93 - 26.2, 93 - 16.1, 93 - 8.6, 93 - 3.2, 93, 93 + 1.2, 93 + 1.0, 93 - 1.1}); + double[] L = addArray(addArray(propDataOut.getVerticesSoundLevel().get(0).levels, SOUND_POWER_LEVELS), A_WEIGHTING); - assertArrayEquals(expectedFullLA, L, ERROR_EPSILON_LOW); + assertArrayEquals(expectedFullLA, L, ERROR_EPSILON_VERY_LOW); } /** @@ -5746,15 +5785,17 @@ public void TC28() throws IOException { List expectedZProfileLeft = Arrays.asList( new Coordinate(0.0, 0.0), - new Coordinate(168.36, 0.0), - //new Coordinate(256.17, 0.0), // building ignored in CNOSSOS - //new Coordinate(276.59, 0.0), // building ignored in CNOSSOS - new Coordinate(356.24, 0.0), - new Coordinate(444.81, 0.0), + new Coordinate(168.34, 0.0), + new Coordinate(256.16, 0.0), + new Coordinate(256.16, 14.0), + new Coordinate(276.58, 14.0), + new Coordinate(276.58, 0.0), + new Coordinate(356.23, 0.0), + new Coordinate(444.79, 0.0), new Coordinate(525.11, 0.0), - new Coordinate(988.63, 0.0), - new Coordinate(1002.95, 0.0), - new Coordinate(1022.31, 0.0)); + new Coordinate(988.62, 0.0), + new Coordinate(1002.96, 0.0), + new Coordinate(1022.27, 0.0)); /* Table 348 */ double [][] segmentsMeanPlanesDirect = new double[][]{ @@ -5893,12 +5934,12 @@ public void TC28() throws IOException { assertEquals(CutProfile.PROFILE_TYPE.LEFT, cnossosPath.getCutProfile().getProfileType()); assertZProfil(expectedZProfileLeft, Arrays.asList(cnossosPath.getSRSegment().getPoints2DGround())); - // TODO Weird plane, A B not at 0 (there is no DEM) - //assertPlanes(segmentsMeanPlanesLeft, cnossosPath.getSRSegment()); + + assertPlanes(segmentsMeanPlanesLeft, cnossosPath.getSRSegment()); assertDoubleArrayEquals("w (H) - lateral left", expectedLeftH_W, cnossosPath.groundAttenuation.w, ERROR_EPSILON_LOW); - assertDoubleArrayEquals("Cf (H) - lateral left", expectedLeftH_CF, cnossosPath.groundAttenuation.cf, 50); - assertDoubleArrayEquals("AGround (H) - lateral left", expectedLeftH_Aground, cnossosPath.groundAttenuation.aGround, ERROR_EPSILON_HIGH); + assertDoubleArrayEquals("Cf (H) - lateral left", expectedLeftH_CF, cnossosPath.groundAttenuation.cf, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("AGround (H) - lateral left", expectedLeftH_Aground, cnossosPath.groundAttenuation.aGround, ERROR_EPSILON_VERY_LOW); double[] expectedLeftADiv = {71.01, 71.01, 71.01, 71.01, 71.01, 71.01, 71.01, 71.01}; double[] expectedLeftAGroundH = {-1.53, -1.53, -1.25, 15.70, 21.95, 13.29, 5.98, -0.45}; @@ -5907,8 +5948,8 @@ public void TC28() throws IOException { assertDoubleArrayEquals("ADiv (H) - lateral left", expectedLeftADiv, cnossosPath.aDiv, ERROR_EPSILON_VERY_LOW); assertDoubleArrayEquals("ADif (H) - lateral left", expectedLeftADifH, cnossosPath.aDif, ERROR_EPSILON_LOW); - assertDoubleArrayEquals("AGround (H) - lateral left", expectedLeftAGroundH, cnossosPath.groundAttenuation.aGround, ERROR_EPSILON_HIGH); - assertDoubleArrayEquals("L (H) - lateral left", expectedLeftLH, sumArray(cnossosPath.aGlobalRaw, LW_SOURCE), ERROR_EPSILON_HIGH); + assertDoubleArrayEquals("AGround (H) - lateral left", expectedLeftAGroundH, cnossosPath.groundAttenuation.aGround, ERROR_EPSILON_VERY_LOW); + assertDoubleArrayEquals("L (H) - lateral left", expectedLeftLH, sumArray(cnossosPath.aGlobalRaw, LW_SOURCE), ERROR_EPSILON_VERY_LOW); // Left favourable path cnossosPath = propDataOut.getPropagationPaths().get(5); @@ -6354,6 +6395,428 @@ public void TestFavourableConditionAttenuationRose() { } } + + /** + * Regression test for multi-diffraction favorable path: missing e term in deltaPrime calculation + * with positive orientation. + * Two buildings create multi-diffraction. In favorable conditions, the deltaPrime + * formula (Eq. 2.5.21) must include the e term (distance between diffraction edges). + * Without the fix, deltaPrime would be significantly lower (missing toCurve(e, dPrime) contribution). + */ + @Test + public void regressionMultiDifFavourable_MissingETerm() throws IOException { + GeometryFactory f = new GeometryFactory(); + ProfileBuilder profileBuilder = new ProfileBuilder(); + + // Two buildings creating multi-diffraction at 200m distance + // Building 1: x=[75,80], height 10m — Building 2: x=[120,125], height 10m + // e ≈ distance between building tops ≈ 40m (significant contribution to deltaPrime) + profileBuilder + .addBuilding(new Coordinate[]{ + new Coordinate(75, -50, 0), new Coordinate(80, -50, 0), + new Coordinate(80, 50, 0), new Coordinate(75, 50, 0) + }, 10.0) + .addBuilding(new Coordinate[]{ + new Coordinate(120, -50, 0), new Coordinate(125, -50, 0), + new Coordinate(125, 50, 0), new Coordinate(120, 50, 0) + }, 10.0) + .finishFeeding(); + + SceneWithAttenuation scene = new SceneWithAttenuation(profileBuilder); + scene.addSource(f.createPoint(new Coordinate(0, 0, 1))); + scene.addReceiver(new Coordinate(200, 0, 4)); + scene.defaultGroundAttenuation = 0.5; + scene.reflexionOrder = 0; + scene.maxSrcDist = 300; + scene.setComputeHorizontalDiffraction(true); + scene.setComputeVerticalDiffraction(true); + + AttenuationParameters attData = new AttenuationParameters(); + attData.setHumidity(HUMIDITY); + attData.setTemperature(TEMPERATURE); + scene.defaultCnossosParameters = attData; + + AttenuationComputeOutput propDataOut = new AttenuationComputeOutput(true, true, scene); + PathFinder pathFinder = new PathFinder(scene); + pathFinder.setThreadCount(1); + pathFinder.run(propDataOut); + + // Find the favorable direct path with multi-diffraction (3+ segments = 2+ diffraction edges) + CnossosPath favDirectPath = null; + CnossosPath homDirectPath = null; + for (CnossosPath path : propDataOut.getPropagationPaths()) { + if (path.getCutProfile().getProfileType() == CutProfile.PROFILE_TYPE.DIRECT + && path.getSegmentList().size() >= 3) { + if (path.isFavourable()) { + favDirectPath = path; + } else { + homDirectPath = path; + } + } + } + assertNotNull(favDirectPath, "Should find a favorable direct path with multi-diffraction"); + assertNotNull(homDirectPath, "Should find a homogeneous direct path with multi-diffraction"); + + // === ASSERTIONS === + + // e > 0 confirms multi-diffraction (distance between diffraction edges) + assertTrue(favDirectPath.e > 0, "Multi-diffraction path must have e > 0"); + + // delta and deltaPrime should be positive for standard geometry (barriers above S-R line) + assertTrue(favDirectPath.delta > 0, "Favorable delta should be positive for barriers above S-R line"); + assertTrue(favDirectPath.deltaPrime > 0, "Favorable deltaPrime should be positive"); + + // KEY REGRESSION CHECK: + // With correct fix: deltaPrime_F includes the e term via toCurve(e, dPrime) + // Without fix: deltaPrime_F is missing ~toCurve(e, dPrime) contribution + // For e ≈ 40m and dPrime ≈ 200m, the missing term is approximately 40m + // The homogeneous deltaPrime_H = seg1.dPrime + e + seg2.dPrime - srPath.dPrime + // The favorable deltaPrime_F should be close to deltaPrime_H (both include e) + // Without fix: deltaPrime_F ≈ deltaPrime_H - e (dramatically wrong) + double deltaPrimeDiff = Math.abs(favDirectPath.deltaPrime - homDirectPath.deltaPrime); + assertTrue(deltaPrimeDiff < homDirectPath.e, + String.format("Favorable deltaPrime (%.2f) should be close to homogeneous deltaPrime (%.2f), " + + "difference (%.2f) should be less than e (%.2f). " + + "A large difference indicates the e term is missing.", + favDirectPath.deltaPrime, homDirectPath.deltaPrime, deltaPrimeDiff, homDirectPath.e)); + + // aDif values should be physically bounded (diffraction cannot add more than 25dB) + assertTrue(Arrays.stream(favDirectPath.aDif).allMatch(d -> d >= -25), + "Diffraction attenuation should be >= -25 dB"); + + // Global attenuation must be negative (sound always loses energy) + assertTrue(Arrays.stream(favDirectPath.aGlobal).allMatch(d -> d < 0), + "Global attenuation should be negative"); + assertTrue(Arrays.stream(favDirectPath.aGlobalRaw).allMatch(d -> d < 0), + "Raw global attenuation should be negative"); + + // Precise numeric assertions + assertEquals(50.0, favDirectPath.e, ERROR_EPSILON_LOWEST); + assertEquals(0.6407, favDirectPath.delta, ERROR_EPSILON_VERY_LOW); + assertEquals(1.9613, favDirectPath.deltaPrime, ERROR_EPSILON_VERY_LOW); + assertEquals(0.8651, favDirectPath.deltaSPrimeR, ERROR_EPSILON_VERY_LOW); + assertEquals(1.6569, favDirectPath.deltaSRPrime, ERROR_EPSILON_VERY_LOW); + } + + + /** + * JSON-based standalone regression test for multi-diffraction favorable (missing e term). + * Loads the CutProfile previously generated by regressionMultiDifFavourable_MissingETerm. + */ + @Test + public void regressionMultiDifFavourable_Standalone() throws IOException { + AttenuationComputeOutput propDataOut = computeCnossosPath( + AttenuationComputeOutputCnossosTest.class.getResource("RegressionTestMultiDifFav.json")); + assertNotNull(propDataOut); + assertEquals(2, propDataOut.getPropagationPaths().size()); + + CnossosPath homPath = propDataOut.getPropagationPaths().get(0); + assertFalse(homPath.isFavourable()); + CnossosPath favPath = propDataOut.getPropagationPaths().get(1); + assertTrue(favPath.isFavourable()); + assertEquals(CutProfile.PROFILE_TYPE.DIRECT, favPath.getCutProfile().getProfileType()); + + // Multi-diffraction: e > 0 + assertTrue(favPath.e > 0, "Multi-diffraction path must have e > 0"); + // deltaPrime should be positive (barriers above S-R line) + assertTrue(favPath.deltaPrime > 0, "Favorable deltaPrime should be positive"); + // Favorable deltaPrime should be close to homogeneous (both include e contribution) + double deltaPrimeDiff = Math.abs(favPath.deltaPrime - homPath.deltaPrime); + assertTrue(deltaPrimeDiff < homPath.e, + "deltaPrime difference between F and H should be less than e"); + // aDif physically bounded + assertTrue(Arrays.stream(favPath.aDif).allMatch(d -> d >= -25)); + // Global attenuation negative + assertTrue(Arrays.stream(favPath.aGlobal).allMatch(d -> d < 0)); + assertTrue(Arrays.stream(favPath.aGlobalRaw).allMatch(d -> d < 0)); + + // Precise numeric assertions (same geometry as scene-based test) + assertEquals(50.0, favPath.e, ERROR_EPSILON_LOWEST); + assertEquals(0.6407, favPath.delta, ERROR_EPSILON_VERY_LOW); + assertEquals(1.9613, favPath.deltaPrime, ERROR_EPSILON_VERY_LOW); + assertEquals(0.8651, favPath.deltaSPrimeR, ERROR_EPSILON_VERY_LOW); + assertEquals(1.6569, favPath.deltaSRPrime, ERROR_EPSILON_VERY_LOW); + } + + + /** + * Regression test for single-diffraction favorable path deltaPrime calculation. + * A thin wall creates a single diffraction point. The favorable path delta and deltaPrime + * are computed using toCurve formulas. This test verifies that: + * - delta and deltaPrime are physically consistent between H and F paths + * - the favorable computations produce bounded, reasonable values + * - aDif and aGlobal values are physically valid + * The fix corrected the negative deltaPrime orientation branch (using rcvPrime + * instead of srcPrime and dPrime instead of d), which is only triggered in rare terrain + * configurations. This test validates the overall single-diffraction favorable code path. + */ + @Test + public void regressionSingleDifFavourable_DeltaPrime() throws IOException { + GeometryFactory f = new GeometryFactory(); + ProfileBuilder profileBuilder = new ProfileBuilder(); + + // Thin wall at x=20, height=6m creates single diffraction. + // Source at (0,0,1), Receiver at (50,0,4) → wall above S-R line. + List alphas = Arrays.asList(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + profileBuilder + .addWall(new Coordinate[]{ + new Coordinate(20, -100, 0), + new Coordinate(20, 100, 0) + }, 6.0, alphas, 1) + .finishFeeding(); + + SceneWithAttenuation scene = new SceneWithAttenuation(profileBuilder); + scene.addSource(f.createPoint(new Coordinate(0, 0, 1))); + scene.addReceiver(new Coordinate(50, 0, 4)); + scene.defaultGroundAttenuation = 0.5; + scene.reflexionOrder = 0; + scene.maxSrcDist = 100; + scene.setComputeHorizontalDiffraction(true); + scene.setComputeVerticalDiffraction(true); + + AttenuationParameters attData = new AttenuationParameters(); + attData.setHumidity(HUMIDITY); + attData.setTemperature(TEMPERATURE); + scene.defaultCnossosParameters = attData; + + AttenuationComputeOutput propDataOut = new AttenuationComputeOutput(true, true, scene); + PathFinder pathFinder = new PathFinder(scene); + pathFinder.setThreadCount(1); + pathFinder.run(propDataOut); + + // Find favorable and homogeneous direct paths with diffraction + CnossosPath favDirectPath = null; + CnossosPath homDirectPath = null; + for (CnossosPath path : propDataOut.getPropagationPaths()) { + if (path.getCutProfile().getProfileType() == CutProfile.PROFILE_TYPE.DIRECT + && path.getSegmentList().size() >= 2) { + if (path.isFavourable()) { + favDirectPath = path; + } else { + homDirectPath = path; + } + } + } + assertNotNull(favDirectPath, "Should find a favorable direct path with diffraction"); + assertNotNull(homDirectPath, "Should find a homogeneous direct path with diffraction"); + + // Should have diffraction + boolean hasDiffraction = favDirectPath.getPointList().stream() + .anyMatch(p -> p.type.name().startsWith("DIF")); + assertTrue(hasDiffraction, "Diffraction should be triggered by wall above S-R line"); + + // delta should be positive (wall above S-R line) + assertTrue(favDirectPath.delta > 0, + "Favorable delta should be positive for wall above S-R line"); + + // deltaPrime should be positive and bounded + assertTrue(favDirectPath.deltaPrime > 0, + "Favorable deltaPrime should be positive"); + assertTrue(favDirectPath.deltaPrime < 50, + "DeltaPrime should be bounded for a single wall"); + + // Favorable delta/deltaPrime should be close to homogeneous (curvature effect small at 50m) + double deltaDiff = Math.abs(favDirectPath.delta - homDirectPath.delta); + assertTrue(deltaDiff < Math.max(1.0, homDirectPath.delta * 0.5), + String.format("Favorable delta (%.4f) should be close to homogeneous (%.4f)", + favDirectPath.delta, homDirectPath.delta)); + + double deltaPrimeDiff = Math.abs(favDirectPath.deltaPrime - homDirectPath.deltaPrime); + assertTrue(deltaPrimeDiff < Math.max(1.0, homDirectPath.deltaPrime * 0.5), + String.format("Favorable deltaPrime (%.4f) should be close to homogeneous (%.4f)", + favDirectPath.deltaPrime, homDirectPath.deltaPrime)); + + // aDif should be physically bounded + assertTrue(Arrays.stream(favDirectPath.aDif).allMatch(d -> d >= -25), + "Diffraction attenuation should be >= -25 dB"); + + // Global attenuation must be negative + assertTrue(Arrays.stream(favDirectPath.aGlobal).allMatch(d -> d < 0), + "Global attenuation should be negative"); + assertTrue(Arrays.stream(favDirectPath.aGlobalRaw).allMatch(d -> d < 0), + "Raw global attenuation should be negative"); + + // Precise numeric assertions + assertEquals(0.0, favDirectPath.e, ERROR_EPSILON_LOWEST); + assertEquals(0.5885, favDirectPath.delta, ERROR_EPSILON_VERY_LOW); + assertEquals(2.7190, favDirectPath.deltaPrime, ERROR_EPSILON_VERY_LOW); + assertEquals(1.0031, favDirectPath.deltaSPrimeR, ERROR_EPSILON_VERY_LOW); + assertEquals(1.9853, favDirectPath.deltaSRPrime, ERROR_EPSILON_VERY_LOW); + } + + + /** + * JSON-based standalone regression test for single-diffraction favorable path. + * Loads the CutProfile previously generated by regressionSingleDifFavourable_DeltaPrime. + */ + @Test + public void regressionSingleDifFavourable_Standalone() throws IOException { + AttenuationComputeOutput propDataOut = computeCnossosPath( + AttenuationComputeOutputCnossosTest.class.getResource("RegressionTestSingleDif.json")); + assertNotNull(propDataOut); + assertEquals(2, propDataOut.getPropagationPaths().size()); + + CnossosPath homPath = propDataOut.getPropagationPaths().get(0); + assertFalse(homPath.isFavourable()); + CnossosPath favPath = propDataOut.getPropagationPaths().get(1); + assertTrue(favPath.isFavourable()); + assertEquals(CutProfile.PROFILE_TYPE.DIRECT, favPath.getCutProfile().getProfileType()); + + // Single diffraction: 2 segments + assertEquals(2, favPath.getSegmentList().size()); + // delta positive (wall above SR line) + assertTrue(favPath.delta > 0); + // deltaPrime positive and bounded + assertTrue(favPath.deltaPrime > 0); + assertTrue(favPath.deltaPrime < 50); + // Favorable close to homogeneous + assertTrue(Math.abs(favPath.deltaPrime - homPath.deltaPrime) < 1.0); + // aDif physically bounded + assertTrue(Arrays.stream(favPath.aDif).allMatch(d -> d >= -25)); + // Global attenuation negative + assertTrue(Arrays.stream(favPath.aGlobal).allMatch(d -> d < 0)); + assertTrue(Arrays.stream(favPath.aGlobalRaw).allMatch(d -> d < 0)); + + // Precise numeric assertions (same geometry as scene-based test) + assertEquals(0.0, favPath.e, ERROR_EPSILON_LOWEST); + assertEquals(0.5885, favPath.delta, ERROR_EPSILON_VERY_LOW); + assertEquals(2.7190, favPath.deltaPrime, ERROR_EPSILON_VERY_LOW); + assertEquals(1.0031, favPath.deltaSPrimeR, ERROR_EPSILON_VERY_LOW); + assertEquals(1.9853, favPath.deltaSRPrime, ERROR_EPSILON_VERY_LOW); + } + + + /** + * Test regression issue, reflection in favourable over DEM + */ + @Test + public void TCFavourableReflection() throws IOException { + AttenuationComputeOutput propDataOut = computeCnossosPath(AttenuationComputeOutputCnossosTest.class.getResource("RegressionTestReflection1.json")); + assertNotNull(propDataOut); + assertEquals(2, propDataOut.getPropagationPaths().size()); + CnossosPath cnossosPath = propDataOut.getPropagationPaths().get(0); + assertFalse(cnossosPath.isFavourable()); + assertEquals(CutProfile.PROFILE_TYPE.REFLECTION, cnossosPath.getCutProfile().getProfileType()); + // check if cnossosPath.aDif array is positive + // Why 18dB gain, because up to 9dB gain for the reflection in favourable condition (eq. 2.5.20) on the ground for SO and OR + assertTrue(Arrays.stream(cnossosPath.aDif).allMatch(d -> d >= -18)); + // Check attenuation is cnossosPath.aGlobal < 0 dB + assertTrue(Arrays.stream(cnossosPath.aGlobal).allMatch(d -> d < 0)); + assertTrue(Arrays.stream(cnossosPath.aGlobalRaw).allMatch(d -> d < 0)); + cnossosPath = propDataOut.getPropagationPaths().get(1); + assertTrue(cnossosPath.isFavourable()); + assertEquals(CutProfile.PROFILE_TYPE.REFLECTION, cnossosPath.getCutProfile().getProfileType()); + // check if cnossosPath.aDif array is positive + // Why 18dB gain, because up to 9dB gain for the reflection in favourable condition (eq. 2.5.20) on the ground for SO and OR + assertTrue(Arrays.stream(cnossosPath.aDif).allMatch(d -> d >= -18)); + // Check attenuation is cnossosPath.aGlobal < 0 dB + assertTrue(Arrays.stream(cnossosPath.aGlobal).allMatch(d -> d < 0)); + assertTrue(Arrays.stream(cnossosPath.aGlobalRaw).allMatch(d -> d < 0)); + } + + + /** + * Test regression issue, reflection in favourable over DEM + */ + @Test + public void TCFavourableReflection2() throws IOException { + AttenuationComputeOutput propDataOut = computeCnossosPath(AttenuationComputeOutputCnossosTest.class.getResource("RegressionTestReflection2.json")); + assertNotNull(propDataOut); + assertEquals(2, propDataOut.getPropagationPaths().size()); + CnossosPath cnossosPath = propDataOut.getPropagationPaths().get(0); + assertFalse(cnossosPath.isFavourable()); + assertEquals(CutProfile.PROFILE_TYPE.REFLECTION, cnossosPath.getCutProfile().getProfileType()); + // check if cnossosPath.aDif array is positive + // Why 18dB gain, because up to 9dB gain for the reflection in favourable condition (eq. 2.5.20) on the ground for SO and OR + assertTrue(Arrays.stream(cnossosPath.aDif).allMatch(d -> d >= -18)); + // Check attenuation is cnossosPath.aGlobal < 0 dB + assertTrue(Arrays.stream(cnossosPath.aGlobal).allMatch(d -> d < 0)); + assertTrue(Arrays.stream(cnossosPath.aGlobalRaw).allMatch(d -> d < 0)); + cnossosPath = propDataOut.getPropagationPaths().get(1); + assertTrue(cnossosPath.isFavourable()); + assertEquals(CutProfile.PROFILE_TYPE.REFLECTION, cnossosPath.getCutProfile().getProfileType()); + // check if cnossosPath.aDif array is positive + // Why 18dB gain, because up to 9dB gain for the reflection in favourable condition (eq. 2.5.20) on the ground for SO and OR + assertTrue(Arrays.stream(cnossosPath.aDif).allMatch(d -> d >= -18)); + // Check attenuation is cnossosPath.aGlobal < 0 dB + assertTrue(Arrays.stream(cnossosPath.aGlobal).allMatch(d -> d < 0)); + assertTrue(Arrays.stream(cnossosPath.aGlobalRaw).allMatch(d -> d < 0)); + } + + @Test + public void reflectionOnBuildingWallNearReceiver() throws IOException { + AttenuationComputeOutput propDataOut = computeReflectionOnBuildingWallNearReceiver(false); + + List reflectionPaths = propDataOut.getPropagationPaths().stream() + .filter(path -> path.getCutProfile().getProfileType() == CutProfile.PROFILE_TYPE.REFLECTION) + .collect(Collectors.toList()); + assertFalse(reflectionPaths.isEmpty(), + "A reflection path should exist on the building wall when source and receiver are on the same side."); + assertTrue(reflectionPaths.stream().anyMatch(path -> + path.getPointList().stream().anyMatch(point -> point.type == PointPath.POINT_TYPE.REFL)), + "At least one computed reflection path should contain a reflection point on the wall."); + } + + @Test + public void reflectionOnBuildingWallNearReceiverFilteredWhenOptionEnabled() throws IOException { + AttenuationComputeOutput propDataOut = computeReflectionOnBuildingWallNearReceiver(true); + + List reflectionPaths = propDataOut.getPropagationPaths().stream() + .filter(path -> path.getCutProfile().getProfileType() == CutProfile.PROFILE_TYPE.REFLECTION) + .collect(Collectors.toList()); + assertTrue(reflectionPaths.isEmpty(), + "Reflection paths ending with a wall reflection within 0.5 m of the receiver should be filtered when the option is enabled."); + assertFalse(propDataOut.getPropagationPaths().isEmpty(), + "Enabling the reflection-profile filter should not remove the valid direct paths."); + assertTrue(propDataOut.getPropagationPaths().stream().allMatch(path -> + path.getCutProfile().getProfileType() == CutProfile.PROFILE_TYPE.DIRECT), + "Only direct paths should remain after filtering the near-receiver reflection profile."); + } + + private AttenuationComputeOutput computeReflectionOnBuildingWallNearReceiver(boolean enableReflectionProfileFilter) + throws IOException { + GeometryFactory geometryFactory = new GeometryFactory(); + ProfileBuilder profileBuilder = new ProfileBuilder(); + ObjectMapper objectMapper = new ObjectMapper(); + + profileBuilder + .addBuilding(new Coordinate[]{ + new Coordinate(0.0, -2.5, 0.0), + new Coordinate(1.0, -2.5, 0.0), + new Coordinate(1.0, 2.5, 0.0), + new Coordinate(0.0, 2.5, 0.0) + }, 5.0) + .finishFeeding(); + + SceneWithAttenuation scene = new SceneWithAttenuation(profileBuilder); + scene.addSource(geometryFactory.createPoint(new Coordinate(11.49, 0.0, 2.0))); + scene.addReceiver(new Coordinate(1.49, 0.0, 2.0)); + scene.defaultGroundAttenuation = 0.0; + scene.reflexionOrder = 1; + scene.maxSrcDist = 50.0; + scene.setCloseReceiverReflectionWallDistance(enableReflectionProfileFilter ? 0.5 : 0.0); + scene.setComputeHorizontalDiffraction(false); + scene.setComputeVerticalDiffraction(false); + + AttenuationParameters attData = new AttenuationParameters(); + attData.setHumidity(HUMIDITY); + attData.setTemperature(TEMPERATURE); + scene.defaultCnossosParameters = attData; + + AttenuationComputeOutput propDataOut = new AttenuationComputeOutput(true, true, scene); + PathFinder pathFinder = new PathFinder(scene); + pathFinder.setThreadCount(1); + pathFinder.run(propDataOut); + + for (int i = 0; i < propDataOut.getPropagationPaths().size(); i++) { + CnossosPath path = propDataOut.getPropagationPaths().get(i); + LOGGER.info("Path {} profileType={}", i, path.getCutProfile().getProfileType()); + LOGGER.info("Path {} segmentList={}", i, objectMapper.writeValueAsString(path.getSegmentList())); + LOGGER.info("Path {} pointList={}", i, objectMapper.writeValueAsString(path.getPointList())); + } + return propDataOut; + } + /** * Assertions for a list of {@link CnossosPath}. * @param expectedPts Array of arrays of array of expected coordinates (xyz) of points of paths. To each path diff --git a/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestMultiDifFav.json b/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestMultiDifFav.json new file mode 100644 index 000000000..f01a39bd7 --- /dev/null +++ b/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestMultiDifFav.json @@ -0,0 +1,166 @@ +{ + "cutPoints": [ + { + "type": "Source", + "coordinate": { + "x": 0.0, + "y": 0.0, + "z": 1.0 + }, + "zGround": 0.0, + "groundCoefficient": 0.5, + "sourcePk": -1, + "li": 1.0, + "orientation": { + "yaw": 0.0, + "pitch": 0.0, + "roll": 0.0 + } + }, + { + "type": "Wall", + "coordinate": { + "x": 75.0, + "y": 0.0, + "z": 10.0 + }, + "zGround": 0.0, + "groundCoefficient": 0.5, + "wall": { + "p0": { + "x": 75.0, + "y": -50.0, + "z": 10.0 + }, + "p1": { + "x": 75.0, + "y": 50.0, + "z": 10.0 + } + }, + "wallAlpha": [ + 0.004918209037966988, + 0.008088162780793065, + 0.013267721240171722, + 0.02168493917994337, + 0.03525564533465828, + 0.056883929412881944, + 0.09077715686040604, + 0.14258583864393162 + ], + "intersectionType": "BUILDING_ENTER" + }, + { + "type": "Wall", + "coordinate": { + "x": 80.0, + "y": 0.0, + "z": 10.0 + }, + "zGround": 0.0, + "groundCoefficient": 0.5, + "wall": { + "p0": { + "x": 80.0, + "y": 50.0, + "z": 10.0 + }, + "p1": { + "x": 80.0, + "y": -50.0, + "z": 10.0 + } + }, + "wallAlpha": [ + 0.004918209037966988, + 0.008088162780793065, + 0.013267721240171722, + 0.02168493917994337, + 0.03525564533465828, + 0.056883929412881944, + 0.09077715686040604, + 0.14258583864393162 + ], + "intersectionType": "BUILDING_EXIT" + }, + { + "type": "Wall", + "coordinate": { + "x": 120.0, + "y": 0.0, + "z": 10.0 + }, + "zGround": 0.0, + "groundCoefficient": 0.5, + "wall": { + "p0": { + "x": 120.0, + "y": -50.0, + "z": 10.0 + }, + "p1": { + "x": 120.0, + "y": 50.0, + "z": 10.0 + } + }, + "wallAlpha": [ + 0.004918209037966988, + 0.008088162780793065, + 0.013267721240171722, + 0.02168493917994337, + 0.03525564533465828, + 0.056883929412881944, + 0.09077715686040604, + 0.14258583864393162 + ], + "intersectionType": "BUILDING_ENTER" + }, + { + "type": "Wall", + "coordinate": { + "x": 125.0, + "y": 0.0, + "z": 10.0 + }, + "zGround": 0.0, + "groundCoefficient": 0.5, + "wall": { + "p0": { + "x": 125.0, + "y": 50.0, + "z": 10.0 + }, + "p1": { + "x": 125.0, + "y": -50.0, + "z": 10.0 + } + }, + "wallAlpha": [ + 0.004918209037966988, + 0.008088162780793065, + 0.013267721240171722, + 0.02168493917994337, + 0.03525564533465828, + 0.056883929412881944, + 0.09077715686040604, + 0.14258583864393162 + ], + "intersectionType": "BUILDING_EXIT" + }, + { + "type": "Receiver", + "coordinate": { + "x": 200.0, + "y": 0.0, + "z": 4.0 + }, + "zGround": 0.0, + "groundCoefficient": 0.5, + "receiverPk": 0 + } + ], + "curvedPath": false, + "profileType": "DIRECT" +} \ No newline at end of file diff --git a/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestReflection1.json b/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestReflection1.json new file mode 100644 index 000000000..cba51a0d1 --- /dev/null +++ b/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestReflection1.json @@ -0,0 +1,703 @@ +{ + "cutPoints": [ + { + "type": "Source", + "coordinate": { + "x": 661722.1280113459, + "y": 6858873.869236646, + "z": 42.44010598910836 + }, + "zGround": 42.39010598910655, + "groundCoefficient": 0, + "sourcePk": 861, + "li": 106.64301657903766, + "orientation": { + "yaw": 77.90634792780077, + "pitch": -0.6554503475403527, + "roll": 0 + } + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661740.8114094897, + "y": 6858865.446918677, + "z": 42.14435438437163 + }, + "zGround": 42.14435438437163, + "groundCoefficient": 0.7 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661747.9945218033, + "y": 6858862.208832358, + "z": 42.04987149831092 + }, + "zGround": 42.04987149831092, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661751.7860293298, + "y": 6858860.499652811, + "z": 42 + }, + "zGround": 42, + "groundCoefficient": 0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661755.5728488471, + "y": 6858858.792586579, + "z": 42.067560638528285 + }, + "zGround": 42.067560638528285, + "groundCoefficient": 0.7 + }, + { + "type": "Wall", + "coordinate": { + "x": 661763.8811518921, + "y": 6858855.047273789, + "z": 42.153047956692596 + }, + "zGround": 42.215789054541034, + "groundCoefficient": 0.7, + "wall": { + "p0": { + "x": 661736.0001587445, + "y": 6858832.235552125, + "z": 42.153047956692596 + }, + "p1": { + "x": 661766.5767235617, + "y": 6858857.252741518, + "z": 42.153047956692596 + } + }, + "wallAlpha": [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + "intersectionType": "BUILDING_ENTER", + "wallPk": 57 + }, + { + "type": "Wall", + "coordinate": { + "x": 661764.0847906731, + "y": 6858854.955475148, + "z": 42.153047956692596 + }, + "zGround": 42.21942217357285, + "groundCoefficient": 0.7, + "wall": { + "p0": { + "x": 661766.6691137244, + "y": 6858857.06992128, + "z": 42.153047956692596 + }, + "p1": { + "x": 661736.1268063026, + "y": 6858832.080760665, + "z": 42.153047956692596 + } + }, + "wallAlpha": [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + "intersectionType": "BUILDING_EXIT", + "wallPk": 57 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661767.7305839066, + "y": 6858853.311982373, + "z": 42.28446676248358 + }, + "zGround": 42.28446676248358, + "groundCoefficient": 0.7 + }, + { + "type": "Topography", + "coordinate": { + "x": 661768.2991860397, + "y": 6858853.0556613365, + "z": 42.29461119186949 + }, + "zGround": 42.29461119186949, + "groundCoefficient": 0.7 + }, + { + "type": "Topography", + "coordinate": { + "x": 661784.4351092051, + "y": 6858845.781723556, + "z": 41.53994893837065 + }, + "zGround": 41.53994893837065, + "groundCoefficient": 0.7 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661797.4492313622, + "y": 6858839.915067284, + "z": 44.704094138295034 + }, + "zGround": 44.704094138295034, + "groundCoefficient": 0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661800, + "y": 6858838.765202342, + "z": 45.32426676647552 + }, + "zGround": 45.32426676647552, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661807.82296041, + "y": 6858835.238677909, + "z": 47.226276163068746 + }, + "zGround": 47.226276163068746, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661815.0603271817, + "y": 6858831.976134139, + "z": 47.258794272967364 + }, + "zGround": 47.258794272967364, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661822.3446500928, + "y": 6858828.6924229385, + "z": 46.65822987937826 + }, + "zGround": 46.65822987937826, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661829.7054922022, + "y": 6858825.37421753, + "z": 44.786372809916564 + }, + "zGround": 44.786372809916564, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661843.0938927054, + "y": 6858819.338839743, + "z": 42.821250743592216 + }, + "zGround": 42.821250743592216, + "groundCoefficient": 0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661854.1685425139, + "y": 6858814.346481213, + "z": 42.08000419992201 + }, + "zGround": 42.08000419992201, + "groundCoefficient": 0.7 + }, + { + "type": "Topography", + "coordinate": { + "x": 661855.3638512879, + "y": 6858813.807646121, + "z": 42 + }, + "zGround": 42, + "groundCoefficient": 0.7 + }, + { + "type": "Topography", + "coordinate": { + "x": 661858.7995597002, + "y": 6858812.258857807, + "z": 42.12450789959489 + }, + "zGround": 42.12450789959489, + "groundCoefficient": 0.7 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661860.5041478842, + "y": 6858811.490443861, + "z": 42.0958053711009 + }, + "zGround": 42.0958053711009, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661862.5864747086, + "y": 6858810.551748529, + "z": 42.06074233032198 + }, + "zGround": 42.06074233032198, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661864.2143704486, + "y": 6858809.817906888, + "z": 42.072032201719736 + }, + "zGround": 42.072032201719736, + "groundCoefficient": 0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661875.21625371, + "y": 6858804.858350903, + "z": 42.42231030395976 + }, + "zGround": 42.42231030395976, + "groundCoefficient": 0.3 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661883.41951339, + "y": 6858801.160390774, + "z": 42.683485792249776 + }, + "zGround": 42.683485792249776, + "groundCoefficient": 0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661885.993631692, + "y": 6858800, + "z": 42.76544060419645 + }, + "zGround": 42.76544060419645, + "groundCoefficient": 0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661893.3239070332, + "y": 6858796.695573832, + "z": 42.99882200576676 + }, + "zGround": 42.99882200576676, + "groundCoefficient": 0.3 + }, + { + "type": "Topography", + "coordinate": { + "x": 661893.3609066486, + "y": 6858796.678894718, + "z": 43 + }, + "zGround": 43, + "groundCoefficient": 0.3 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661914.709625112, + "y": 6858787.055072877, + "z": 42.37809825388812 + }, + "zGround": 42.37809825388812, + "groundCoefficient": 0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661920.8909043318, + "y": 6858784.268604449, + "z": 42.19803365906798 + }, + "zGround": 42.19803365906798, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661923.2775714569, + "y": 6858783.192715081, + "z": 42.12850852785233 + }, + "zGround": 42.12850852785233, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661929.5027958902, + "y": 6858780.386436523, + "z": 42.14763386795743 + }, + "zGround": 42.14763386795743, + "groundCoefficient": 0 + }, + { + "type": "Wall", + "coordinate": { + "x": 661940.9916210645, + "y": 6858775.207371239, + "z": 47.6 + }, + "zGround": 42.361908118193874, + "groundCoefficient": 0, + "wall": { + "p0": { + "x": 661943.5, + "y": 6858757, + "z": 47.6 + }, + "p1": { + "x": 661937.7, + "y": 6858799.1, + "z": 47.6 + } + }, + "wallAlpha": [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + "intersectionType": "BUILDING_ENTER", + "wallPk": 25554 + }, + { + "type": "Topography", + "coordinate": { + "x": 661948.7511110671, + "y": 6858771.709458729, + "z": 42.50662778076166 + }, + "zGround": 42.50662778076166, + "groundCoefficient": 0 + }, + { + "type": "Wall", + "coordinate": { + "x": 661959.027048498, + "y": 6858767.077152988, + "z": 47.6 + }, + "zGround": 42.26240031460237, + "groundCoefficient": 0, + "wall": { + "p0": { + "x": 661954.3, + "y": 6858800.9, + "z": 47.6 + }, + "p1": { + "x": 661960.1, + "y": 6858759.4, + "z": 47.6 + } + }, + "wallAlpha": [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + "intersectionType": "BUILDING_EXIT", + "wallPk": 25554 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661966.5867443474, + "y": 6858763.669305995, + "z": 42.082729566847085 + }, + "zGround": 42.082729566847085, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661970.0676134975, + "y": 6858762.100159602, + "z": 42 + }, + "zGround": 42, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661995.2320435718, + "y": 6858750.756247217, + "z": 42.972074311698016 + }, + "zGround": 42.972074311698016, + "groundCoefficient": 0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661996.0050303232, + "y": 6858750.407791322, + "z": 42.95023309690925 + }, + "zGround": 42.95023309690925, + "groundCoefficient": 0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 662000, + "y": 6858748.606892758, + "z": 42.837352778325354 + }, + "zGround": 42.837352778325354, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662037.0775299438, + "y": 6858731.892655642, + "z": 41.78970442774896 + }, + "zGround": 41.78970442774896, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662038.0421351499, + "y": 6858731.457819768, + "z": 43.05159988151934 + }, + "zGround": 43.05159988151934, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662042.7914561786, + "y": 6858729.31686599, + "z": 43.38033554820951 + }, + "zGround": 43.38033554820951, + "groundCoefficient": 0 + }, + { + "type": "Reflection", + "coordinate": { + "x": 662071.9044826354, + "y": 6858716.192959729, + "z": 43.5806546101346 + }, + "zGround": 44.56704258037549, + "groundCoefficient": 0, + "wall": { + "p0": { + "x": 662071.9, + "y": 6858715.2, + "z": 52.55489252838457 + }, + "p1": { + "x": 662072.1, + "y": 6858752, + "z": 52.55489252838457 + } + }, + "wallPk": 122063, + "wallAlpha": [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + }, + { + "type": "Topography", + "coordinate": { + "x": 662026.9941156902, + "y": 6858696.531985256, + "z": 43.887764860075244 + }, + "zGround": 43.887764860075244, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662025.823516249, + "y": 6858696.019517261, + "z": 43.84846633159078 + }, + "zGround": 43.84846633159078, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662025.618683483, + "y": 6858695.929845052, + "z": 43.65509803766903 + }, + "zGround": 43.65509803766903, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662021.3098566302, + "y": 6858694.043515892, + "z": 43.920358422920515 + }, + "zGround": 43.920358422920515, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662010.55493262, + "y": 6858689.335197952, + "z": 43.49235029882455 + }, + "zGround": 43.49235029882455, + "groundCoefficient": 0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 662000, + "y": 6858684.714432749, + "z": 43.801217556298184 + }, + "zGround": 43.801217556298184, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661993.2069999373, + "y": 6858681.740575934, + "z": 44 + }, + "zGround": 44, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661982.5458493708, + "y": 6858677.073310369, + "z": 43.946991631699134 + }, + "zGround": 43.946991631699134, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661974.1912606092, + "y": 6858673.415817288, + "z": 42.83640757612829 + }, + "zGround": 42.83640757612829, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661967.6606602207, + "y": 6858670.556834469, + "z": 42 + }, + "zGround": 42, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661965.3842923581, + "y": 6858669.560280366, + "z": 42.28209942482084 + }, + "zGround": 42.28209942482084, + "groundCoefficient": 0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661963.3260077994, + "y": 6858668.659199325, + "z": 42.33211268305454 + }, + "zGround": 42.33211268305454, + "groundCoefficient": 0 + }, + { + "type": "Receiver", + "coordinate": { + "x": 661937.0197737766, + "y": 6858657.142789401, + "z": 47.963762705849874 + }, + "zGround": 43.963762705849874, + "groundCoefficient": 0, + "receiverPk": 121249 + } + ], + "curvedPath": false, + "profileType": "REFLECTION" +} diff --git a/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestReflection2.json b/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestReflection2.json new file mode 100644 index 000000000..17344d2a5 --- /dev/null +++ b/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestReflection2.json @@ -0,0 +1,715 @@ +{ + "cutPoints": [ + { + "type": "Source", + "coordinate": { + "x": 661889.9101599681, + "y": 6858926.937746482, + "z": 41.05 + }, + "zGround": 41.0, + "groundCoefficient": 0.0, + "sourcePk": 2091, + "li": 107.35421692812405, + "orientation": { + "yaw": 259.02175151813043, + "pitch": 0.6724250317751295, + "roll": 0.0 + } + }, + { + "type": "Topography", + "coordinate": { + "x": 661913.5029535431, + "y": 6858919.415421733, + "z": 41.0 + }, + "zGround": 41.0, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661916.6431041227, + "y": 6858918.414216329, + "z": 40.90051409332349 + }, + "zGround": 40.90051409332349, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661917.6079050247, + "y": 6858918.106599273, + "z": 40.87824060482728 + }, + "zGround": 40.87824060482728, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661920.9799701656, + "y": 6858917.0314502455, + "z": 41.0 + }, + "zGround": 41.0, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 661926.8403330224, + "y": 6858915.162932538, + "z": 41.0 + }, + "zGround": 41.0, + "groundCoefficient": 0.0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661956.1829900739, + "y": 6858905.8073216975, + "z": 40.226139978743525 + }, + "zGround": 40.226139978743525, + "groundCoefficient": 0.7 + }, + { + "type": "Topography", + "coordinate": { + "x": 661962.5638051131, + "y": 6858903.77286305, + "z": 40.05785741137583 + }, + "zGround": 40.05785741137583, + "groundCoefficient": 0.7 + }, + { + "type": "Topography", + "coordinate": { + "x": 661964.6971017006, + "y": 6858903.092682907, + "z": 40.0 + }, + "zGround": 40.0, + "groundCoefficient": 0.7 + }, + { + "type": "Topography", + "coordinate": { + "x": 661965.8226491843, + "y": 6858902.733813422, + "z": 40.0 + }, + "zGround": 40.0, + "groundCoefficient": 0.7 + }, + { + "type": "Topography", + "coordinate": { + "x": 661969.0200300844, + "y": 6858901.714360706, + "z": 40.287948666312865 + }, + "zGround": 40.287948666312865, + "groundCoefficient": 0.7 + }, + { + "type": "Wall", + "coordinate": { + "x": 661983.1292780923, + "y": 6858897.215769, + "z": 42.153047956692596 + }, + "zGround": 40.51237513806361, + "groundCoefficient": 0.7, + "wall": { + "p0": { + "x": 661875.3488122831, + "y": 6858885.041231335, + "z": 42.153047956692596 + }, + "p1": { + "x": 661994.8152757528, + "y": 6858898.535782025, + "z": 42.153047956692596 + } + }, + "wallAlpha": [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + "intersectionType": "BUILDING_ENTER", + "wallPk": 57 + }, + { + "type": "Wall", + "coordinate": { + "x": 661983.5954045337, + "y": 6858897.067149277, + "z": 42.153047956692596 + }, + "zGround": 40.51978950292175, + "groundCoefficient": 0.7, + "wall": { + "p0": { + "x": 661994.8372817191, + "y": 6858898.336995869, + "z": 42.153047956692596 + }, + "p1": { + "x": 661875.3849599758, + "y": 6858884.844042583, + "z": 42.153047956692596 + } + }, + "wallAlpha": [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + "intersectionType": "BUILDING_EXIT", + "wallPk": 57 + }, + { + "type": "Topography", + "coordinate": { + "x": 661985.2038901383, + "y": 6858896.554299832, + "z": 40.54537461907603 + }, + "zGround": 40.54537461907603, + "groundCoefficient": 0.7 + }, + { + "type": "Topography", + "coordinate": { + "x": 661985.81277611, + "y": 6858896.36016267, + "z": 40.57729626062577 + }, + "zGround": 40.57729626062577, + "groundCoefficient": 0.7 + }, + { + "type": "Topography", + "coordinate": { + "x": 661989.4344671343, + "y": 6858895.205422942, + "z": 40.88181465564866 + }, + "zGround": 40.88181465564866, + "groundCoefficient": 0.7 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 661992.5869774569, + "y": 6858894.2002767585, + "z": 41.019235343444116 + }, + "zGround": 41.019235343444116, + "groundCoefficient": 0.0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 662000.0, + "y": 6858891.836709139, + "z": 41.342375492822654 + }, + "zGround": 41.342375492822654, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662009.5252251249, + "y": 6858888.799686988, + "z": 41.75758840385592 + }, + "zGround": 41.75758840385592, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662013.5485240932, + "y": 6858887.51689861, + "z": 42.8328109063298 + }, + "zGround": 42.8328109063298, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662018.649741981, + "y": 6858885.890426635, + "z": 42.779690376966016 + }, + "zGround": 42.779690376966016, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662020.2446352348, + "y": 6858885.381910974, + "z": 43.33869814795687 + }, + "zGround": 43.33869814795687, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662030.4334065545, + "y": 6858882.133323798, + "z": 44.19074973480001 + }, + "zGround": 44.19074973480001, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662032.6278568481, + "y": 6858881.433645411, + "z": 44.232858911795375 + }, + "zGround": 44.232858911795375, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662044.9971252306, + "y": 6858877.489828695, + "z": 45.65462197291275 + }, + "zGround": 45.65462197291275, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662046.1567079299, + "y": 6858877.1201074235, + "z": 45.94366184062431 + }, + "zGround": 45.94366184062431, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662050.398266756, + "y": 6858875.767729087, + "z": 46.05098869749143 + }, + "zGround": 46.05098869749143, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662065.0595961693, + "y": 6858871.093111782, + "z": 44.943828226934514 + }, + "zGround": 44.943828226934514, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662067.8854306248, + "y": 6858870.192122911, + "z": 45.125203181355666 + }, + "zGround": 45.125203181355666, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662103.8345642475, + "y": 6858858.730103515, + "z": 45.15340234322309 + }, + "zGround": 45.15340234322309, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662106.6901667969, + "y": 6858857.8196233865, + "z": 44.89983825400298 + }, + "zGround": 44.89983825400298, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662107.4529237237, + "y": 6858857.576426018, + "z": 44.853570927785036 + }, + "zGround": 44.853570927785036, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662109.8352446188, + "y": 6858856.816846981, + "z": 43.915413852719844 + }, + "zGround": 43.915413852719844, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662112.4365645075, + "y": 6858855.987442318, + "z": 45.171376848433134 + }, + "zGround": 45.171376848433134, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662118.058582937, + "y": 6858854.194918333, + "z": 45.258225686208156 + }, + "zGround": 45.258225686208156, + "groundCoefficient": 0.0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 662124.0032503043, + "y": 6858852.2995209815, + "z": 44.186594903938065 + }, + "zGround": 44.186594903938065, + "groundCoefficient": 0.7 + }, + { + "type": "Topography", + "coordinate": { + "x": 662133.2520707784, + "y": 6858849.350627671, + "z": 42.51933244706706 + }, + "zGround": 42.51933244706706, + "groundCoefficient": 0.7 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 662133.9864828198, + "y": 6858849.116467783, + "z": 42.58264711370354 + }, + "zGround": 42.58264711370354, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662147.8278512482, + "y": 6858844.703286786, + "z": 43.775930418111535 + }, + "zGround": 43.775930418111535, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662148.7251064538, + "y": 6858844.417205995, + "z": 43.74802009707152 + }, + "zGround": 43.74802009707152, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662157.8768260743, + "y": 6858841.499272314, + "z": 41.400029107436254 + }, + "zGround": 41.400029107436254, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662162.0412608084, + "y": 6858840.171484218, + "z": 41.47202149091655 + }, + "zGround": 41.47202149091655, + "groundCoefficient": 0.0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 662172.3362832965, + "y": 6858836.889019926, + "z": 41.73890921652997 + }, + "zGround": 41.73890921652997, + "groundCoefficient": 0.3 + }, + { + "type": "Topography", + "coordinate": { + "x": 662181.2042895042, + "y": 6858834.061545411, + "z": 41.96880303271502 + }, + "zGround": 41.96880303271502, + "groundCoefficient": 0.3 + }, + { + "type": "Topography", + "coordinate": { + "x": 662182.2046410742, + "y": 6858833.7425933825, + "z": 42.0 + }, + "zGround": 42.0, + "groundCoefficient": 0.3 + }, + { + "type": "Reflection", + "coordinate": { + "x": 662182.2984317525, + "y": 6858833.712689169, + "z": 42.02355479548803 + }, + "zGround": 42.010475103236914, + "groundCoefficient": 0.3, + "wall": { + "p0": { + "x": 662183.0, + "y": 6858829.1, + "z": 48.0560792335534 + }, + "p1": { + "x": 662181.8, + "y": 6858837.0, + "z": 48.0560792335534 + } + }, + "wallPk": 100530, + "wallAlpha": [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + }, + { + "type": "Topography", + "coordinate": { + "x": 662181.7796757604, + "y": 6858833.350006894, + "z": 42.031913426757605 + }, + "zGround": 42.031913426757605, + "groundCoefficient": 0.3 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 662178.7927028377, + "y": 6858831.261699192, + "z": 42.275596183120854 + }, + "zGround": 42.275596183120854, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662165.3781838162, + "y": 6858821.883092785, + "z": 43.36997736936667 + }, + "zGround": 43.36997736936667, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662162.2306892686, + "y": 6858819.682558239, + "z": 42.78146451408848 + }, + "zGround": 42.78146451408848, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662157.7161949413, + "y": 6858816.526301548, + "z": 42.3850420509512 + }, + "zGround": 42.3850420509512, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662151.0290400238, + "y": 6858811.851054239, + "z": 42.5639259733648 + }, + "zGround": 42.5639259733648, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662138.8453854444, + "y": 6858803.332992525, + "z": 42.84243663546004 + }, + "zGround": 42.84243663546004, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662137.2654094909, + "y": 6858802.228370543, + "z": 42.882604707540764 + }, + "zGround": 42.882604707540764, + "groundCoefficient": 0.0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 662135.3628447418, + "y": 6858800.89821432, + "z": 42.92289287225354 + }, + "zGround": 42.92289287225354, + "groundCoefficient": 0.0 + }, + { + "type": "GroundEffect", + "coordinate": { + "x": 662134.078100233, + "y": 6858800.0, + "z": 42.95009825298734 + }, + "zGround": 42.95009825298734, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662119.6447983974, + "y": 6858789.909123328, + "z": 43.25573370738 + }, + "zGround": 43.25573370738, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662107.750763736, + "y": 6858781.593546041, + "z": 43.47209529936684 + }, + "zGround": 43.47209529936684, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662101.2436656111, + "y": 6858777.044183365, + "z": 43.62571829940858 + }, + "zGround": 43.62571829940858, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662047.7770049316, + "y": 6858739.663583614, + "z": 43.22019380950089 + }, + "zGround": 43.22019380950089, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662038.678030506, + "y": 6858733.302140486, + "z": 43.010128445261316 + }, + "zGround": 43.010128445261316, + "groundCoefficient": 0.0 + }, + { + "type": "Topography", + "coordinate": { + "x": 662037.1966272618, + "y": 6858732.266434478, + "z": 41.770316492253535 + }, + "zGround": 41.770316492253535, + "groundCoefficient": 0.0 + }, + { + "type": "Receiver", + "coordinate": { + "x": 662037.0197737766, + "y": 6858732.142789401, + "z": 45.78293649348511 + }, + "zGround": 41.78293649348511, + "groundCoefficient": 0.0, + "receiverPk": 122981 + } + ], + "curvedPath": false, + "profileType": "REFLECTION" +} diff --git a/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestSingleDif.json b/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestSingleDif.json new file mode 100644 index 000000000..27cad7284 --- /dev/null +++ b/noisemodelling-propagation/src/test/resources/org/noise_planet/noisemodelling/propagation/RegressionTestSingleDif.json @@ -0,0 +1,67 @@ +{ + "cutPoints": [ + { + "type": "Source", + "coordinate": { + "x": 0.0, + "y": 0.0, + "z": 1.0 + }, + "zGround": 0.0, + "groundCoefficient": 0.5, + "sourcePk": -1, + "li": 1.0, + "orientation": { + "yaw": 0.0, + "pitch": 0.0, + "roll": 0.0 + } + }, + { + "type": "Wall", + "coordinate": { + "x": 20.0, + "y": 0.0, + "z": 6.0 + }, + "zGround": 0.0, + "groundCoefficient": 0.5, + "wall": { + "p0": { + "x": 20.0, + "y": -100.0, + "z": 6.0 + }, + "p1": { + "x": 20.0, + "y": 100.0, + "z": 6.0 + } + }, + "wallAlpha": [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0 + ], + "intersectionType": "THIN_WALL_ENTER_EXIT" + }, + { + "type": "Receiver", + "coordinate": { + "x": 50.0, + "y": 0.0, + "z": 4.0 + }, + "zGround": 0.0, + "groundCoefficient": 0.5, + "receiverPk": 0 + } + ], + "curvedPath": false, + "profileType": "DIRECT" +} \ No newline at end of file diff --git a/noisemodelling-scripts/pom.xml b/noisemodelling-scripts/pom.xml new file mode 100644 index 000000000..65d42e46d --- /dev/null +++ b/noisemodelling-scripts/pom.xml @@ -0,0 +1,591 @@ + + + 4.0.0 + + org.noise-planet + noisemodelling-parent + 6.0.1-SNAPSHOT + ../pom.xml + + + noisemodelling-scripts + NoiseModelling Scripts + WebServer and groovy scripts of NoiseModelling + + + 11 + 11 + UTF-8 + + + + + + + unix-config + + unix + + + sh + -c + + + command -v python3 >/dev/null 2>&1 && ( + python3 -m venv target/venv && + target/venv/bin/python -m pip install -r ../Docs/requirements.txt && + target/venv/bin/sphinx-build -M html ../Docs target/sphinx + ) || echo "Python3 not found. Skipping documentation generation." + + + + + windows-config + + windows + + + cmd + /c + + where python >nul 2>nul && ( python -m venv target/venv && target\venv\Scripts\activate.bat && pip install -r ..\Docs\requirements.txt && sphinx-build -M html ..\Docs target\sphinx ) || echo Python not found. Skipping documentation generation. + + + + + macos-bundler + + mac + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.5.0 + + + regex-property + + regex-property + + + macOS.version + ${project.version} + + ^([0-9]+(\.[0-9]+)*).* + $1 + false + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.6.0 + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/macos-stage/lib + + + + + + + maven-resources-plugin + 3.3.1 + + + copy-app-files + package + + copy-resources + + + ${project.build.directory}/macos-stage/lib + + + + ${project.build.directory} + + ${project.build.finalName}.jar + help/** + + + + + + + copy-help-files + package + + copy-resources + + + ${project.build.directory}/macos-stage/help + + + + ${project.build.directory}/sphinx/html/ + + ** + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + + create-macos-app + package + + exec + + + jpackage + + --input + ${project.build.directory}/macos-stage + --main-jar + lib/${project.build.finalName}.jar + --main-class + org.noise_planet.noisemodelling.webserver.NoiseModellingServer + --type + dmg + --dest + ${project.build.directory} + --name + NoiseModelling + --icon + ../installer/Logo_noisemodelling_square.icns + --vendor + ${parent.organization.name} + --app-version + ${macOS.version} + --mac-package-name + NoiseModelling + --arguments + -u -r "" + + + + + + + + + + + + ${project.groupId} + noisemodelling-jdbc + ${project.version} + + + ${project.groupId} + noisemodelling-emission + ${project.version} + + + ${project.groupId} + noisemodelling-pathfinder + ${project.version} + + + ${project.groupId} + noisemodelling-propagation + ${project.version} + + + org.junit.jupiter + junit-jupiter + test + + + org.apache.groovy + groovy-templates + + + org.geotools.ogc + net.opengis.wps + + + org.geotools.xsd + gt-xsd-wps + + + org.orbisgis + h2gis-utilities + + + org.orbisgis + h2gis + + + org.orbisgis + postgis-jts + + + com.h2database + h2 + + + org.postgresql + postgresql + + + commons-cli + commons-cli + + + org.osgi + org.osgi.service.jdbc + + + com.opencsv + opencsv + + + io.javalin + javalin-bundle + + + ch.qos.logback + logback-classic + + + + + org.apache.groovy + groovy-sql + + + org.apache.groovy + groovy-json + + + org.slf4j + slf4j-api + + + org.apache.groovy + groovy + + + org.slf4j + slf4j-reload4j + + + com.zaxxer + HikariCP + + + com.auth0 + java-jwt + + + io.javalin + javalin-rendering + + + org.thymeleaf + thymeleaf + + + com.atlassian + onetime + + + com.google.zxing + core + + + com.google.zxing + javase + + + org.openstreetmap.osmosis + osmosis-core + + + org.openstreetmap.osmosis + osmosis-pbf + + + org.openstreetmap.osmosis + osmosis-xml + + + org.jfree + jfreechart + + + org.matsim + matsim + + + org.geotools + * + + + + org.apache.logging.log4j + log4j-1.2-api + + + + + + + + + ${project.basedir}/src/main/resources + + org/noise_planet/noisemodelling/version.properties + + true + + + + ${project.basedir}/src/main/resources + + org/noise_planet/noisemodelling/version.properties + + false + + + + ${project.basedir}/src/main/groovy/org/noise_planet/noisemodelling/scripts + + **/*.groovy + + scripts + false + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.5.1 + + + generate-functions-docs + package + + exec + + + ${java.home}/bin/java + + -classpath + + org.noise_planet.noisemodelling.autodoc.GenerateFunctionsDocs + ${project.parent.basedir}/Docs + ${project.basedir}/src/main/groovy/org/noise_planet/noisemodelling/scripts + + + + + generate-cnossos-report + package + + exec + + + ${java.home}/bin/java + + -classpath + + org.noise_planet.noisemodelling.autodoc.GenerateReferenceDeviation + ${project.parent.basedir}/Docs + + + + + generate-documentation + package + + exec + + + + ${shell.executable} + + ${shell.arg} + ${sphinx.command} + + true + + + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 4.2.1 + + + + addSources + addTestSources + compile + compileTests + + + + + + + ${project.basedir}/src/main/groovy + + **/*.groovy + + + + + + ${project.basedir}/src/test/groovy + + **/*.groovy + + + + + + + + org.codehaus.mojo + appassembler-maven-plugin + 2.1.0 + + + assemble + package + + assemble + + + + + + + org.noise_planet.noisemodelling.webserver.NoiseModellingServer + WebServer + + + org.noise_planet.noisemodelling.runner.Main + ScriptRunner + + + + flat + true + lib + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + create-distribution + package + + single + + + NoiseModelling_${project.parent.version} + false + + src/assembly/distribution.xml + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + + jar + + package + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 11 + 11 + + + + org.apache.felix + maven-bundle-plugin + 5.1.1 + true + + + bundle-manifest + process-classes + + manifest + + + + + + jar + bundle + war + + + org.noise_planet.noisemodelling.* + UMRAE team (Eiffel University), DECIDE team (Lab-STICC) + org.slf4j;version="[1.6.0,2)",!org.h2.*,* + ${buildNumber} + + + + + + + diff --git a/noisemodelling-scripts/src/assembly/distribution.xml b/noisemodelling-scripts/src/assembly/distribution.xml new file mode 100644 index 000000000..63a9695d4 --- /dev/null +++ b/noisemodelling-scripts/src/assembly/distribution.xml @@ -0,0 +1,65 @@ + + + dist + + zip + + + true + + + + + ${project.build.directory}/appassembler + / + + **/* + + 0755 + + + + ${project.basedir}/src/assembly + / + + start_linux_macos.sh + start_windows.bat + + 0755 + + + + ${project.basedir}/src/test/resources/org/noise_planet/noisemodelling/scripts + /resources + + + + ${project.basedir}/target/sphinx/html + /help + + + + ${project.basedir}/src/main/groovy/org/noise_planet/noisemodelling/scripts + scripts + + + ${project.parent.basedir} + / + + LICENSE + README.md + + + + ${project.basedir}/src/test/groovy/org/noise_planet/noisemodelling/scripts + / + + get_started_tutorial_complex.groovy + + 0755 + + + \ No newline at end of file diff --git a/noisemodelling-scripts/src/assembly/start_linux_macos.sh b/noisemodelling-scripts/src/assembly/start_linux_macos.sh new file mode 100644 index 000000000..707f087ee --- /dev/null +++ b/noisemodelling-scripts/src/assembly/start_linux_macos.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bash bin/WebServer -u -s scripts/ -r "" diff --git a/noisemodelling-scripts/src/assembly/start_windows.bat b/noisemodelling-scripts/src/assembly/start_windows.bat new file mode 100644 index 000000000..6044418ca --- /dev/null +++ b/noisemodelling-scripts/src/assembly/start_windows.bat @@ -0,0 +1 @@ +call bin\WebServer.bat -u -s scripts/ -r "" diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/Add_Laeq_Leq_columns.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/Add_Laeq_Leq_columns.groovy similarity index 75% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/Add_Laeq_Leq_columns.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/Add_Laeq_Leq_columns.groovy index 910b92a91..4e830f47a 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/Add_Laeq_Leq_columns.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/Add_Laeq_Leq_columns.groovy @@ -15,20 +15,17 @@ * @Author Arnaud Can, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Acoustic_Tools +package org.noise_planet.noisemodelling.scripts.Acoustic_Tools -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.JDBCUtilities import org.slf4j.Logger import org.slf4j.LoggerFactory import java.sql.Connection -title = 'Add Leq and LAeq columns' -description = '➡️ Add the columns Leq and LAeq to a table with octave band values from 63 Hz to 8000 Hz.'+ +title = 'Add LAeq and Leq columns' +description = '➡️ Add the columns LAeq and Leq to a table with octave band values from 63 Hz to 8000 Hz.'+ '


' + 'The columns of the table should be named HZ63, HZ125,..., HZ8000 with an HZ prefix that can be changed.' @@ -43,7 +40,7 @@ inputs = [ tableName: [ title : 'Name of the table', name : 'Name of the table', - description: 'Name of the table on which Leq and LAeq columns will be added.', + description: 'Name of the table on which LAeq and Leq columns will be added.', type : String.class ] ] @@ -58,15 +55,6 @@ outputs = [ ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - def exec(Connection connection, input) { // output string, the information given back to the user @@ -114,17 +102,3 @@ def exec(Connection connection, input) { return resultString } - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/Create_Isolines.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/Create_Isolines.groovy similarity index 89% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/Create_Isolines.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/Create_Isolines.groovy index 987146d06..56220a375 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/Create_Isolines.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/Create_Isolines.groovy @@ -1,387 +1,358 @@ -/** - * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. - * - * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). - * - * - * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. - * - * Contact: contact@noise-planet.org - * - */ - -/** - * @Author Adapted from NM WPS scripts - * @Author Ignacio Soto Molina, Ministry for Ecological Transition (MITECO), Spain - */ - -package org.noise_planet.noisemodelling.wps.Acoustic_Tools - -import geoserver.GeoServer -import geoserver.catalog.Store -import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore -import org.h2gis.utilities.GeometryTableUtilities -import org.h2gis.utilities.TableLocation -import org.h2gis.utilities.wrapper.ConnectionWrapper -import org.locationtech.jts.geom.* -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import java.sql.Connection -import java.sql.SQLException - -// ---------------- -// Create Isolines (Isophones) from TRIANGLES + RECEIVERS_LEVEL -// ---------------- - -title = 'Create Isolines (Isophones)' - -description = 'Generate isolines (isophones) by linear interpolation on triangle edges (marching-triangles).' + - '
One multilines map per PERIOD and per LEVEL is created.' + - '

Main output table : ISOLINES_NOISE_MAP ' + - 'with :
' + - '- PERIOD : receivers period label (VARCHAR).
' + - '- LEVEL : isoline value (DOUBLE).
' + - '- THE_GEOM : MULTILINESTRING/LINESTRING geometry.' + - '

Additional output tables : one table per PERIOD, ' + - 'named L<PERIOD>_ISOLINES_NOISE_MAP, ' + - 'containing only the isolines of that PERIOD (same structure as above).' - -inputs = [ - trianglesTable : [ - name : 'Triangles table', - title : 'Triangles table', - description: 'Name of the triangles table.
' + - 'Shall contain : PK, THE_GEOM, PK_1, PK_2, PK_3, CELL_ID.', - min : 1, max: 1, - type : String.class - ], - receiversTable : [ - name : 'Receivers level table', - title : 'Receivers level table', - description: 'Name of the receivers level table.
' + - 'Shall contain : IDRECEIVER, PERIOD, THE_GEOM, LAEQ (or any field to contour).', - min : 1, max: 1, - type : String.class - ], - fieldName : [ - name : 'Field to contour', - title : 'Field to contour', - description: 'Receivers numeric field to contour (e.g. LAEQ). Default: LAEQ.', - min : 0, max: 1, - type : String.class - ], - isoClasses : [ - name : 'Iso levels (dB)', - title : 'Iso levels (dB)', - description: 'Comma-separated levels. Default: 35.0,40.0,45.0,50.0,55.0,60.0,65.0,70.0,75.0,80.0,200.0', - min : 0, max: 1, - type : String.class - ] -] - -outputs = [ - result: [ - name: 'Result output string', - title: 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', - type: String.class - ] -] - -// ------------------- -// Open Connection to Geoserver (same pattern as Template) -// ------------------- -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// ------------------- -// run() wrapper (same pattern as Template) -// ------------------- -def run(input) { - String dbName = "h2gisdb" - openGeoserverDataStoreConnection(dbName).withCloseable { Connection connection -> - return [result: exec(connection, input)] - } -} - -// ------------------- -// Main function (same structure as Template.exec) -// ------------------- -def exec(Connection connection, input) { - - // Need to change the ConnectionWrapper to WpsConnectionWrapper to work under postGIS database - connection = new ConnectionWrapper(connection) - - // Create a sql connection to interact with the database in SQL - Sql sql = new Sql(connection) - - // Logger - Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") - - // print to command window - logger.info('Start : Create Isolines') - logger.info("inputs {}", input) - - // ------------------- - // Get inputs - // ------------------- - String trianglesTable = (input['trianglesTable'] ?: 'TRIANGLES') as String - String receiversTable = (input['receiversTable'] ?: 'RECEIVERS_LEVEL') as String - String fieldName = (input['fieldName'] ?: 'LAEQ') as String - String isoClassesStr = (input['isoClasses'] ?: '35.0,40.0,45.0,50.0,55.0,60.0,65.0,70.0,75.0,80.0,200.0') as String - - // do it case-insensitive for table names - trianglesTable = trianglesTable.toUpperCase() - receiversTable = receiversTable.toUpperCase() - - // Parse levels (sorted) - List levels = isoClassesStr.split(',') - .collect { it.trim() } - .findAll { it } - .collect { it as Double } - .sort() - - // ------------------- - // Checks - // ------------------- - def triExists = org.h2gis.utilities.JDBCUtilities.tableExists(connection, trianglesTable) - def recExists = org.h2gis.utilities.JDBCUtilities.tableExists(connection, receiversTable) - if (!triExists) throw new SQLException(String.format("The table %s does not exist.", trianglesTable)) - if (!recExists) throw new SQLException(String.format("The table %s does not exist.", receiversTable)) - - // SRID (receivers first, then triangles) - int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(receiversTable)) - if (srid == 0) srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(trianglesTable)) - if (srid == 0) throw new SQLException("Unable to determine SRID of geometries (receivers/triangles).") - - // Validate field existence in receivers (case-insensitive) - def cntRow = sql.firstRow( - "SELECT COUNT(*) AS CNT FROM INFORMATION_SCHEMA.COLUMNS WHERE UPPER(TABLE_NAME)=? AND UPPER(COLUMN_NAME)=?", - [receiversTable.toUpperCase(), fieldName.toUpperCase()] - ) - if ((cntRow?.CNT ?: 0) == 0) { - throw new SQLException(String.format("Field '%s' does not exist in %s", fieldName, receiversTable)) - } - - // ------------------- - // Create output & temporaries (NO placeholders in DDL) - // ------------------- - String outTable = "ISOLINES_NOISE_MAP" - String segTable = "TMP_ISO_SEGMENTS" - String resultString - - sql.execute("DROP TABLE IF EXISTS \"" + outTable + "\"") - sql.execute("""CREATE TABLE "${outTable}"( - "PERIOD" VARCHAR, - "LEVEL" DOUBLE, - "THE_GEOM" GEOMETRY - )""") - sql.execute("CREATE SPATIAL INDEX ON \"" + outTable + "\"(\"THE_GEOM\")") - - sql.execute("DROP TABLE IF EXISTS \"" + segTable + "\"") - sql.execute("""CREATE TABLE "${segTable}"( - "PERIOD" VARCHAR, - "LEVEL" DOUBLE, - "THE_GEOM" GEOMETRY - )""") - sql.execute("CREATE SPATIAL INDEX ON \"" + segTable + "\"(\"THE_GEOM\")") - - // ------------------- - // Periods list - // ------------------- - List periods = [] - sql.eachRow("SELECT DISTINCT \"PERIOD\" FROM \"" + receiversTable + "\" WHERE \"PERIOD\" IS NOT NULL") { r -> - periods.add(r.PERIOD?.toString()) - } - if (periods.isEmpty()) periods = [null] - - // ------------------- - // Geometry machinery - // ------------------- - GeometryFactory gf = new GeometryFactory(new PrecisionModel(), srid) - double eps = 1e-9 - - // Interpolate point on edge - def interpPoint = { Coordinate a, Coordinate b, double va, double vb, double cLevel -> - double dv = (vb - va) - if (Math.abs(dv) < eps) return null - double t = (cLevel - va) / dv - if (t < -eps || t > 1 + eps) return null - if (t < 0) t = 0 - if (t > 1) t = 1 - new Coordinate(a.x + t * (b.x - a.x), a.y + t * (b.y - a.y)) - } - - // Load triangles to memory - List triRows = [] - sql.eachRow("SELECT \"PK\", \"PK_1\", \"PK_2\", \"PK_3\" FROM \"" + trianglesTable + "\"") { r -> - triRows.add([PK: r.PK as Integer, A: r.PK_1 as Integer, B: r.PK_2 as Integer, C: r.PK_3 as Integer]) - } - - // Insert batch for segments - String insSegSQL = "INSERT INTO " + segTable + "(PERIOD, LEVEL, THE_GEOM) VALUES (?, ?, ?)" - - // ------------------- - // Build segments by PERIOD & LEVEL - // ------------------- - periods.each { periodVal -> - // Map: receiver id -> (coord, val) - Map recMap = [:] - String sqlRec = (periodVal == null) ? - "SELECT IDRECEIVER, THE_GEOM, " + fieldName + " AS VAL FROM " + receiversTable : - "SELECT IDRECEIVER, THE_GEOM, " + fieldName + " AS VAL FROM " + receiversTable + " WHERE PERIOD = ?" - - if (periodVal == null) { - sql.eachRow(sqlRec) { r -> - Point pt = r.THE_GEOM as Point - if (pt != null) recMap[r.IDRECEIVER as Integer] = [coord: pt.coordinate, val: (r.VAL as Double)] - } - } else { - sql.eachRow(sqlRec, [periodVal]) { r -> - Point pt = r.THE_GEOM as Point - if (pt != null) recMap[r.IDRECEIVER as Integer] = [coord: pt.coordinate, val: (r.VAL as Double)] - } - } - - if (recMap.isEmpty()) return - - sql.withBatch(5000, insSegSQL) { ps -> - triRows.each { trow -> - def rA = recMap[trow.A]; def rB = recMap[trow.B]; def rC = recMap[trow.C] - if (rA == null || rB == null || rC == null) return - - Coordinate A = rA.coord as Coordinate - Coordinate B = rB.coord as Coordinate - Coordinate C = rC.coord as Coordinate - double vA = (rA.val as Double) - double vB = (rB.val as Double) - double vC = (rC.val as Double) - - levels.each { L -> - List hits = [] - - // AB - if ((L > Math.min(vA, vB) - eps) && (L < Math.max(vA, vB) + eps) && Math.abs(vA - vB) > eps) { - def p = interpPoint(A, B, vA, vB, L); if (p != null) hits << p - } else if (Math.abs(vA - L) <= eps && Math.abs(vA - vB) > eps) { - hits << A - } else if (Math.abs(vB - L) <= eps && Math.abs(vA - vB) > eps) { - hits << B - } - // BC - if ((L > Math.min(vB, vC) - eps) && (L < Math.max(vB, vC) + eps) && Math.abs(vB - vC) > eps) { - def p = interpPoint(B, C, vB, vC, L); if (p != null) hits << p - } else if (Math.abs(vB - L) <= eps && Math.abs(vB - vC) > eps) { - hits << B - } else if (Math.abs(vC - L) <= eps && Math.abs(vB - vC) > eps) { - hits << C - } - // CA - if ((L > Math.min(vC, vA) - eps) && (L < Math.max(vC, vA) + eps) && Math.abs(vC - vA) > eps) { - def p = interpPoint(C, A, vC, vA, L); if (p != null) hits << p - } else if (Math.abs(vC - L) <= eps && Math.abs(vC - vA) > eps) { - hits << C - } else if (Math.abs(vA - L) <= eps && Math.abs(vC - vA) > eps) { - hits << A - } - - // de-dup small numeric jitter - def uniq = [] - hits.each { h -> - if (h == null) return - def kx = Math.rint(h.x * 1e6) / 1e6 - def ky = Math.rint(h.y * 1e6) / 1e6 - if (!uniq.any { Math.abs(it.x - kx) < 1e-9 && Math.abs(it.y - ky) < 1e-9 }) { - uniq << new Coordinate(kx, ky) - } - } - - if (uniq.size() == 2) { - LineString ls = gf.createLineString([uniq[0], uniq[1]] as Coordinate[]) - ps.addBatch(periodVal, (L as Double), ls) - } - } // levels - } // triangles - } // batch - } // periods - - // ------------------- - // Stitch segments per (PERIOD, LEVEL) and insert to output - // (without using GROUP BY directly to avoid dialect quirks) - // ------------------- - List groups = [] - sql.eachRow("SELECT DISTINCT \"PERIOD\", \"LEVEL\" FROM \"" + segTable + "\"") { g -> - groups.add([p: g.PERIOD, l: (g.LEVEL as Double)]) - } - - String insMerged = - "INSERT INTO \"" + outTable + "\"(\"PERIOD\", \"LEVEL\", \"THE_GEOM\") " + - "SELECT ?, ?, ST_LineMerge(ST_Union(\"THE_GEOM\")) " + - "FROM \"" + segTable + "\" " + - "WHERE ((\"PERIOD\" IS NULL AND ? IS NULL) OR \"PERIOD\" = ?) " + - "AND \"LEVEL\" = ?" - - groups.each { g -> - sql.execute(insMerged, [g.p, g.l, g.p, g.p, g.l]) - } - - // ------------------- - // Cleanup - // ------------------- - sql.execute("DROP TABLE IF EXISTS \"" + segTable + "\"") - - // ------------------- - // Create a layer for each PERIOD from the output - // ------------------- - periods.findAll { it != null }.each { p -> - // Normalize table name: uppercase and only [A-Z0-9_] - String periodSafe = p.toString().toUpperCase().replaceAll('[^A-Z0-9_]', '_') - String perTable = "L" + periodSafe + "_ISOLINES_NOISE_MAP" - - // Drop + create destination table (without placeholders in DDL) - sql.execute("DROP TABLE IF EXISTS \"" + perTable + "\"") - sql.execute("""CREATE TABLE "${perTable}"( - "PERIOD" VARCHAR, - "LEVEL" DOUBLE, - "THE_GEOM" GEOMETRY - )""") - - // Insert only the rows of that PERIOD (here we can build the WHERE as a string) - String val = p.replace("'", "''") // escapar comillas simples - sql.execute("""INSERT INTO "${perTable}"("PERIOD","LEVEL","THE_GEOM") - SELECT "PERIOD","LEVEL","THE_GEOM" - FROM "${outTable}" - WHERE "PERIOD" = '${val}'""") - - // Spatial index - sql.execute("CREATE SPATIAL INDEX ON \"" + perTable + "\"(\"THE_GEOM\")") - } - - // ------------------- - // Print results - // ------------------- - List periodTables = periods.findAll { it != null } - .collect { "L" + it.toString().toUpperCase().replaceAll("[^A-Z0-9_]", "_") + "_ISOLINES_NOISE_MAP" } - - if (periodTables.isEmpty()) { - resultString = "Isolines created in " + outTable + " for " + levels.size() + " levels. No PERIOD values found, so no per-period tables were created." - } else { - resultString = "Isolines created in " + outTable + " for " + levels.size() + " levels and " + - periodTables.size() + " periods: " + periodTables.join(", ") - } - - logger.info('Result : ' + resultString) - logger.info('End : Create Isolines') - - // send resultString to WPS Builder - return resultString -} - +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + +/** + * @Author Adapted from NM WPS scripts + * @Author Ignacio Soto Molina, Ministry for Ecological Transition (MITECO), Spain + */ + +package org.noise_planet.noisemodelling.scripts.Acoustic_Tools + +import groovy.sql.Sql +import org.h2gis.utilities.GeometryTableUtilities +import org.h2gis.utilities.TableLocation +import org.h2gis.utilities.wrapper.ConnectionWrapper +import org.locationtech.jts.geom.* +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.sql.Connection +import java.sql.SQLException + +// ---------------- +// Create Isolines (Isophones) from TRIANGLES + RECEIVERS_LEVEL +// ---------------- + +title = 'Create Isolines' + +description = 'Generate isolines (isophones) by linear interpolation on triangle edges (marching-triangles).' + + '
One multilines map per PERIOD and per LEVEL is created.' + + '

Main output table : ISOLINES_NOISE_MAP ' + + 'with :
' + + '- PERIOD : receivers period label (VARCHAR).
' + + '- LEVEL : isoline value (DOUBLE).
' + + '- THE_GEOM : MULTILINESTRING/LINESTRING geometry.' + + '

Additional output tables : one table per PERIOD, ' + + 'named L<PERIOD>_ISOLINES_NOISE_MAP, ' + + 'containing only the isolines of that PERIOD (same structure as above).' + +inputs = [ + trianglesTable : [ + name : 'Triangles table', + title : 'Triangles table', + description: 'Name of the triangles table.
' + + 'Shall contain : PK, THE_GEOM, PK_1, PK_2, PK_3, CELL_ID.', + type : String.class + ], + receiversTable : [ + name : 'Receivers level table', + title : 'Receivers level table', + description: 'Name of the receivers level table.
' + + 'Shall contain : IDRECEIVER, PERIOD, THE_GEOM, LAEQ (or any field to contour).', + type : String.class + ], + fieldName : [ + name : 'Field to contour', + title : 'Field to contour', + description: 'Receivers numeric field to contour (e.g. LAEQ).', + default : 'LAEQ', + type : String.class + ], + isoClasses : [ + name : 'Iso levels (dB)', + title : 'Iso levels (dB)', + description: 'Comma-separated levels.', + default : '35.0,40.0,45.0,50.0,55.0,60.0,65.0,70.0,75.0,80.0,200.0', + type : String.class + ] +] + +outputs = [ + result: [ + name: 'Result output string', + title: 'Result output string', + description: 'This type of result does not allow the blocks to be linked together.', + type: String.class + ] +] + +// ------------------- +// Main function (same structure as Template.exec) +// ------------------- +def exec(Connection connection, Map input) { + + // Need to change the ConnectionWrapper to WpsConnectionWrapper to work under postGIS database + connection = new ConnectionWrapper(connection) + + // Create a sql connection to interact with the database in SQL + Sql sql = new Sql(connection) + + // Logger + Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") + + // print to command window + logger.info('Start : Create Isolines') + logger.info("inputs {}", input) + + // ------------------- + // Get inputs + // ------------------- + String trianglesTable = (input['trianglesTable'] ?: 'TRIANGLES') as String + String receiversTable = (input['receiversTable'] ?: 'RECEIVERS_LEVEL') as String + String fieldName = (input['fieldName'] ?: 'LAEQ') as String + String isoClassesStr = (input['isoClasses'] ?: '35.0,40.0,45.0,50.0,55.0,60.0,65.0,70.0,75.0,80.0,200.0') as String + + // do it case-insensitive for table names + trianglesTable = trianglesTable.toUpperCase() + receiversTable = receiversTable.toUpperCase() + + // Parse levels (sorted) + List levels = isoClassesStr.split(',') + .collect { it.trim() } + .findAll { it } + .collect { it as Double } + .sort() + + // ------------------- + // Checks + // ------------------- + def triExists = org.h2gis.utilities.JDBCUtilities.tableExists(connection, trianglesTable) + def recExists = org.h2gis.utilities.JDBCUtilities.tableExists(connection, receiversTable) + if (!triExists) throw new SQLException(String.format("The table %s does not exist.", trianglesTable)) + if (!recExists) throw new SQLException(String.format("The table %s does not exist.", receiversTable)) + + // SRID (receivers first, then triangles) + int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(receiversTable)) + if (srid == 0) srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(trianglesTable)) + if (srid == 0) throw new SQLException("Unable to determine SRID of geometries (receivers/triangles).") + + // Validate field existence in receivers (case-insensitive) + def cntRow = sql.firstRow( + "SELECT COUNT(*) AS CNT FROM INFORMATION_SCHEMA.COLUMNS WHERE UPPER(TABLE_NAME)=? AND UPPER(COLUMN_NAME)=?", + [receiversTable.toUpperCase(), fieldName.toUpperCase()] + ) + if ((cntRow?.CNT ?: 0) == 0) { + throw new SQLException(String.format("Field '%s' does not exist in %s", fieldName, receiversTable)) + } + + // ------------------- + // Create output & temporaries (NO placeholders in DDL) + // ------------------- + String outTable = "ISOLINES_NOISE_MAP" + String segTable = "TMP_ISO_SEGMENTS" + String resultString + + sql.execute("DROP TABLE IF EXISTS \"" + outTable + "\"") + sql.execute("""CREATE TABLE "${outTable}"( + "PERIOD" VARCHAR, + "LEVEL" DOUBLE, + "THE_GEOM" GEOMETRY + )""") + sql.execute("CREATE SPATIAL INDEX ON \"" + outTable + "\"(\"THE_GEOM\")") + + sql.execute("DROP TABLE IF EXISTS \"" + segTable + "\"") + sql.execute("""CREATE TABLE "${segTable}"( + "PERIOD" VARCHAR, + "LEVEL" DOUBLE, + "THE_GEOM" GEOMETRY + )""") + sql.execute("CREATE SPATIAL INDEX ON \"" + segTable + "\"(\"THE_GEOM\")") + + // ------------------- + // Periods list + // ------------------- + List periods = [] + sql.eachRow("SELECT DISTINCT \"PERIOD\" FROM \"" + receiversTable + "\" WHERE \"PERIOD\" IS NOT NULL") { r -> + periods.add(r.PERIOD?.toString()) + } + if (periods.isEmpty()) periods = [null] + + // ------------------- + // Geometry machinery + // ------------------- + GeometryFactory gf = new GeometryFactory(new PrecisionModel(), srid) + double eps = 1e-9 + + // Interpolate point on edge + def interpPoint = { Coordinate a, Coordinate b, double va, double vb, double cLevel -> + double dv = (vb - va) + if (Math.abs(dv) < eps) return null + double t = (cLevel - va) / dv + if (t < -eps || t > 1 + eps) return null + if (t < 0) t = 0 + if (t > 1) t = 1 + new Coordinate(a.x + t * (b.x - a.x), a.y + t * (b.y - a.y)) + } + + // Load triangles to memory + List triRows = [] + sql.eachRow("SELECT \"PK\", \"PK_1\", \"PK_2\", \"PK_3\" FROM \"" + trianglesTable + "\"") { r -> + triRows.add([PK: r.PK as Integer, A: r.PK_1 as Integer, B: r.PK_2 as Integer, C: r.PK_3 as Integer]) + } + + // Insert batch for segments + String insSegSQL = "INSERT INTO " + segTable + "(PERIOD, LEVEL, THE_GEOM) VALUES (?, ?, ?)" + + // ------------------- + // Build segments by PERIOD & LEVEL + // ------------------- + periods.each { periodVal -> + // Map: receiver id -> (coord, val) + Map recMap = [:] + String sqlRec = (periodVal == null) ? + "SELECT IDRECEIVER, THE_GEOM, " + fieldName + " AS VAL FROM " + receiversTable : + "SELECT IDRECEIVER, THE_GEOM, " + fieldName + " AS VAL FROM " + receiversTable + " WHERE PERIOD = ?" + + if (periodVal == null) { + sql.eachRow(sqlRec) { r -> + Point pt = r.THE_GEOM as Point + if (pt != null) recMap[r.IDRECEIVER as Integer] = [coord: pt.coordinate, val: (r.VAL as Double)] + } + } else { + sql.eachRow(sqlRec, [periodVal]) { r -> + Point pt = r.THE_GEOM as Point + if (pt != null) recMap[r.IDRECEIVER as Integer] = [coord: pt.coordinate, val: (r.VAL as Double)] + } + } + + if (recMap.isEmpty()) return + + sql.withBatch(5000, insSegSQL) { ps -> + triRows.each { trow -> + def rA = recMap[trow.A]; def rB = recMap[trow.B]; def rC = recMap[trow.C] + if (rA == null || rB == null || rC == null) return + + Coordinate A = rA.coord as Coordinate + Coordinate B = rB.coord as Coordinate + Coordinate C = rC.coord as Coordinate + double vA = (rA.val as Double) + double vB = (rB.val as Double) + double vC = (rC.val as Double) + + levels.each { L -> + List hits = [] + + // AB + if ((L > Math.min(vA, vB) - eps) && (L < Math.max(vA, vB) + eps) && Math.abs(vA - vB) > eps) { + def p = interpPoint(A, B, vA, vB, L); if (p != null) hits << p + } else if (Math.abs(vA - L) <= eps && Math.abs(vA - vB) > eps) { + hits << A + } else if (Math.abs(vB - L) <= eps && Math.abs(vA - vB) > eps) { + hits << B + } + // BC + if ((L > Math.min(vB, vC) - eps) && (L < Math.max(vB, vC) + eps) && Math.abs(vB - vC) > eps) { + def p = interpPoint(B, C, vB, vC, L); if (p != null) hits << p + } else if (Math.abs(vB - L) <= eps && Math.abs(vB - vC) > eps) { + hits << B + } else if (Math.abs(vC - L) <= eps && Math.abs(vB - vC) > eps) { + hits << C + } + // CA + if ((L > Math.min(vC, vA) - eps) && (L < Math.max(vC, vA) + eps) && Math.abs(vC - vA) > eps) { + def p = interpPoint(C, A, vC, vA, L); if (p != null) hits << p + } else if (Math.abs(vC - L) <= eps && Math.abs(vC - vA) > eps) { + hits << C + } else if (Math.abs(vA - L) <= eps && Math.abs(vC - vA) > eps) { + hits << A + } + + // de-dup small numeric jitter + def uniq = [] + hits.each { h -> + if (h == null) return + def kx = Math.rint(h.x * 1e6) / 1e6 + def ky = Math.rint(h.y * 1e6) / 1e6 + if (!uniq.any { Math.abs(it.x - kx) < 1e-9 && Math.abs(it.y - ky) < 1e-9 }) { + uniq << new Coordinate(kx, ky) + } + } + + if (uniq.size() == 2) { + LineString ls = gf.createLineString([uniq[0], uniq[1]] as Coordinate[]) + ps.addBatch(periodVal, (L as Double), ls) + } + } // levels + } // triangles + } // batch + } // periods + + // ------------------- + // Stitch segments per (PERIOD, LEVEL) and insert to output + // (without using GROUP BY directly to avoid dialect quirks) + // ------------------- + List groups = [] + sql.eachRow("SELECT DISTINCT \"PERIOD\", \"LEVEL\" FROM \"" + segTable + "\"") { g -> + groups.add([p: g.PERIOD, l: (g.LEVEL as Double)]) + } + + String insMerged = + "INSERT INTO \"" + outTable + "\"(\"PERIOD\", \"LEVEL\", \"THE_GEOM\") " + + "SELECT ?, ?, ST_LineMerge(ST_Union(\"THE_GEOM\")) " + + "FROM \"" + segTable + "\" " + + "WHERE ((\"PERIOD\" IS NULL AND ? IS NULL) OR \"PERIOD\" = ?) " + + "AND \"LEVEL\" = ?" + + groups.each { g -> + sql.execute(insMerged, [g.p, g.l, g.p, g.p, g.l]) + } + + // ------------------- + // Cleanup + // ------------------- + sql.execute("DROP TABLE IF EXISTS \"" + segTable + "\"") + + // ------------------- + // Create a layer for each PERIOD from the output + // ------------------- + periods.findAll { it != null }.each { p -> + // Normalize table name: uppercase and only [A-Z0-9_] + String periodSafe = p.toString().toUpperCase().replaceAll('[^A-Z0-9_]', '_') + String perTable = "L" + periodSafe + "_ISOLINES_NOISE_MAP" + + // Drop + create destination table (without placeholders in DDL) + sql.execute("DROP TABLE IF EXISTS \"" + perTable + "\"") + sql.execute("""CREATE TABLE "${perTable}"( + "PERIOD" VARCHAR, + "LEVEL" DOUBLE, + "THE_GEOM" GEOMETRY + )""") + + // Insert only the rows of that PERIOD (here we can build the WHERE as a string) + String val = p.replace("'", "''") // escapar comillas simples + sql.execute("""INSERT INTO "${perTable}"("PERIOD","LEVEL","THE_GEOM") + SELECT "PERIOD","LEVEL","THE_GEOM" + FROM "${outTable}" + WHERE "PERIOD" = '${val}'""") + + // Spatial index + sql.execute("CREATE SPATIAL INDEX ON \"" + perTable + "\"(\"THE_GEOM\")") + } + + // ------------------- + // Print results + // ------------------- + List periodTables = periods.findAll { it != null } + .collect { "L" + it.toString().toUpperCase().replaceAll("[^A-Z0-9_]", "_") + "_ISOLINES_NOISE_MAP" } + + if (periodTables.isEmpty()) { + resultString = "Isolines created in " + outTable + " for " + levels.size() + " levels. No PERIOD values found, so no per-period tables were created." + } else { + resultString = "Isolines created in " + outTable + " for " + levels.size() + " levels and " + + periodTables.size() + " periods: " + periodTables.join(", ") + } + + logger.info('Result : ' + resultString) + logger.info('End : Create Isolines') + + // send resultString to WPS Builder + return resultString +} diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/Create_Isosurface.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/Create_Isosurface.groovy similarity index 62% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/Create_Isosurface.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/Create_Isosurface.groovy index bb96ddb57..b14da1598 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/Create_Isosurface.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/Create_Isosurface.groovy @@ -15,92 +15,77 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ +package org.noise_planet.noisemodelling.scripts.Acoustic_Tools -package org.noise_planet.noisemodelling.wps.Acoustic_Tools - -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore +import org.h2gis.api.ProgressVisitor import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.TableLocation import org.h2gis.utilities.wrapper.ConnectionWrapper import org.noise_planet.noisemodelling.jdbc.utils.IsoSurface +import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection title = 'Create isosurfaces from a NoiseModelling resulting table and its associated TRIANGLES table.' description = '➡️ Create isosurfaces from a NoiseModelling resulting table and its associated TRIANGLES table.'+ '
' + - '🚨 The triangle table must have been created using the WPS block "Receivers/Delaunay_Grid".

' + + '🚨 The triangle table must have been created using the "Receivers/Delaunay_Grid" WPS block.

' + '✅ The output table is called CONTOURING_NOISE_MAP

' + - 'Create isosurfaces' + 'Create isosurfaces' inputs = [ resultTable : [ name : 'Sound levels table', title : 'Sound levels table', - description: 'Name of the sound levels table, generated from "Noise_level_from_source". (STRING)

' + - 'Example : RECEIVERS_LEVEL.', + description: 'Name of the sound levels table, generated from the "Noise_level_from_source" WPS block. (STRING)

' + + 'Example : RECEIVERS_LEVEL', type : String.class ], isoClass : [ name : 'Iso levels in dB', title : 'Iso levels in dB', - description: 'Separation of sound levels for isosurfaces. First range is from -∞ to first value excluded. The first value included to next value excluded..

' + - 'Read this documentation for more information about sound levels classes.

' + - '🛠 Default value: 35.0,40.0,45.0,50.0,55.0,60.0,65.0,70.0,75.0,80.0,200.0 ', - min : 0, max: 1, + description: 'Separation of sound levels for isosurfaces. The first range is from -∞ to the first value (excluded). The next range is from the first value (included) to the next value (excluded).

' + + 'Read this documentation for more information about sound levels classes.', + default : "35.0,40.0,45.0,50.0,55.0,60.0,65.0,70.0,75.0,80.0,200.0", type : String.class ], resultTableField : [ name : 'Field of result table', title : 'Field of result table', - description: 'Field to read in the result table to make the iso surface; Default value: LAEQ', - min : 0, max: 1, + description: 'Field to read in the result table to make the iso surface.', + default : 'LAEQ', type : String.class ], keepTriangles: [ name : 'Keep triangles', title : 'Keep triangles', description: 'Point inside areas with the same iso levels are kept so elevation variation into ' + - 'same iso level areas will be preserved but the output data size will be higher.', - min : 0, max: 1, + 'same iso level areas will be preserved but the output data size will be higher. Keeping triangles will reduce significantly the computation time.', + default : false, type : Boolean.class ], smoothCoefficient: [ name : 'Polygon smoothing coefficient', title : 'Polygon smoothing coefficient', - description: 'This coefficient (Bezier curve coefficient) will smooth the generated isosurfaces.

'+ - 'If equal to 0, it disables the smoothing step and will keep the altitude of receivers (3D geojson can be viewed on https://kepler.gl).

' + - '🛠 Default value: 0.5 ', - min : 0, max: 1, - type : Double.class - ] + description: 'This coefficient (Bezier curve coefficient) will smooth the generated isosurfaces.

' + + 'If equal to 0, it disables the smoothing step and will keep the altitude of final polygons (3D geojson can be viewed on https://kepler.gl).' + + 'Use this option with keepTriangles to keep the altitude variation into same iso level areas.', + default : 0, + type : Double.class] ] outputs = [ result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', + name : 'Output table', + title : 'Output table', + description: 'Name of the output table containing the isosurfaces. The table is created in the same schema as the input result table. (STRING)', type : String.class ] ] - -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -def exec(Connection connection, Map input) { +def exec(Connection connection, Map input, ProgressVisitor progressVisitor) { //Need to change the ConnectionWrapper to WpsConnectionWrapper to work under postGIS database connection = new ConnectionWrapper(connection) @@ -121,7 +106,7 @@ def exec(Connection connection, Map input) { isoLevels = new ArrayList<>() StringTokenizer st = new StringTokenizer(input['isoClass'] as String, ",") while (st.hasMoreTokens()) { - isoLevels.add(Double.parseDouble(st.nextToken())) + isoLevels.add(Double.parseDouble(st.nextToken().trim())) } } @@ -138,22 +123,17 @@ def exec(Connection connection, Map input) { if(input.containsKey("keepTriangles")) { isoSurface.setMergeTriangles(!(input['keepTriangles'] as Boolean)) - } - - if (input.containsKey("smoothCoefficient")) { - double coefficient = input['smoothCoefficient'] as Double - if (coefficient < 0.01) { - isoSurface.setSmooth(false) - } else { - isoSurface.setSmooth(true) - isoSurface.setSmoothCoefficient(coefficient) - } } - else { + double coefficient = input.getOrDefault("smoothCoefficient", 0.0) as Double + if(coefficient < 0.01) { + isoSurface.setSmooth(false) + } else { isoSurface.setSmooth(true) - isoSurface.setSmoothCoefficient(0.5) + isoSurface.setSmoothCoefficient(coefficient) } + isoSurface.setProgressVisitor(progressVisitor) + isoSurface.createTable(connection, "IDRECEIVER") resultString = "Table " + isoSurface.getOutputTable() + " created" @@ -162,20 +142,9 @@ def exec(Connection connection, Map input) { logger.info(resultString) // print to WPS Builder - return resultString + return [result: isoSurface.getOutputTable()] } - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } +def exec(Connection connection, Map input) { + return exec(connection, input, new RootProgressVisitor(1, true, 5)) } diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/DynamicIndicators.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/DynamicIndicators.groovy similarity index 71% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/DynamicIndicators.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/DynamicIndicators.groovy index 4e203d79d..84c495e42 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Acoustic_Tools/DynamicIndicators.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Acoustic_Tools/DynamicIndicators.groovy @@ -14,38 +14,38 @@ * @Author Pierre Aumond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Acoustic_Tools +package org.noise_planet.noisemodelling.scripts.Acoustic_Tools + + -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore + import org.slf4j.Logger import org.slf4j.LoggerFactory import java.sql.Connection title = 'Compute dynamic indicators' -description = 'Compute dynamic indicators as L10, L90
The columns of the table should be named HZ63, HZ125,..., HZ8000 with an HZ prefix that can be changed.' +description = 'Computes dynamic percentile indicators (L10, L50, L90) for each row in the table' inputs = [ columnName : [ name : 'Column name', title : 'Column name', - description: 'Column name on which to perform the calculation. (STRING)
For example : LEQA', + description: 'Column name on which to perform the calculation. (STRING)
For example : LEAQ', type : String.class ], tableName: [ title : 'Name of the table', name : 'Name of the table', - description: 'Name of the table on which to perform the calculation. The table must contain multiple sound level values for a single receiver. (STRING)
For example : RECEIVERS_LEVEL', + description: 'Name of the table on which to perform the calculation. The table must contain multiple sound level values for a single receiver. The columns of the table should be named HZ63, HZ125,..., HZ8000 with an HZ prefix that can be changed. (STRING)
For example : RECEIVERS_LEVEL', type : String.class ], outputTableName: [ title : 'Name of the output table', name : 'Name of the output table', - description: 'Name of the output table default to tableName+_DYN_IND', - min : 0, max: 1, + description: 'Name of the output table', + default : 'tableName_DYN_IND', type : String.class, ] ] @@ -60,15 +60,6 @@ outputs = [ ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - def exec(Connection connection, Map input) { // output string, the information given back to the user @@ -117,17 +108,3 @@ def exec(Connection connection, Map input) { return resultString } - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/All_Possible_Configuration.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/All_Possible_Configuration.groovy similarity index 77% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/All_Possible_Configuration.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/All_Possible_Configuration.groovy index 7c30441fb..f0fd1f419 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/All_Possible_Configuration.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/All_Possible_Configuration.groovy @@ -1,26 +1,38 @@ -package org.noise_planet.noisemodelling.wps.Data_Assimilation +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + +/** + * @Author DIAGNE Ndeye-Maguette, Université Gustave Eiffel + */ + +package org.noise_planet.noisemodelling.scripts.Data_Assimilation -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.BatchingPreparedStatementWrapper import groovy.sql.BatchingStatementWrapper import groovy.sql.Sql import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.wrapper.ConnectionWrapper import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection -// ----------------- WPS Metadata ------------------ -title = 'all configurations ' -description = 'process to generate all configurations.' + +title = 'All configurations' +description = 'Process to generate all configurations.' inputs = [ trafficValues: [ name: 'Traffic values', title: 'Traffic values', - description: 'list of variation values in % for traffic like [0.01,1.0, 2.0,3,4]', + description: 'List of variation values in % for traffic like [0.01,1.0, 2.0,3,4]', type: String.class ], temperatureValues : [ @@ -41,30 +53,6 @@ outputs = [ ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} @CompileStatic def exec(Connection connection,input) { @@ -98,7 +86,7 @@ def exec(Connection connection,input) { * The generated combinations include values for type of roads primary, secondary, tertiary, others, and temperature. * * The total number of combinations is calculated as: - * (number of `vals` elements) ^ (number of paramèters) * (number of `temps` elements). + * (number of `vals` elements) ^ (number of parameters) * (number of `temps` elements). * * The sql table follows the structure: * IT, PRIMARY, SECONDARY, TERTIARY, OTHERS, TEMP. diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Create_Assimilated_Maps.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Create_Assimilated_Maps.groovy similarity index 65% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Create_Assimilated_Maps.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Create_Assimilated_Maps.groovy index de6b6e52d..90235bcec 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Create_Assimilated_Maps.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Create_Assimilated_Maps.groovy @@ -10,22 +10,20 @@ * */ -package org.noise_planet.noisemodelling.wps.Data_Assimilation +/** + * @Author DIAGNE Ndeye-Maguette, Université Gustave Eiffel + */ + +package org.noise_planet.noisemodelling.scripts.Data_Assimilation import groovy.sql.Sql import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.JDBCUtilities -import geoserver.GeoServer -import geoserver.catalog.Store import org.h2gis.utilities.wrapper.ConnectionWrapper - import java.sql.Connection - title = 'Creation of the result table' -description = 'Creation of the result table.' - +description = 'Creates the ASSIMILATED_MAPS table by joining the best configuration table with the receivers noise levels.' inputs = [ bestConfigTable: [ name: 'The best configuration table', @@ -40,9 +38,9 @@ inputs = [ type: String.class ], outputTable: [ - name: 'The output table name', - title: 'The output table name', - description: 'The output table name', + name: 'The output table name', + title: 'The output table name', + description: 'The output table name', type: String.class ] ] @@ -55,16 +53,6 @@ outputs = [ ] ] -// Open Connection to Geoserver -Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - @CompileStatic def exec(Connection connection,inputs) { connection = new ConnectionWrapper(connection) @@ -75,8 +63,8 @@ def exec(Connection connection,inputs) { Sql sql = new Sql(connection) // Add Timestamp to the NMs sql.execute("DROP TABLE "+outputTable+" IF EXISTS;") - sql.execute("CREATE TABLE "+outputTable+" AS SELECT b.EPOCH TIMESTAMP, a.LAEQ, a.THE_GEOM, a.IDRECEIVER FROM "+bestConfigTable+" b LEFT JOIN "+receiverLevel+" a ON a.PERIOD = b.IT ; ") - sql.execute("ALTER TABLE "+outputTable+" ALTER COLUMN TIMESTAMP SET DATA TYPE INTEGER") + sql.execute("CREATE TABLE "+outputTable+" AS SELECT b.EPOCH TIMESTAMP, a.LAEQ, a.THE_GEOM, a.IDRECEIVER FROM "+bestConfigTable+" b LEFT JOIN "+receiverLevel+" a ON a.PERIOD = b.IT;") + sql.execute("ALTER TABLE "+outputTable+" ALTER COLUMN TIMESTAMP SET DATA TYPE INTEGER;") def columnNames = JDBCUtilities.getColumnNames(connection, outputTable) @@ -85,18 +73,3 @@ def exec(Connection connection,inputs) { return "Calculation Done ! The table "+outputTable+" has been created." } - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Data_Simulation.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Data_Simulation.groovy similarity index 86% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Data_Simulation.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Data_Simulation.groovy index 261e78128..171d711a2 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Data_Simulation.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Data_Simulation.groovy @@ -10,12 +10,13 @@ * */ -package org.noise_planet.noisemodelling.wps.Data_Assimilation +/** + * @Author DIAGNE Ndeye-Maguette, Université Gustave Eiffel + */ + +package org.noise_planet.noisemodelling.scripts.Data_Assimilation -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.SpatialResultSet import org.h2gis.utilities.wrapper.ConnectionWrapper import org.noise_planet.noisemodelling.emission.road.cnossos.RoadCnossos @@ -24,19 +25,18 @@ import org.noise_planet.noisemodelling.pathfinder.profilebuilder.ProfileBuilder import org.noise_planet.noisemodelling.pathfinder.utils.AcousticIndicatorsFunctions import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.PreparedStatement import java.sql.SQLException title = 'Data Simulation' -description = 'Method to execute a series of operations for generate noise maps' - +description = 'Method for performing a series of operations to generate noise maps' inputs = [ noiseMapLimit: [ - name: 'Number of map ', + name: 'Number of map', title: 'Number of map', - description: 'The optional parameter limits the number of maps to be generated', + description: 'The optional parameter between 1 and 100 corresponding to the percentage of number of maps relative to the maximal number of combinations', + default: '100', type: Integer.class ] ] @@ -45,7 +45,7 @@ outputs = [ result: [ name: 'Noise map table ', title: 'Noise map table', - description: 'NOISE_MAPS table input', + description: 'LW_ROADS and ROADS_GEOM tables output', type: String.class ] ] @@ -80,7 +80,8 @@ def exec(Connection connection,input) { "HZ63 double precision, HZ125 double precision, HZ250 double precision, HZ500 double precision, HZ1000 double precision, HZ2000 double precision, HZ4000 double precision, HZ8000 double precision);") int size if (limit != null){ - size = limit + + size = (int) ((limit * allCombinations.size()) / 100) } else{ size = allCombinations.size() @@ -205,32 +206,6 @@ def exec(Connection connection,input) { } logger.info('End data simulation ') - return "Calculation Done ! The table LW_ROADS has been created." - -} + return "Calculation Done ! The table LW_ROADS and ROADS_GEOM has been created." - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection,input)] - } -} - -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() } diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Extract_Best_Configuration.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Extract_Best_Configuration.groovy similarity index 84% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Extract_Best_Configuration.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Extract_Best_Configuration.groovy index c1e938fc3..c78388c6b 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Extract_Best_Configuration.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Extract_Best_Configuration.groovy @@ -10,42 +10,41 @@ * */ -package org.noise_planet.noisemodelling.wps.Data_Assimilation +/** + * @Author DIAGNE Ndeye-Maguette, Université Gustave Eiffel + */ + +package org.noise_planet.noisemodelling.scripts.Data_Assimilation -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.SpatialResultSet import org.h2gis.utilities.wrapper.ConnectionWrapper import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.PreparedStatement title = 'Extraction of the best configurations' description = 'Extraction of the best maps, i.e. those that minimise the difference between the measured and simulated values, by calculating the minimum median values. ' - inputs = [ observationTable: [ name: 'Sensors measurement training table', title: 'Measurement table', - description: 'table of observationSensor containing the training data Set', + description: 'Table of "observationSensor" containing the training data Set', type: String.class ], noiseMapTable: [ name: 'Noise map table', title: 'Noise map table', - description: 'table of noiseMapTable containing the noise maps after simulation', + description: 'Table of "noiseMapTable" containing the noise maps after simulation', type: String.class ], tempToleranceThreshold: [ - name: 'temperature tolerance threshold ', - title: 'temperature tolerance threshold ', - description: 'temperature tolerance threshold pour extraire la best configuration', + name: 'Temperature tolerance threshold', + title: 'Temperature tolerance threshold', + description: 'Temperature tolerance threshold used to filter and extract the best configurations', type: Double.class ] ] @@ -202,27 +201,3 @@ static def exec(Connection connection, input){ return "Calculation Done ! The table BEST_CONFIGURATION_FULL has been created." } -// run the script -static def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Merged_Sensors_Receivers.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Merged_Sensors_Receivers.groovy similarity index 64% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Merged_Sensors_Receivers.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Merged_Sensors_Receivers.groovy index df5c6520c..5641771a2 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Merged_Sensors_Receivers.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Merged_Sensors_Receivers.groovy @@ -10,21 +10,19 @@ * */ -package org.noise_planet.noisemodelling.wps.Data_Assimilation +/** + * @Author DIAGNE Ndeye-Maguette, Université Gustave Eiffel + */ + +package org.noise_planet.noisemodelling.scripts.Data_Assimilation -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.wrapper.ConnectionWrapper - import java.sql.Connection - title = 'Merged Sensors and Receivers' -description = 'Adding the sensors into the RECEIVERS after creating a regular grid of receivers.' - +description = 'Merges sensor locations into an existing RECEIVERS table previously created with a regular grid.' inputs = [ tableReceivers: [ name: 'The receiver table', @@ -35,7 +33,7 @@ inputs = [ tableSensors: [ name: 'The Sensors table', title: 'The Sensors table', - description: 'The Sensors table ', + description: 'The Sensors table', type: String.class ] ] @@ -65,27 +63,3 @@ static def exec(Connection connection,inputs) { return "Calculation Done ! The tables " + receiverTable + " and "+tableSensors +" have been merged." } -// run the script -static def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/NMs_4_BestConfigs.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/NMs_4_BestConfigs.groovy similarity index 72% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/NMs_4_BestConfigs.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/NMs_4_BestConfigs.groovy index edc2293a8..bca4af70b 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/NMs_4_BestConfigs.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/NMs_4_BestConfigs.groovy @@ -10,17 +10,17 @@ * */ -package org.noise_planet.noisemodelling.wps.Data_Assimilation +/** + * @Author DIAGNE Ndeye-Maguette, Université Gustave Eiffel + */ + +package org.noise_planet.noisemodelling.scripts.Data_Assimilation -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.wrapper.ConnectionWrapper import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection title = 'Dynamic Road Traffic Emission' @@ -68,28 +68,3 @@ static def exec(Connection connection,inputs){ logger.info('End Traffic calibration') return "Calculation Done ! The table LW_ROADS_best has been created." } - -// run the script -static def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Prepare_Sensors.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Prepare_Sensors.groovy similarity index 86% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Prepare_Sensors.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Prepare_Sensors.groovy index 0a2036a7d..02708a66f 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Data_Assimilation/Prepare_Sensors.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Data_Assimilation/Prepare_Sensors.groovy @@ -1,11 +1,24 @@ -package org.noise_planet.noisemodelling.wps.Data_Assimilation +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + +/** + * @Author DIAGNE Ndeye-Maguette, Université Gustave Eiffel + */ + +package org.noise_planet.noisemodelling.scripts.Data_Assimilation import com.opencsv.CSVReader -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.wrapper.ConnectionWrapper import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -20,39 +33,38 @@ import java.time.format.DateTimeParseException import java.util.concurrent.atomic.AtomicInteger title = 'Preparation of Sensor data' -description = 'Extraction of sensor data for a given period and creation of sql tables ' - +description = 'Extracts sensor data for a given period and creates SQL tables' inputs = [ startDate: [ name: 'Start Time Stamp', title: 'Start Time Stamp', - description: 'the start timestamp to extract the dataset in format "%Y-%m-%d %H:%M:%S" ', + description: 'The start timestamp to extract the dataset in format "%Y-%m-%d %H:%M:%S"', type: String.class ], endDate: [ name: 'End Time Stamp', title: 'End Time Stamp', - description: 'the end timestamp to extract the dataset in format "%Y-%m-%d %H:%M:%S" ', + description: 'The end timestamp to extract the dataset in format "%Y-%m-%d %H:%M:%S"', type: String.class ], trainingRatio: [ name: 'Training data percentage', title: 'Training data percentage', - description: 'Training data as a percentage of total data ', + description: 'Training data as a percentage of total data', type: Float.class ], workingFolder: [ name: 'Input folder path', title: 'Working directory path with input files', - description: 'Folder containing csv files "device_mapping_sf", the osm file and the folder "devices_data"', + description: 'Folder containing .csv files "device_mapping_sf", the .osm file and the folder "devices_data"', type: String.class ], targetSRID : [ name : 'Target projection identifier', title : 'Target projection identifier', description: '🌍 Target projection identifier (also called SRID) of your table.
' + - 'It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Web Mercator projection).

' + - '🚨 The target SRID must be in metric coordinates example 2056 for Geneva.', + 'It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Web Mercator projection).

' + + '🚨 The target SRID must be in metric coordinates (e.g 2056 for Geneva).', type : Integer.class ] ] @@ -136,31 +148,6 @@ static def exec(Connection connection,input){ return "Calculation Done ! The tables SENSORS_MEASUREMENTS, SENSORS_LOCATION and SENSORS_MEASUREMENTS_TRAINING have been created." - -} - -static def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() } /** @@ -210,7 +197,6 @@ static def allMeasurements(LocalDateTime dayStart, LocalDateTime dayEnd, String } - /** * Extracts sensor data from the sensor measurements files for a given period dayStart -> dayEnd * @@ -338,6 +324,4 @@ static def extractObservationData(Connection connection,Float ratio) { } } - - } diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Add_Primary_Key.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Add_Primary_Key.groovy similarity index 79% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Add_Primary_Key.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Add_Primary_Key.groovy index 262cbe259..a6818642f 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Add_Primary_Key.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Add_Primary_Key.groovy @@ -14,22 +14,18 @@ * @Author Pierre Aumond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Database_Manager +package org.noise_planet.noisemodelling.scripts.Database_Manager -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.ResultSet import java.sql.Statement title = 'Add primary key column or constraint' -description = '➡️ Add a Primary Key (🔑) column or add a Primary Key constraint to a column of a table.
' + +description = '➡️ Adds a Primary Key (🔑) column, or adds a Primary Key constraint to an existing column.
' + '
' + 'It is necessary to add a Primary Key on one of the columns for the source and receiver tables before doing a calculation.

' + '💡 If the table already has a Primary Key, it will remove the constraint before the operation.' @@ -38,7 +34,7 @@ inputs = [ pkName: [ name: 'Name of the column', title: 'Name of the column', - description: 'Name of the column to be added, or for which the main key constraint will be added.

'+ + description: 'Name of the column to be added, or for which the main key constraint will be added.

'+ '💡 Primary keys must contain UNIQUE values, and cannot contain NULL values', type: String.class ], @@ -59,16 +55,6 @@ outputs = [ ] ] - -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - def exec(Connection connection, input) { // output string, the information given back to the user @@ -124,17 +110,3 @@ def exec(Connection connection, input) { return resultString } - -// run the script -def run(input) { - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Clean_Database.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Clean_Database.groovy similarity index 76% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Clean_Database.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Clean_Database.groovy index acb154f72..acfc11493 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Clean_Database.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Clean_Database.groovy @@ -15,26 +15,22 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Database_Manager +package org.noise_planet.noisemodelling.scripts.Database_Manager -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.Statement title = 'Delete all database tables' -description = '➡️ Delete all non-system tables of the database.

'+ +description = '➡️ Delete all non-system tables of the database.

'+ '🚨 Use with caution' inputs = [ areYouSure: [ - name: 'Are you sure ?', + name: 'Are you sure?', title: 'Are you sure?', description: 'Are you sure you want to delete all the tables in the database?', type: Boolean.class @@ -50,15 +46,6 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - def exec(Connection connection, input) { // output string, the information given back to the user @@ -112,17 +99,3 @@ def exec(Connection connection, input) { return resultString } - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Display_Database.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Display_Database.groovy similarity index 62% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Display_Database.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Display_Database.groovy index 0cf4f77c6..6801e07db 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Display_Database.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Display_Database.groovy @@ -14,33 +14,32 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ +package org.noise_planet.noisemodelling.scripts.Database_Manager -package org.noise_planet.noisemodelling.wps.Database_Manager - -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore +import org.h2gis.api.ProgressVisitor +import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation +import org.h2gis.utilities.dbtypes.DBTypes +import org.h2gis.utilities.dbtypes.DBUtils import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection title = 'Display the list of tables (and their attributes).' description = '➡️ Displays the list of tables that are in the database.
' + - '
' + - 'Optionally it is also possible to display their attributes ("showColumns" parameter).

' + - '💡 To visualize the content of (a part of) a table, you can use "Table Visualization Data" script.' + '
' + + 'Optionally it is also possible to display their attributes ("showColumns" parameter).

' + + '💡 To visualize the content of (a part of) a table, you can use "Table Visualization Data" script.' inputs = [ showColumns: [ name : 'Display columns of the tables', title : 'Display columns of the tables', - description: 'Do you want to display also the column of the tables ?

' + + description: 'Would you also like to display the column name in the tables?

' + '💡 Note : A small yellow key symbol (🔑) will appear if the column as a Primary Key constraint.', - type : Boolean.class, - min : 0, max: 1 + default : true, + type : Boolean.class ] ] @@ -53,17 +52,7 @@ outputs = [ ] ] - -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -def exec(Connection connection, input) { +def exec(Connection connection, Map input) { // output string, the information given back to the user String resultString = null @@ -75,11 +64,7 @@ def exec(Connection connection, input) { logger.info('Start : Display database') logger.info("inputs {}", input) // log inputs of the run - Boolean showColumnName = false - - if(input['showColumns']) { - showColumnName = input['showColumns'].toBoolean() - } + Boolean showColumnName = input['showColumns'].toBoolean() // list of the system tables List ignorelst = ["SPATIAL_REF_SYS", "GEOMETRY_COLUMNS"] @@ -89,20 +74,31 @@ def exec(Connection connection, input) { // Get every table names List tables = JDBCUtilities.getTableNames(connection, null, "PUBLIC", "%", null) + DBTypes dbType = DBUtils.getDBType(connection) + // Loop over the tables tables.each { t -> - TableLocation tab = TableLocation.parse(t) + TableLocation tab = TableLocation.parse(t, dbType) if (!ignorelst.contains(tab.getTable())) { sb.append(tab.getTable()) sb.append("
") if (showColumnName) { List fields = JDBCUtilities.getColumnNames(connection, t) + def geometryColumnNames = GeometryTableUtilities.getGeometryColumnNames(connection, tab) Integer keyColumnIndex = JDBCUtilities.getIntegerPrimaryKey(connection, tab) int columnIndex = 1; fields.each { f -> if (columnIndex == keyColumnIndex) { sb.append(String.format("       %s 🔑
", f)) + } else if(geometryColumnNames.contains(f)) { + int epsg = 0; + try { + epsg = GeometryTableUtilities.getSRID(connection, tab) + } catch (Exception ex) { + //ignore + } + sb.append(String.format("       %s 🌐 (srid: %d)
", f, epsg)) } else { sb.append(String.format("       %s
", f)) } @@ -113,23 +109,16 @@ def exec(Connection connection, input) { } } + if(sb.length() == 0) { + sb.append('
') + sb.append('

🗄 Database is Empty

') + sb.append('

No tables found in the database.

') + sb.append('

Please import data using **Import_File** to get started.

') + sb.append('
') + } // print to command window logger.info('End : Display database') // print to WPS Builder return sb.toString() } - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Drop_a_Table.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Drop_a_Table.groovy similarity index 78% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Drop_a_Table.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Drop_a_Table.groovy index b469c98ee..611ab0ff0 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Drop_a_Table.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Drop_a_Table.groovy @@ -15,16 +15,12 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Database_Manager +package org.noise_planet.noisemodelling.scripts.Database_Manager -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.Statement @@ -50,14 +46,7 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} + def exec(Connection connection, input) { // output string, the information given back to the user @@ -112,18 +101,3 @@ def exec(Connection connection, input) { // print to WPS Builder return resultString } - - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Table_Visualization_Data.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Table_Visualization_Data.groovy new file mode 100644 index 000000000..4ea59e16d --- /dev/null +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Table_Visualization_Data.groovy @@ -0,0 +1,217 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + +/** + * @Author Pierre Aumond, Université Gustave Eiffel + * @Author Nicolas Fortin, Université Gustave Eiffel + */ + + +package org.noise_planet.noisemodelling.scripts.Database_Manager + +import groovy.sql.Sql +import org.h2gis.utilities.JDBCUtilities +import org.h2gis.utilities.GeometryTableUtilities +import org.h2gis.utilities.TableLocation +import org.locationtech.jts.geom.Geometry +import org.locationtech.jts.io.WKTWriter +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.sql.Connection +import java.sql.Statement + + +title = 'Display first rows of a query result.' +description = '➡️ Display the content of a SQL query result.
' + + '
' + + 'You can provide either a table name or a complete SELECT SQL query.
' + + 'Using "linesNumber" parameter, you can choose the number of lines to display

' + + '🚨 Be careful, this treatment can be very long if the query returns many rows.' + +inputs = [linesNumber: [name : 'Number of rows', + title : 'Number of rows', + description: 'Number of rows you want to display. This parameter is ignored if your SQL query already contains a LIMIT clause.', + default : 10, + type : Integer.class], + tableName : [name : 'Table name', + title : 'Table name', + description: 'Table name or SQL SELECT query (e.g., mytable or SELECT * FROM mytable)', + type : String.class]] + +outputs = [ + result: [ + name : 'Result output string', + title : 'Result output string', + description: 'This type of result does not allow the blocks to be linked together.', + type : String.class + ] +] + +def exec(Connection connection, input) { + + // Create a logger to display messages in the geoserver logs and in the command prompt. + Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") + + // print to command window + logger.info('Start : Display first rows of a query result') + logger.info("inputs {}", input) // log inputs of the run + + // Get the number of rows the user want to display + int linesNumber = 10 + if (input['linesNumber']) { + linesNumber = input['linesNumber'] as Integer + } + + // Get SQL query or table name + String sqlQuery = input["tableName"] as String + + // Create a connection statement to interact with the database in SQL + Sql sql = new Sql(connection) + + List output + String finalQuery + boolean isTableName = !sqlQuery.toUpperCase().trim().startsWith("SELECT ") + + if (isTableName) { + // If the input is a table name, create a SELECT query + Statement statement = connection.createStatement() + finalQuery = String.format("SELECT * FROM %s", statement.enquoteIdentifier(sqlQuery, false)) + } else { + // If the input is already a SQL query, use it as is + // Additional validation: prevent common SQL injection patterns + def upperQuery = sqlQuery.toUpperCase() + if (upperQuery.contains(" DROP ") || upperQuery.contains(" DELETE ") || + upperQuery.contains(" UPDATE ") || upperQuery.contains(" INSERT ") || + upperQuery.contains(" ALTER ") || upperQuery.contains(" CREATE ") || + upperQuery.contains(" TRUNCATE ")) { + throw new IllegalArgumentException("Query contains forbidden SQL keywords") + } + finalQuery = sqlQuery + } + + // Add LIMIT clause if not already present + if (!finalQuery.toUpperCase().contains("LIMIT")) { + finalQuery += String.format(" LIMIT %s", linesNumber.toString()) + } + + output = sql.rows(finalQuery) + + // Check if the query returned any result + if (output.isEmpty()) { + logger.info("The query did not return any result.") + return "The query did not return any result." + } + + logger.info('End : Display first rows of a query result') + + + // print to WPS Builder + return mapToTable(output, sql, sqlQuery, connection, isTableName) +} + + +/** + * Convert a list to HTML table + * @param list + * @param isTableName true if the query was a simple table name, false if it was a custom SQL query + * @return + */ +static String mapToTable(List list, Sql sql, String queryOrTableName, Connection connection, boolean isTableName) { + + StringBuilder output = new StringBuilder() + + Map first = list.first() + + if (isTableName) { + // Only show total count and metadata for table names + try { + output.append("The total number of rows is " + sql.firstRow('SELECT COUNT(*) FROM ' + queryOrTableName.toUpperCase())[0]) + } catch (Exception e) { + output.append("Unable to determine total row count for this query") + } + + //get SRID of the table + try { + int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(queryOrTableName)) + + if (srid > 0) { + output.append("
") + output.append("The srid of the table is " + srid) + } else { + output.append("
") + output.append("This table doesn't have any srid") + } + } catch (Exception e) { + output.append("
") + output.append("Unable to determine SRID information") + } + + //get primary key of the table + try { + int pkIndex = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(queryOrTableName)) + + if (pkIndex > 0) { + output.append("
") + output.append("The table has the following primary key : " + JDBCUtilities.getColumnName(connection, queryOrTableName, pkIndex)) + } else { + output.append("
") + output.append("This table does not have primary key.") + } + } catch (Exception e) { + output.append("
") + output.append("Unable to determine primary key information") + } + + output.append("

") + } else { + output.append("SQL Query: " + queryOrTableName + "
") + output.append("Showing first " + list.size() + " rows

") + } + + // Add CSS styling for table cells with scroll support + output.append("") + + output.append("") + + first.each { key, val -> + output.append("") + } + + output.append("") + WKTWriter wktWriter = new WKTWriter(3) + list.each { map -> + if (map.size() > 0) { + + def values = map.values() + + output.append("") + + values.each { + def val = it + if (it instanceof Geometry) { + val = wktWriter.write(it) + } + output.append "" + } + + output.append("") + } + } + output.append("
${key}
${val}
") + + output.toString() +} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Table_Visualization_Map.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Table_Visualization_Map.groovy similarity index 65% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Table_Visualization_Map.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Table_Visualization_Map.groovy index 3d40c9bbd..a377fb48d 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Table_Visualization_Map.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Database_Manager/Table_Visualization_Map.groovy @@ -16,30 +16,27 @@ */ -package org.noise_planet.noisemodelling.wps.Database_Manager +package org.noise_planet.noisemodelling.scripts.Database_Manager -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore -import org.h2gis.utilities.GeometryMetaData import org.h2gis.utilities.GeometryTableUtilities -import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation +import org.h2gis.utilities.dbtypes.DBTypes import org.h2gis.utilities.dbtypes.DBUtils import org.locationtech.jts.geom.Geometry import org.locationtech.jts.io.WKTWriter import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.ResultSet import java.sql.Statement -title = 'Diplay a table on a map.' +title = 'Display a table on a map.' description = '➡️ Display a table containing a geometric column on a map 🗺
'+ - '
' + - 'Technically, it groups all the geometries of a table and returns them in WKT OGC format.

'+ - '🚨 Be careful, this treatment can be blocked if the table is too large.' + '
' + + 'Technically, it groups all the geometries of a table and returns them in WKT OGC format.

'+ + '🚨 Be careful, this treatment can be blocked if the table is too large.' + +executionTimeout = 120 // For synchronous WPS, it will wait this time before returning a message, but it will still run the execution in the background inputs = [ inputSRID: [ @@ -47,8 +44,7 @@ inputs = [ title : 'Projection identifier', description: '🌍 Original projection identifier (also called SRID) of your table. It should be an EPSG code, a integer with 4 or 5 digits (ex: 3857 is Web Mercator projection). (INTEGER)

' + 'All coordinates will be projected from the specified EPSG to WGS84 coordinates.

' + - 'This entry is optional because many formats already include the projection and you can also import files without geometry attributes.

' + - '🛠 Default value: 4326 ', + 'This entry is optional because many formats already include the projection and you can also import files without geometry attributes.', type : Integer.class, min : 0, max: 1 ], @@ -69,16 +65,7 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -def exec(Connection connection, input) { +def exec(Connection connection, Map input) { // output geometry, the information given back to the user Geometry geom = null @@ -104,9 +91,10 @@ def exec(Connection connection, input) { if (input['inputSRID']) { srid = input['inputSRID'] as Integer } + DBTypes dbType = DBUtils.getDBType(connection) // Read Geometry Index and type of the table - List spatialFieldNames = GeometryTableUtilities.getGeometryColumnNames(connection, TableLocation.parse(tableName, DBUtils.getDBType(connection))) + List spatialFieldNames = GeometryTableUtilities.getGeometryColumnNames(connection, TableLocation.parse(tableName, dbType)) // If the table does not contain a geometry field if (spatialFieldNames.isEmpty()) { @@ -114,7 +102,7 @@ def exec(Connection connection, input) { } // Get the SRID of the table - Integer tableSrid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(tableName)) + Integer tableSrid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(tableName, dbType)) if (tableSrid != 0 && tableSrid != srid && input['inputSRID']) throw new Exception("The table already has a different SRID than the one you gave.") @@ -124,15 +112,8 @@ def exec(Connection connection, input) { // Display the actual SRID in the command window logger.info("The actual SRID of the table is " + srid) - if (tableSrid == 0) { - GeometryMetaData metaData = GeometryTableUtilities.getMetaData(connection, TableLocation.parse(tableName, DBUtils.getDBType(connection)), spatialFieldNames.get(0)); - metaData.setSRID(srid); - connection.createStatement().execute(String.format("ALTER TABLE %s ALTER COLUMN %s %s USING ST_SetSRID(%s,%d)", - TableLocation.parse(tableName, DBUtils.getDBType(connection)), spatialFieldNames.get(0), metaData.getSQL(), spatialFieldNames.get(0),spatialFieldNames.get(0) ,srid)) - } - // Project geometry in WGS84 (EPSG:4326) and groups all the geometries of the table - String geomField = "ST_ACCUM(ST_TRANSFORM(" + spatialFieldNames.get(0) + " ,4326))" + String geomField = "ST_ACCUM(ST_TRANSFORM(" + TableLocation.quoteIdentifier(spatialFieldNames.get(0)) + " ,4326))" ResultSet rs = stmt.executeQuery(String.format("select %s " + spatialFieldNames.get(0) + " from %s", geomField, tableName)) // Get the geometry field from the table @@ -141,10 +122,11 @@ def exec(Connection connection, input) { } // print to command window - if (asWKT(geom).size() > 100) { - logger.info('Result (100 first characters) : ' + asWKT(geom).substring(0, 100) + '...') + String wkt = asWKT(geom) + if (wkt.size() > 100) { + logger.info('Result (100 first characters) : ' + wkt.substring(0, 100) + '...') } else { - logger.info('Result : ' + asWKT(geom)) + logger.info('Result : ' + wkt) } logger.info('End : Display a table on a map') @@ -154,20 +136,6 @@ def exec(Connection connection, input) { } -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - /** * Convert a Geometry value into a Well Known Text value. * @param geometry Geometry instance diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Noise_level_from_traffic.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Deprecated/Noise_level_from_traffic.groovy similarity index 76% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Noise_level_from_traffic.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Deprecated/Noise_level_from_traffic.groovy index fb1a8d0bf..685b1bb67 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Noise_level_from_traffic.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Deprecated/Noise_level_from_traffic.groovy @@ -14,12 +14,11 @@ * @Author Pierre Aumond, Université Gustave Eiffel * @Author Nicolas Fortin, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.NoiseModelling +package org.noise_planet.noisemodelling.scripts.Deprecated -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore +import org.h2gis.api.EmptyProgressVisitor +import org.h2gis.api.ProgressVisitor import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation @@ -29,7 +28,7 @@ import org.h2gis.utilities.wrapper.ConnectionWrapper import org.noise_planet.noisemodelling.jdbc.NoiseMapByReceiverMaker import org.noise_planet.noisemodelling.jdbc.NoiseMapDatabaseParameters import org.noise_planet.noisemodelling.jdbc.input.DefaultTableLoader -import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor +import org.noise_planet.noisemodelling.jdbc.utils.DataBaseUtilities import org.noise_planet.noisemodelling.propagation.AttenuationParameters import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -55,9 +54,9 @@ inputs = [ name : 'Buildings table name', title : 'Buildings table name', description: '🏠 Name of the Buildings table

' + - 'The table must contain:
    ' + - '
  • THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON)
  • ' + - '
  • HEIGHT : the height of the building (FLOAT)
', + 'The table must contain:
    ' + + '
  • THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON)
  • ' + + '
  • HEIGHT : the height of the building (FLOAT)
', type : String.class ], tableRoads : [ @@ -73,7 +72,8 @@ inputs = [ '
  • WBV_D WBV_E WBV_N : Hourly average motorcycles, tricycles or quads > 50 cc count (6-18h)(18-22h)(22-6h) (DOUBLE)
  • ' + '
  • LV_SPD_D LV_SPD_E LV_SPD_N : Hourly average light vehicle speed (6-18h)(18-22h)(22-6h) (DOUBLE)
  • ' + '
  • MV_SPD_D MV_SPD_E MV_SPD_N : Hourly average medium heavy vehicles speed (6-18h)(18-22h)(22-6h) (DOUBLE)
  • ' + - '
  • HGV_SPD_D HGV_SPD_E HGV_SPD_N : Hourly average heavy duty vehicles speed (6-18h)(18-22h)(22-6h) (DOUBLE)
  • ' + + '
  • HGV_SPD_D HGV_SPD_E HGV_SPD_N : Hourly ave' + + 'rage heavy duty vehicles speed (6-18h)(18-22h)(22-6h) (DOUBLE)
  • ' + '
  • WAV_SPD_D WAV_SPD_E WAV_SPD_N : Hourly average mopeds, tricycles or quads ≤ 50 cc speed (6-18h)(18-22h)(22-6h) (DOUBLE)
  • ' + '
  • WBV_SPD_D WBV_SPD_E WBV_SPD_N : Hourly average motorcycles, tricycles or quads > 50 cc speed (6-18h)(18-22h)(22-6h) (DOUBLE)
  • ' + '
  • PVMT : CNOSSOS road pavement identifier (ex: NL05)(default NL08) (VARCHAR)
  • ' + @@ -113,7 +113,8 @@ inputs = [ '
  • SLOPE : Slope (in %) of the road section. If the field is not filled in, the LINESTRING z-values will be used to calculate the slope and the traffic direction (way field) will be force to 3 (bidirectional). (DOUBLE)
  • ' + '
  • WAY : Define the way of the road section. 1 = one way road section and the traffic goes in the same way that the slope definition you have used, 2 = one way road section and the traffic goes in the inverse way that the slope definition you have used, 3 = bi-directional traffic flow, the flow is split into two components and correct half for uphill and half for downhill (INTEGER)
  • ' + '
    ', - min : 0, max: 1, type: String.class + min : 0, max: 1, + type: String.class ], tableSourceDirectivity : [ name : 'Source directivity table name', @@ -125,7 +126,8 @@ inputs = [ '
  • THETA : [-90;90] Vertical angle in degree. 0° front 90° top -90° bottom (FLOAT)
  • ' + '
  • PHI : [0;360] Horizontal angle in degree. 0° front 90° right (FLOAT)
  • ' + '
  • LW63, LW125, LW250, LW500, LW1000, LW2000, LW4000, LW8000 : attenuation levels in dB for each octave or third octave (FLOAT)
  • ' , - min : 0, max: 1, type: String.class + min : 0, max: 1, + type: String.class ], tablePeriodAtmosphericSettings : [ name : 'Atmospheric settings table name for each time period', @@ -140,7 +142,8 @@ inputs = [ '
  • GDISC : choose between accept G discontinuity or not (BOOLEAN) default true
  • ' + '
  • PRIME2520 : choose to use prime values to compute eq. 2.5.20 (BOOLEAN) default false
  • ' + '' , - min : 0, max: 1, type: String.class + min : 0, max: 1, + type: String.class ], tableReceivers : [ name : 'Receivers table name', @@ -175,163 +178,140 @@ inputs = [ paramWallAlpha : [ name : 'wallAlpha', title : 'Wall absorption coefficient', - description: 'Wall absorption coefficient (FLOAT)

    ' + - 'This coefficient is going
      ' + - '
    • from 0 : fully absorbent
    • ' + - '
    • to strictly less than 1 : fully reflective.
    ' + + description: 'Wall absorption coefficient [0,1] (between ``0`` : "fully reflective" and ``1`` : "fully absorbent")' + '🛠 Default value: 0.1 ', - min : 0, max: 1, - type : String.class + min : 0, max: 1, + type: Double.class ], confReflOrder : [ name : 'Order of reflexion', title : 'Order of reflexion', description: 'Maximum number of reflections to be taken into account (INTEGER).

    ' + - '🚨 Adding 1 order of reflexion can significantly increase the processing time.

    ' + - '🛠 Default value: 1 ', - min : 0, max: 1, - type : String.class + '🚨 Adding 1 order of reflexion can significantly increase the processing time', + default : 1, + type: Integer.class ], confMaxSrcDist : [ name : 'Maximum source-receiver distance', title : 'Maximum source-receiver distance', description: 'Maximum distance between source and receiver (FLOAT, in meters).

    ' + - '🛠 Default value: 150 ', - min : 0, max: 1, - type : String.class + 'Noise level from traffic', + default : 150, + type: Double.class ], confMaxReflDist : [ name : 'Maximum source-reflexion distance', title : 'Maximum source-reflexion distance', - description: 'Maximum reflection distance from the source (FLOAT, in meters).

    ' + - '🛠 Default value: 50 ', - min : 0, max: 1, - type : String.class + description: 'Maximum search distance of walls / facades from the "Source-Receiver" segment, for the calculation of specular reflections (meters).

    ' + + 'Noise level from traffic', + default : 50, + type: Double.class + ], + confMinWallReflDist: [ + name : 'Ignore close reflections', + title : 'Ignore close reflections', + description: 'Optional maximum receiver-to-wall distance (meters) below which reflection cut profiles are ignored. With regard to the population’s exposure to noise, it is recommended that the contribution due to reflection off the façade wall of the building where the resident lives should be disregarded. If you have placed the receivers 0.1 m from the façades, you can set this parameter to 0.2 m. This offset is set to ensure that the contribution from the nearby wall is ignored. ' + + 'Use 0 to keep all reflections.', + default: 0, + type: Double.class ], confThreadNumber : [ name : 'Thread number', title : 'Thread number', description: 'Number of thread to use on the computer (INTEGER).

    ' + - 'To set this value, look at the number of cores you have.
    ' + - 'If it is set to 0, use the maximum number of cores available.

    ' + - '🛠 Default value: 0 ', - min : 0, max: 1, - type : String.class + '🛠 Default value: 0 = Automatic. Will check the number of cores and apply -1. (*e.g*: 8 cores = 7 cores will be used', + default : 0, + type: Integer.class ], confDiffVertical : [ name : 'Diffraction on vertical edges', title : 'Diffraction on vertical edges', - description: 'Compute or not the diffraction on vertical edges. Following Directive 2015/996, enable this option for rail and industrial sources only.

    ' + - '🛠 Default value: false ', - min : 0, max: 1, + description: 'Compute or not the diffraction on vertical edges. Following Directive 2015/996, enable this option for rail and industrial sources only', + default : false, type : Boolean.class ], confDiffHorizontal : [ name : 'Diffraction on horizontal edges', title : 'Diffraction on horizontal edges', - description: 'Compute or not the diffraction on horizontal edges.

    ' + - '🛠 Default value: false ', - min : 0, max: 1, + description: 'Compute or not the diffraction on horizontal edges', + default : false, type : Boolean.class ], confExportSourceId : [ - name : 'keep source id', + name : 'Keep source id', title : 'Separate receiver level by source identifier', - description: 'Keep source identifier in output in order to get noise contribution of each noise source.

    ' + - '🛠 Default value: false ', - min : 0, max: 1, + description: 'Keep source identifier in output in order to get noise contribution of each noise source. When only the source geometry is given, the attenuation between each pair of "source-receiver" points is specified (commonly referred to as the "attenuation matrix")', + default : false, type: Boolean.class ], confHumidity : [ name : 'Relative humidity', title : 'Relative humidity', - description: '🌧 Humidity for noise propagation.

    ' + - '🛠 Default humidity value: 70', - min : 0, max: 1, - type: Double.class + description: '🌧 Humidity for noise propagation (%) [0,100]', + default : 70, + type : Double.class ], confTemperature : [ name : 'Temperature', title : 'Air temperature', - description: '🌡 Default Air temperature in degree celsius.

    ' + - '🛠 Default value: 15', - min : 0, max: 1, - type: Double.class + description: '🌡 Air temperature (°C)', + default : 15, + type : Double.class ], confFavourableOccurrencesDefault: [ name : 'Probability of occurrences', title : 'Probability of occurrences', - description: 'Comma-delimited string containing the default probability of occurrences of favourable propagation conditions.

    ' + - 'The north slice is the last array index not the first one
    ' + - 'Slice width are 22.5°: (16 slices)
      ' + - '
    • The first column 22.5° contain occurrences between 11.25 to 33.75 °
    • ' + - '
    • The last column 360° contains occurrences between 348.75° to 360° and 0 to 11.25°
    ' + - '🛠 Default value: 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5', - min : 0, max: 1, + description: 'Comma-delimited string containing the probability ([0,1]) of occurrences of favourable propagation conditions. Follow the clockwise direction. The north slice is the last array index (n°16 in the schema below) not the first one

    ' + + 'Noise level from traffic', + default : '0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5', type : String.class ], confRaysName : [ name : '', title : 'Export scene', description: 'Save each mnt, buildings and propagation rays into the specified table (ex:RAYS) or file URL (ex: file:///Z:/dir/map.kml)

    ' + - 'You can set a table name here in order to save all the rays computed by NoiseModelling.

    ' + - 'The number of rays has been limited in this script in order to avoid memory exception.

    ' + - '🛠 Default value: empty (do not keep rays)', + 'You can set a table name here in order to save all the rays computed by NoiseModelling.

    ' + + 'The number of rays has been limited in this script in order to avoid memory exception.

    ' + + '🛠 Default value: empty (do not keep rays)', min : 0, max: 1, type: String.class ], confMaxError : [ name : 'Max Error (dB)', title : 'Max Error (dB)', - description: 'Threshold for excluding negligible sound sources in calculations. Default value: 0.1', - min : 0, max: 1, + description: 'Threshold for excluding negligible sound sources in calculations.' + + 'This parameter is ignored if no emission level is specified or if you set it to 0 dB. This parameter have a great impact on computation time.', + default : 0.1, type : Double.class ], frequencyFieldPrepend : [ name : 'Frequency field name', title : 'Frequency field name', - description: 'Frequency field name prepend. Ex. for 1000 Hz frequency the default column name is HZ1000.' + - '🛠 Default value: HZ', - min : 0, max: 1, type: String.class + description: 'Frequency field name prepend. Ex. for 1000 Hz frequency the default column name is HZ1000', + default : 'HZ', + type: String.class + ], + coefficientVersion : [ + name : 'Coefficient version', + title : 'Coefficient version', + description: '🌧 Cnossos coefficient version (1 = 2015, 2 = 2020)', + default : 2, + type : Integer.class ] ] outputs = [ result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', + name : 'Created table', + title : 'Created table', + description: 'Name of the table containing the results of the computation. Can be used as input for another process.', type : String.class ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script -def exec(Connection connection, Map input) { +def exec(Connection connection, Map input, ProgressVisitor progress) { int maximumRaysToExport = 5000 DBTypes dbType = DBUtils.getDBType(connection.unwrap(Connection.class)) @@ -354,11 +334,10 @@ def exec(Connection connection, Map input) { // ------------------- String sources_table_name = input['tableRoads'] - // do it case-insensitive - sources_table_name = sources_table_name.toUpperCase() + // Check if srid are in metric projection. int sridSources = GeometryTableUtilities.getSRID(connection, TableLocation.parse(sources_table_name)) - if (sridSources == 3785 || sridSources == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+sources_table_name+".") + if (!DataBaseUtilities.isSridMetric(connection, sridSources)) throw new IllegalArgumentException("Error : Please use a metric projection for "+sources_table_name+".") if (sridSources == 0) throw new IllegalArgumentException("Error : The table "+sources_table_name+" does not have an associated SRID.") //Get the geometry field of the source table @@ -369,14 +348,13 @@ def exec(Connection connection, Map input) { } //Get the primary key field of the source table - int pkIndex = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(sources_table_name)) + int pkIndex = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(sources_table_name, dbType)) if (pkIndex < 1) { throw new IllegalArgumentException(String.format("Source table %s does not contain a primary key", sourceTableIdentifier)) } String receivers_table_name = input['tableReceivers'] - // do it case-insensitive - receivers_table_name = receivers_table_name.toUpperCase() + //Get the geometry field of the receiver table TableLocation receiverTableIdentifier = TableLocation.parse(receivers_table_name) List geomFieldsRcv = GeometryTableUtilities.getGeometryColumnNames(connection, receiverTableIdentifier) @@ -384,35 +362,33 @@ def exec(Connection connection, Map input) { throw new SQLException(String.format("The table %s does not exists or does not contain a geometry field", receiverTableIdentifier)) } // Check if srid are in metric projection and are all the same. - int sridReceivers = GeometryTableUtilities.getSRID(connection, TableLocation.parse(receivers_table_name)) - if (sridReceivers == 3785 || sridReceivers == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+receivers_table_name+".") + int sridReceivers = GeometryTableUtilities.getSRID(connection, TableLocation.parse(receivers_table_name, dbType)) + if (!DataBaseUtilities.isSridMetric(connection, sridReceivers)) throw new IllegalArgumentException("Error : Please use a metric projection for "+receivers_table_name+".") if (sridReceivers == 0) throw new IllegalArgumentException("Error : The table "+receivers_table_name+" does not have an associated SRID.") if (sridReceivers != sridSources) throw new IllegalArgumentException("Error : The SRID of table "+sources_table_name+" and "+receivers_table_name+" are not the same.") //Get the primary key field of the receiver table - int pkIndexRecv = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(receivers_table_name)) + int pkIndexRecv = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(receivers_table_name, dbType)) if (pkIndexRecv < 1) { throw new IllegalArgumentException(String.format("Source table %s does not contain a primary key", receiverTableIdentifier)) } String building_table_name = input['tableBuilding'] - // do it case-insensitive - building_table_name = building_table_name.toUpperCase() + // Check if srid are in metric projection and are all the same. - int sridBuildings = GeometryTableUtilities.getSRID(connection, TableLocation.parse(building_table_name)) - if (sridBuildings == 3785 || sridReceivers == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+building_table_name+".") + int sridBuildings = GeometryTableUtilities.getSRID(connection, TableLocation.parse(building_table_name, dbType)) + if (!DataBaseUtilities.isSridMetric(connection, sridBuildings)) throw new IllegalArgumentException("Error : Please use a metric projection for "+building_table_name+".") if (sridBuildings == 0) throw new IllegalArgumentException("Error : The table "+building_table_name+" does not have an associated SRID.") if (sridReceivers != sridBuildings) throw new IllegalArgumentException("Error : The SRID of table "+building_table_name+" and "+receivers_table_name+" are not the same.") String dem_table_name = "" if (input['tableDEM']) { dem_table_name = input['tableDEM'] - // do it case-insensitive - dem_table_name = dem_table_name.toUpperCase() + // Check if srid are in metric projection and are all the same. - int sridDEM = GeometryTableUtilities.getSRID(connection, TableLocation.parse(dem_table_name)) - if (sridDEM == 3785 || sridReceivers == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+dem_table_name+".") + int sridDEM = GeometryTableUtilities.getSRID(connection, TableLocation.parse(dem_table_name, dbType)) + if (!DataBaseUtilities.isSridMetric(connection, sridDEM)) throw new IllegalArgumentException("Error : Please use a metric projection for "+dem_table_name+".") if (sridDEM == 0) throw new IllegalArgumentException("Error : The table "+dem_table_name+" does not have an associated SRID.") if (sridDEM != sridSources) throw new IllegalArgumentException("Error : The SRID of table "+sources_table_name+" and "+dem_table_name+" are not the same.") } @@ -420,11 +396,10 @@ def exec(Connection connection, Map input) { String ground_table_name = "" if (input['tableGroundAbs']) { ground_table_name = input['tableGroundAbs'] - // do it case-insensitive - ground_table_name = ground_table_name.toUpperCase() + // Check if srid are in metric projection and are all the same. - int sridGROUND = GeometryTableUtilities.getSRID(connection, TableLocation.parse(ground_table_name)) - if (sridGROUND == 3785 || sridReceivers == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+ground_table_name+".") + int sridGROUND = GeometryTableUtilities.getSRID(connection, TableLocation.parse(ground_table_name, dbType)) + if (!DataBaseUtilities.isSridMetric(connection, sridGROUND)) throw new IllegalArgumentException("Error : Please use a metric projection for "+ground_table_name+".") if (sridGROUND == 0) throw new IllegalArgumentException("Error : The table "+ground_table_name+" does not have an associated SRID.") if (sridGROUND != sridSources) throw new IllegalArgumentException("Error : The SRID of table "+ground_table_name+" and "+sources_table_name+" are not the same.") } @@ -432,8 +407,6 @@ def exec(Connection connection, Map input) { String tableSourceDirectivity = "" if (input['tableSourceDirectivity']) { tableSourceDirectivity = input['tableSourceDirectivity'] - // do it case-insensitive - tableSourceDirectivity = tableSourceDirectivity.toUpperCase() } boolean recordProfile = false @@ -441,31 +414,25 @@ def exec(Connection connection, Map input) { recordProfile = input['confRecordProfile'] } - int reflexion_order = 0 - if (input['confReflOrder']) { - reflexion_order = Integer.valueOf(input['confReflOrder'] as String) - } + int reflexion_order = input.getOrDefault("confReflOrder",1) as Integer - double max_src_dist = 150 - if (input['confMaxSrcDist']) { - max_src_dist = Double.valueOf(input['confMaxSrcDist'] as String) - } + double max_src_dist = input.getOrDefault("confMaxSrcDist", 150.0) as Double - double max_ref_dist = 50 - if (input['confMaxReflDist']) { - max_ref_dist = Double.valueOf(input['confMaxReflDist'] as String) - } + double max_ref_dist = input.getOrDefault("confMaxReflDist",50.0) as Double - double wall_alpha = 0.1 - if (input['paramWallAlpha']) { - wall_alpha = Double.valueOf(input['paramWallAlpha'] as String) + double close_receiver_reflection_wall_distance = input.getOrDefault("confMinWallReflDist", 0.0) as Double + if (close_receiver_reflection_wall_distance < 0) { + throw new IllegalArgumentException("Error : confMinWallReflDist must be greater than or equal to 0.") } - - int n_thread = 0 - if (input['confThreadNumber']) { - n_thread = Integer.valueOf(input['confThreadNumber'] as String) + if (close_receiver_reflection_wall_distance > 2.0) { + logger.warn("confMinWallReflDist is set to {} m, which is unusually high. Many reflections may be ignored.", + close_receiver_reflection_wall_distance) } + double wall_alpha = input.getOrDefault("paramWallAlpha",0.1) as Double + + int n_thread = input.getOrDefault("confThreadNumber",0) as Integer + boolean compute_vertical_diffraction = false if (input['confDiffVertical']) { compute_vertical_diffraction = input['confDiffVertical'] @@ -481,16 +448,14 @@ def exec(Connection connection, Map input) { confExportSourceId = input['confExportSourceId'] } - double confMaxError = 0.1 - if (input['confMaxError']) { - confMaxError = Double.valueOf(input['confMaxError'] as String) - } + double confMaxError = input.getOrDefault("confMaxError",0.1) as Double String frequencyFieldPrepend = "HZ" if (input['frequencyFieldPrepend']) { frequencyFieldPrepend = input['frequencyFieldPrepend'] as String } + // -------------------------------------------- // Initialize NoiseModelling propagation part // -------------------------------------------- @@ -502,6 +467,11 @@ def exec(Connection connection, Map input) { parameters.setMergeSources(!confExportSourceId) parameters.exportReceiverPosition = true + int coefficientVersion = input.getOrDefault("coefficientVersion",2) as Integer + if (coefficientVersion != 2) { + pointNoiseMap.sceneInputSettings.setCoefficientVersion(coefficientVersion) + } + if (input['tableRoadsTraffic']) { // Use the right default database caps according to db type String tableRoadsTraffic = TableLocation.capsIdentifier(input['tableRoadsTraffic'] as String, dbType) @@ -547,18 +517,18 @@ def exec(Connection connection, Map input) { } environmentalData.setWindRose(favOccurrences) } - if (input.containsKey('confHumidity')) { - environmentalData.setHumidity(input['confHumidity'] as Double) - } - if (input.containsKey('confTemperature')) { - environmentalData.setTemperature(input['confTemperature'] as Double) - } + double confHumidity = input.getOrDefault("confHumidity",70.0) as Double + environmentalData.setHumidity(confHumidity) + + double confTemperature = input.getOrDefault("confTemperature",15.0) as Double + environmentalData.setTemperature(confTemperature) + if(input.containsKey("tablePeriodAtmosphericSettings")) { pointNoiseMap.getSceneInputSettings().setPeriodAtmosphericSettingsTableName(input.get("tablePeriodAtmosphericSettings") as String) } // Building height field name - pointNoiseMap.setHeightField("HEIGHT") + pointNoiseMap.setHeightField(TableLocation.capsIdentifier("height", dbType)) // Import table with Snow, Forest, Grass, Pasture field polygons. Attribute G is associated with each polygon if (ground_table_name != "") { pointNoiseMap.setSoilTableName(ground_table_name) @@ -570,6 +540,7 @@ def exec(Connection connection, Map input) { pointNoiseMap.setMaximumPropagationDistance(max_src_dist) pointNoiseMap.setMaximumReflectionDistance(max_ref_dist) + pointNoiseMap.setCloseReceiverReflectionWallDistance(close_receiver_reflection_wall_distance) pointNoiseMap.setWallAbsorption(wall_alpha) pointNoiseMap.setThreadCount(n_thread) @@ -577,7 +548,7 @@ def exec(Connection connection, Map input) { if(recordProfile) { LocalDateTime now = LocalDateTime.now() pointNoiseMap.noiseMapDatabaseParameters.CSVProfilerOutputPath = new File(String.format("profile_%d_%d_%d_%dh%d.csv", - now.getYear(), now.getMonthValue(), now.getDayOfMonth(), now.getHour(), now.getMinute())) + now.getYear(), now.getMonthValue(), now.getDayOfMonth(), now.getHour(), now.getMinute())) pointNoiseMap.noiseMapDatabaseParameters.CSVProfilerWriteInterval = 120 // delay write csv line in seconds } @@ -589,13 +560,13 @@ def exec(Connection connection, Map input) { // Run Calculations // -------------------------------------------- - // Init ProgressLogger (loading bar) - RootProgressVisitor progressLogger = new RootProgressVisitor(1, true, 1) - logger.info("Start calculation... ") - pointNoiseMap.run(connection, progressLogger) + pointNoiseMap.run(connection, progress) - return "Calculation Done ! The table $pointNoiseMap.noiseMapDatabaseParameters.receiversLevelTable have been created." + return [result : pointNoiseMap.noiseMapDatabaseParameters.receiversLevelTable] } +def exec(Connection connection, Map input) { + return exec(connection, input, new EmptyProgressVisitor()) +} diff --git a/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Deprecated/package-info.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Deprecated/package-info.groovy new file mode 100644 index 000000000..3196ae297 --- /dev/null +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Deprecated/package-info.groovy @@ -0,0 +1,4 @@ +/** + * Unused scripts that will be removed in the next major release + */ +package org.noise_planet.noisemodelling.scripts.Deprecated; \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Flow_2_Noisy_Vehicles.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Flow_2_Noisy_Vehicles.groovy similarity index 89% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Flow_2_Noisy_Vehicles.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Flow_2_Noisy_Vehicles.groovy index 2929ab150..3f422854f 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Flow_2_Noisy_Vehicles.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Flow_2_Noisy_Vehicles.groovy @@ -15,13 +15,10 @@ * @Author Valentin Le Bescond, Université Gustave Eiffel, Ghent University */ -package org.noise_planet.noisemodelling.wps.Dynamic +package org.noise_planet.noisemodelling.scripts.Dynamic -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql import groovy.time.TimeCategory -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.SpatialResultSet @@ -30,7 +27,9 @@ import org.h2gis.utilities.wrapper.ConnectionWrapper import org.locationtech.jts.geom.* import org.noise_planet.noisemodelling.emission.road.cnossosvar.RoadVehicleCnossosvar import org.noise_planet.noisemodelling.emission.road.cnossosvar.RoadVehicleCnossosvarParameters - +import org.noise_planet.noisemodelling.jdbc.utils.DataBaseUtilities +import org.slf4j.Logger +import org.slf4j.LoggerFactory import java.security.InvalidParameterException import java.sql.Connection import java.sql.ResultSet @@ -38,17 +37,17 @@ import java.sql.SQLException import java.util.stream.Collectors title = 'From Road traffic flows to noisy individual vehicles' -description = 'Calculating individual vehicle position and noise_level based on average traffic flows.' + +description = 'Calculates individual vehicle position and noise level based on average traffic flows.' + '

    A first output table is called : SOURCES_GEOM which is needed to compute the Noise Attenuation Matrix' + 'and contain :
    ' + - '- IDSOURCE : an identifier (INTEGER, PRIMARY KEY).
    ' + - '- ROAD_ID : id link to the road segment (INTEGER).
    ' + + '- IDSOURCE : an identifier (INTEGER, PRIMARY KEY).
    ' + + '- ROAD_ID : id link to the road segment (INTEGER).
    ' + '- THE_GEOM : the 3D geometry of the sources (POINT).
    ' + '

    The output table is called : SOURCES_EMISSION ' + 'and contain :
    ' + - '- PK : an identifier (INTEGER, PRIMARY KEY).
    ' + - '- IDSOURCE : link to the source point (INTEGER).
    ' + - '- PERIOD : The TIMESTAMP iteration (VARCHAR).
    ' + + '- PK : an identifier (INTEGER, PRIMARY KEY).
    ' + + '- IDSOURCE : link to the source point (INTEGER).
    ' + + '- PERIOD : The TIMESTAMP iteration (VARCHAR).
    ' + '- HZ63, HZ125, HZ250, HZ500, HZ1000,HZ2000, HZ4000, HZ8000 : 8 columns giving the instantaneous emission sound level for each octave band (FLOAT).' inputs = [ @@ -67,61 +66,41 @@ inputs = [ description : "
    Two methods are available : " + "
    - PROBA : Probabilistic representation of vehicle appearances for each time step (quicker, but sacrifices temporal coherence) Aumond, P., Jacquesson, L., & Can, A. (2018). Probabilistic modeling framework for multisource sound mapping. Applied Acoustics, 139, 34-43. ." + "
    - TNP : Simplified vehicle movements (slower, but maintaining temporal coherence) De Coensel, B.; Brown, A.L.; Tomerini, D. A road traffic noise pattern simulation model that includes distributions of vehicle sound power levels. Appl. Acoust. 2016, 111, 170–178. .", + allowedValues: ['TNP', 'PROBA'], type: String.class], timestep : [name : 'timestep', title : "timestep", - description : "Number of iterations. Timestep in sec.
    Default value : 1 ", + description : "Number of iterations. Timestep in sec.", + default : 1, type: Integer.class], gridStep : [name : 'gridStep', title : "gridStep", - description : "Distance between location of vehicle along the network in meters.
    Default value : 10 ", + description : "Distance between location of vehicle along the network in meters.", + default : 10, type: Integer.class], - duration : [name : 'duration', title: 'duration in sec.', - description: 'Number of seconds to compute (INTEGER).

    Default value : 60 ', - type: Integer.class], + duration: [name : 'duration', title: 'duration in sec.', + description: 'Number of seconds to compute (INTEGER).', + default : 60, + type : Integer.class], ] outputs = [ result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', + name : 'Generated table name', + title : 'Generated table name', + description: 'Name of the generated table. Can be used as the input of other process.', type : String.class ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - // main function of the script def exec(Connection connection, input) { + Logger logger = LoggerFactory.getLogger("Flow_2_Noisy_Vehicles") //Need to change the ConnectionWrapper to WpsConnectionWrapper to work under postGIS database connection = new ConnectionWrapper(connection) @@ -132,29 +111,20 @@ def exec(Connection connection, input) { String resultString = null // print to command window - System.out.println('Start : Traffic Probabilistic Modelling') + logger.info('Start : Traffic Probabilistic Modelling') def start = new Date() // ------------------- // Get every inputs // ------------------- - int duration = 60 - if (input['duration']) { - duration = Integer.valueOf(input['duration'] as String) - } + int duration = input.getOrDefault("duration", 60) as Integer - int timestep = 1 - if (input['timestep']) { - timestep = Integer.valueOf(input['timestep'] as String) - } + int timestep = input.getOrDefault("timestep", 1) as Integer - int gridStep = 10 - if (input['gridStep']) { - gridStep = Integer.valueOf(input['gridStep'] as String) - } + int gridStep = input.getOrDefault("gridStep", 10) as Integer - int nIterations = (int) Math.round(duration/timestep); + int nIterations = (int) Math.round(duration/timestep) String method = "PROBA" if (input['method']) { @@ -166,10 +136,10 @@ def exec(Connection connection, input) { sources_table_name = sources_table_name.toUpperCase() // Check if srid are in metric projection. int sridSources = GeometryTableUtilities.getSRID(connection, TableLocation.parse(sources_table_name)) - if (sridSources == 3785 || sridSources == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+sources_table_name+".") + if (!DataBaseUtilities.isSridMetric(connection, sridSources)) throw new IllegalArgumentException("Error : Please use a metric projection for "+sources_table_name+".") if (sridSources == 0) throw new IllegalArgumentException("Error : The table "+sources_table_name+" does not have an associated SRID.") - System.out.println('Start time : ' + TimeCategory.minus(new Date(), start)) + logger.info('Start time : ' + TimeCategory.minus(new Date(), start)) sql.execute("DROP TABLE IF EXISTS ROAD_POINTS" ) sql.execute("CREATE TABLE ROAD_POINTS(ROAD_ID serial, THE_GEOM geometry, LV int, LV_SPD real, HV int, HV_SPD real) AS SELECT r.PK, ST_Tomultipoint(ST_Densify(the_geom, "+gridStep+")), r.LV_D, r.LV_SPD_D, r.HGV_D, r.HGV_SPD_D FROM "+sources_table_name+" r WHERE NOT ST_IsEmpty(r.THE_GEOM) ;") @@ -189,7 +159,7 @@ def exec(Connection connection, input) { "ALTER TABLE VEHICLES_PROBA ALTER COLUMN LV_DENS_D double;" + "ALTER TABLE VEHICLES_PROBA ALTER COLUMN HGV_DENS_D double;" ) - IndividualVehicleEmissionProcessData probabilisticProcessData = new IndividualVehicleEmissionProcessData(); + IndividualVehicleEmissionProcessData probabilisticProcessData = new IndividualVehicleEmissionProcessData() probabilisticProcessData.setDynamicEmissionTable("VEHICLES_PROBA", sql) @@ -239,7 +209,7 @@ def exec(Connection connection, input) { while (rs.next()) { Road road = new Road() - System.out.println(k + "/" + roadCount + " % " + 100*k/roadCount) + logger.info(k + "/" + roadCount + " % " + 100*k/roadCount) k++ road.setRoad( @@ -291,19 +261,18 @@ def exec(Connection connection, input) { sql.execute("drop table VEHICLES_PROBA if exists;") - System.out.println('Intermediate time : ' + TimeCategory.minus(new Date(), start)) - System.out.println("Export data to table") + logger.info('Intermediate time : ' + TimeCategory.minus(new Date(), start)) + logger.info("Export data to table") resultString = "Calculation Done ! The table SOURCES_EMISSION and SOURCES_GEOM has been created." // print to command window - System.out.println('Result : ' + resultString) - System.out.println('End : Traffic Probabilistic Modelling') - System.out.println('Duration : ' + TimeCategory.minus(new Date(), start)) + logger.info('Result : ' + resultString) + logger.info('End : Traffic Probabilistic Modelling') + logger.info('Duration : ' + TimeCategory.minus(new Date(), start)) - // print to WPS Builder - return resultString + return [result : "SOURCES_GEOM"] } @@ -357,7 +326,7 @@ class Road { Coordinate[] coordinates = geom.getCoordinates() for(int i = 1; i < coordinates.length; i++){ - line_segments.add(new LineSegment(coordinates[i-1], coordinates[i])); + line_segments.add(new LineSegment(coordinates[i-1], coordinates[i])) } /*for (String vehicle_type: [ @@ -842,10 +811,6 @@ class IndividualVehicleEmissionProcessData { LV.put(pk, (double) row[2]) SPEED_HV.put(pk, (double) row[3]) HV.put(pk, (double) row[4]) - } - - } - } \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Ind_Vehicles_2_Noisy_Vehicles.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Ind_Vehicles_2_Noisy_Vehicles.groovy similarity index 80% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Ind_Vehicles_2_Noisy_Vehicles.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Ind_Vehicles_2_Noisy_Vehicles.groovy index 2d2b41b69..d759b4117 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Ind_Vehicles_2_Noisy_Vehicles.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Ind_Vehicles_2_Noisy_Vehicles.groovy @@ -12,16 +12,13 @@ /** * @Author Pierre Aumond, Université Gustave Eiffel - * @Author Valetin Le Bescond, Université Gustave Eiffel, Ghent University + * @Author Valentin Le Bescond, Université Gustave Eiffel, Ghent University */ -package org.noise_planet.noisemodelling.wps.Dynamic +package org.noise_planet.noisemodelling.scripts.Dynamic -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql import groovy.time.TimeCategory -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation @@ -32,7 +29,7 @@ import org.h2gis.utilities.wrapper.ConnectionWrapper import org.locationtech.jts.geom.* import org.noise_planet.noisemodelling.emission.road.cnossosvar.RoadVehicleCnossosvar import org.noise_planet.noisemodelling.emission.road.cnossosvar.RoadVehicleCnossosvarParameters - +import org.noise_planet.noisemodelling.jdbc.utils.DataBaseUtilities import java.sql.Connection import java.sql.SQLException @@ -45,30 +42,35 @@ description = 'Calculating dynamic road emissions based on vehicles trajectories '- HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000 : 8 columns giving the emission sound level for each octave band (FLOAT).' inputs = [ - tableVehicles : [name : 'Individual Vehicles table', - title : "table of the individual Vehicles", - description : "it should contain timestep, geometry (POINT), speed, acceleration, veh_type...", - type: String.class], - tableSourceGeom : [name : 'Source geometry table', - title : "table of the individual Vehicles", - description : "table of points source geometry, the output emission will be reattached to" + - " the index of this table according to the snap distance. Should be SOURCES_GEOM" + - " See Point_Source_From_Network to convert lines to points", - type: String.class], + tableVehicles : [ + name : 'Individual Vehicles table', + title : "table of the individual Vehicles", + description : "it should contain timestep, geometry (POINT), speed, acceleration, veh_type...", + type: String.class], + tableSourceGeom : [ + name : 'Source geometry table', + title : "table of the source geometry", + description : "table of points source geometry, the output emission will be reattached to" + + " the index of this table according to the snap distance. Should be SOURCES_GEOM" + + " See Point_Source_From_Network to convert lines to points", + type: String.class], distance2snap : [name : 'Snap distance', title : "Maximum distance to snap on the network point sources", description : "Maximum distance to snap on the network point sources", min : 0, max : 1, type: Double.class], - tableFormat : [name : 'Vehicles table format', - title : 'Format of the individual Vehicles table', - description :'Format of the individual Vehicles table. Can be for the moment SUMO or Matsim. See in the code to understand the different format.', - type: String.class], - keepNoEmissionGeoms : [name : 'Keep source geometries without emission value', - title : 'Keep source geometries without emission value', - description :'Do not delete source geometries that does not contain any emission value. Default to true, it reduce the computation time when evaluating the attenuation', - min : 0, max: 1, type: Boolean.class] + tableFormat : [ + name : 'Vehicles table format', + title : 'Format of the individual Vehicles table', + description :'Format of the individual Vehicles table. Can be for the moment SUMO or Matsim. See in the code to understand the different format.', + type: String.class], + keepNoEmissionGeoms : [ + name : 'Keep source geometries without emission value', + title : 'Keep source geometries without emission value', + description :'Do not delete source geometries that does not contain any emission value. Default to true, it reduce the computation time when evaluating the attenuation', + default: true, + type: Boolean.class] ] outputs = [ @@ -80,32 +82,6 @@ outputs = [ ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - - // main function of the script def exec(Connection connection, Map input) { @@ -134,7 +110,7 @@ def exec(Connection connection, Map input) { String tableFormat = input['tableFormat'] - double distance2snap = input['distance2snap'] + double distance2snap = input['distance2snap'] as Double boolean removeGeomsNoEmission = true if (input['keepNoEmissionGeoms']) { @@ -145,8 +121,8 @@ def exec(Connection connection, Map input) { // do it case-insensitive vehicles_table_name = vehicles_table_name.toUpperCase() // Check if srid are in metric projection. - sridSources = GeometryTableUtilities.getSRID(connection, TableLocation.parse(vehicles_table_name)) - if (sridSources == 3785 || sridSources == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+vehicles_table_name+".") + int sridSources = GeometryTableUtilities.getSRID(connection, TableLocation.parse(vehicles_table_name)) + if (!DataBaseUtilities.isSridMetric(connection, sridSources)) throw new IllegalArgumentException("Error : Please use a metric projection for "+vehicles_table_name+".") if (sridSources == 0) throw new IllegalArgumentException("Error : The table "+vehicles_table_name+" does not have an associated SRID.") System.out.println('Start time : ' + TimeCategory.minus(new Date(), start)) @@ -339,7 +315,4 @@ class VehicleEmissionProcessData { return res_LV } - - - } diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Noise_From_Attenuation_Matrix.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Noise_From_Attenuation_Matrix.groovy similarity index 87% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Noise_From_Attenuation_Matrix.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Noise_From_Attenuation_Matrix.groovy index 5034af663..20fa98193 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Noise_From_Attenuation_Matrix.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Noise_From_Attenuation_Matrix.groovy @@ -14,11 +14,9 @@ * @Author Pierre Aumond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Dynamic +package org.noise_planet.noisemodelling.scripts.Dynamic + -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation import org.h2gis.utilities.dbtypes.DBTypes @@ -77,27 +75,10 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} -def run(input) { - // Get name of the database - String dbName = "h2gisdb" - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script def exec(Connection connection, input) { diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Point_Source_From_Network.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Point_Source_From_Network.groovy similarity index 80% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Point_Source_From_Network.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Point_Source_From_Network.groovy index 1ebf39a12..f7b1675e0 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Point_Source_From_Network.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Point_Source_From_Network.groovy @@ -14,12 +14,12 @@ * @Author Pierre Aumond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Dynamic +package org.noise_planet.noisemodelling.scripts.Dynamic + + -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore + import org.h2gis.utilities.GeometryMetaData import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.TableLocation @@ -67,27 +67,10 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} -def run(input) { - // Get name of the database - String dbName = "h2gisdb" - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} def exec(connection, Map input) { @@ -101,15 +84,9 @@ def exec(connection, Map input) { logger.info('Start : Point_Source_From_Network.groovy') logger.info("inputs {}", input) - int gridStep = 10 // 10 meters is the default value - if (input['gridStep']) { - gridStep = Integer.valueOf(input['gridStep'] as String) - } + int gridStep = input.getOrDefault("gridStep", 10) as Integer // 10 meters is the default value - double h = 0.05 // height of the source (0.05 m) for road traffic - if (input['height']) { - h = input['height'] as Double - } + double h = input.getOrDefault("height", 0.05) as Double // height of the source (0.05 m) for road traffic String roadsTableName = input['tableNetwork'] diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Split_Sources_Period.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Split_Sources_Period.groovy similarity index 85% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Split_Sources_Period.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Split_Sources_Period.groovy index 3af652d61..490673adb 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Dynamic/Split_Sources_Period.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Dynamic/Split_Sources_Period.groovy @@ -10,17 +10,16 @@ * */ -package org.noise_planet.noisemodelling.wps.Dynamic +package org.noise_planet.noisemodelling.scripts.Dynamic + -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation import org.h2gis.utilities.dbtypes.DBTypes import org.h2gis.utilities.dbtypes.DBUtils import org.h2gis.utilities.wrapper.ConnectionWrapper +import org.noise_planet.noisemodelling.jdbc.utils.DataBaseUtilities import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -78,27 +77,10 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} -def run(input) { - // Get name of the database - String dbName = "h2gisdb" - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script def exec(Connection connection, Map input) { @@ -132,7 +114,7 @@ def exec(Connection connection, Map input) { } int sridSources = GeometryTableUtilities.getSRID(connection, TableLocation.parse(tableSourceDynamic, dbType)) - if (sridSources == 3785 || sridSources == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+tableSourceDynamic+".") + if (!DataBaseUtilities.isSridMetric(connection, sridSources)) throw new IllegalArgumentException("Error : Please use a metric projection for "+tableSourceDynamic+".") if (sridSources == 0) throw new IllegalArgumentException("Error : The table "+tableSourceDynamic+" does not have an associated SRID.") def columnNames = JDBCUtilities.getColumnNames(connection, tableSourceDynamic) diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental/Noise_Map_Difference.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental/Noise_Map_Difference.groovy similarity index 87% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental/Noise_Map_Difference.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental/Noise_Map_Difference.groovy index 56c1b8b46..fcab0292a 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental/Noise_Map_Difference.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental/Noise_Map_Difference.groovy @@ -13,12 +13,12 @@ * @Author Valentin Le Bescond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Experimental +package org.noise_planet.noisemodelling.scripts.Experimental + + -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore + import org.h2gis.utilities.wrapper.ConnectionWrapper import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -75,27 +75,10 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} -def run(input) { - // Get name of the database - String dbName = "h2gisdb" - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script def exec(Connection connection, input) { diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental/Road_Emission_From_AADF.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental/Road_Emission_From_AADF.groovy similarity index 93% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental/Road_Emission_From_AADF.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental/Road_Emission_From_AADF.groovy index ca0cd72b7..ab3057223 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental/Road_Emission_From_AADF.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental/Road_Emission_From_AADF.groovy @@ -1,14 +1,14 @@ -package org.noise_planet.noisemodelling.wps.Experimental +package org.noise_planet.noisemodelling.scripts.Experimental + + -import geoserver.GeoServer -import geoserver.catalog.Store /** * @Author Pierre Aumond, 13/11/2019, Université Gustave Eiffel */ import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore + import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.SpatialResultSet @@ -36,29 +36,10 @@ outputs = [result: [name: 'result', title: 'Result', type: String.class]] -static Connection openGeoserverDataStoreConnection(String dbName) { - if(dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore)store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} -def run(input) { - // Get name of the database - String dbName = "" - if (input['databaseName']) { - dbName = input['databaseName'] as String - } - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { Connection connection -> - exec(connection, input) - } -} def exec(connection, input) { diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental/Road_Emission_From_TMJA.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental/Road_Emission_From_TMJA.groovy similarity index 56% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental/Road_Emission_From_TMJA.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental/Road_Emission_From_TMJA.groovy index f041b177c..04bf77838 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental/Road_Emission_From_TMJA.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental/Road_Emission_From_TMJA.groovy @@ -2,12 +2,12 @@ * @Author Pierre Aumond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Experimental +package org.noise_planet.noisemodelling.scripts.Experimental + + -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore + import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.SpatialResultSet @@ -31,17 +31,7 @@ inputs = [databaseName : [name: 'Name of the database', title: 'Name of the d outputs = [result: [name: 'result', title: 'Result', type: String.class]] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { +def exec(Connection connection, Map input) { String output = null // ------------------- @@ -53,91 +43,72 @@ def run(input) { } sources_table_name = sources_table_name.toUpperCase() - // Get name of the database - String dbName = "" - if (input['databaseName']) { - dbName = input['databaseName'] as String + //Get the geometry field of the source table + TableLocation sourceTableIdentifier = TableLocation.parse(sources_table_name) + List geomFields = GeometryTableUtilities.getGeometryColumnNames(connection, sourceTableIdentifier) + if (geomFields.isEmpty()) { + output = String.format("The table %s does not exists or does not contain a geometry field", sourceTableIdentifier) + throw new SQLException(String.format("The table %s does not exists or does not contain a geometry field", sourceTableIdentifier)); } + String sourceGeomName = geomFields.get(0); - // ---------------------------------- - // Start... - // ---------------------------------- - - System.out.println("Run ...") - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { Connection connection -> - - //Need to change the ConnectionWrapper to WpsConnectionWrapper to work under postgis database - connection = new ConnectionWrapper(connection) - System.out.println("Connection to the database ok ...") + //Get the primary key field of the source table + int pkIndex = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(sources_table_name)) + if (pkIndex < 1) { + throw new IllegalArgumentException(String.format("Source table %s does not contain a primary key", sourceTableIdentifier)); + } - //Get the geometry field of the source table - TableLocation sourceTableIdentifier = TableLocation.parse(sources_table_name) - List geomFields = GeometryTableUtilities.getGeometryColumnNames(connection, sourceTableIdentifier) - if (geomFields.isEmpty()) { - output = String.format("The table %s does not exists or does not contain a geometry field", sourceTableIdentifier) - throw new SQLException(String.format("The table %s does not exists or does not contain a geometry field", sourceTableIdentifier)); + // open sql connection + Sql sql = new Sql(connection) + + // create empty LW_ROADS + sql.execute("drop table if exists LW_ROADS;") + sql.execute("create table LW_ROADS (IDSOURCE integer, the_geom Geometry, " + + "Ld63 double precision, Ld125 double precision, Ld250 double precision, Ld500 double precision, Ld1000 double precision, Ld2000 double precision, Ld4000 double precision, Ld8000 double precision," + + "Le63 double precision, Le125 double precision, Le250 double precision, Le500 double precision, Le1000 double precision, Le2000 double precision, Le4000 double precision, Le8000 double precision," + + "Ln63 double precision, Ln125 double precision, Ln250 double precision, Ln500 double precision, Ln1000 double precision, Ln2000 double precision, Ln4000 double precision, Ln8000 double precision);") + + def qry = 'INSERT INTO LW_ROADS(IDSOURCE,the_geom, ' + + 'Ld63, Ld125, Ld250, Ld500, Ld1000,Ld2000, Ld4000, Ld8000,' + + 'Le63, Le125, Le250, Le500, Le1000,Le2000, Le4000, Le8000,' + + 'Ln63, Ln125, Ln250, Ln500, Ln1000,Ln2000, Ln4000, Ln8000) ' + + 'VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);' + + + long start = System.currentTimeMillis() + System.out.println("Start ...") + // fill the table LW_ROADS + sql.withBatch(100, qry) { ps -> + PreparedStatement st = connection.prepareStatement("SELECT * FROM " + sources_table_name) + SpatialResultSet rs = st.executeQuery().unwrap(SpatialResultSet.class) + while (rs.next()) { + System.println(rs) + Geometry geo = rs.getGeometry() + def results = computeLw(rs.getLong(pkIndex), geo, rs) + + ps.addBatch(rs.getLong(pkIndex) as Integer, geo as Geometry, + results[0][0] as Double, results[0][1] as Double, results[0][2] as Double, + results[0][3] as Double, results[0][4] as Double, results[0][5] as Double, + results[0][6] as Double, results[0][7] as Double, + results[1][0] as Double, results[1][1] as Double, results[1][2] as Double, + results[1][3] as Double, results[1][4] as Double, results[1][5] as Double, + results[1][6] as Double, results[1][7] as Double, + results[2][0] as Double, results[2][1] as Double, results[2][2] as Double, + results[2][3] as Double, results[2][4] as Double, results[2][5] as Double, + results[2][6] as Double, results[2][7] as Double) } - String sourceGeomName = geomFields.get(0); + } - //Get the primary key field of the source table - int pkIndex = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(sources_table_name)) - if (pkIndex < 1) { - throw new IllegalArgumentException(String.format("Source table %s does not contain a primary key", sourceTableIdentifier)); - } + sql.execute("UPDATE LW_ROADS SET THE_GEOM = ST_UPDATEZ(The_geom,0.05);") + sql.execute("ALTER TABLE LW_ROADS ADD pk INT AUTO_INCREMENT PRIMARY KEY;") + long computationTime = System.currentTimeMillis() - start; + output = "The Table LW_ROADS have been created" + return [result: output] - // open sql connection - Sql sql = new Sql(connection) - - // create empty LW_ROADS - sql.execute("drop table if exists LW_ROADS;") - sql.execute("create table LW_ROADS (IDSOURCE integer, the_geom Geometry, " + - "Ld63 double precision, Ld125 double precision, Ld250 double precision, Ld500 double precision, Ld1000 double precision, Ld2000 double precision, Ld4000 double precision, Ld8000 double precision," + - "Le63 double precision, Le125 double precision, Le250 double precision, Le500 double precision, Le1000 double precision, Le2000 double precision, Le4000 double precision, Le8000 double precision," + - "Ln63 double precision, Ln125 double precision, Ln250 double precision, Ln500 double precision, Ln1000 double precision, Ln2000 double precision, Ln4000 double precision, Ln8000 double precision);") - - def qry = 'INSERT INTO LW_ROADS(IDSOURCE,the_geom, ' + - 'Ld63, Ld125, Ld250, Ld500, Ld1000,Ld2000, Ld4000, Ld8000,' + - 'Le63, Le125, Le250, Le500, Le1000,Le2000, Le4000, Le8000,' + - 'Ln63, Ln125, Ln250, Ln500, Ln1000,Ln2000, Ln4000, Ln8000) ' + - 'VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);' - - - long start = System.currentTimeMillis() - System.out.println("Start ...") - // fill the table LW_ROADS - sql.withBatch(100, qry) { ps -> - PreparedStatement st = connection.prepareStatement("SELECT * FROM " + sources_table_name) - SpatialResultSet rs = st.executeQuery().unwrap(SpatialResultSet.class) - while (rs.next()) { - System.println(rs) - Geometry geo = rs.getGeometry() - def results = computeLw(rs.getLong(pkIndex), geo, rs) - - ps.addBatch(rs.getLong(pkIndex) as Integer, geo as Geometry, - results[0][0] as Double, results[0][1] as Double, results[0][2] as Double, - results[0][3] as Double, results[0][4] as Double, results[0][5] as Double, - results[0][6] as Double, results[0][7] as Double, - results[1][0] as Double, results[1][1] as Double, results[1][2] as Double, - results[1][3] as Double, results[1][4] as Double, results[1][5] as Double, - results[1][6] as Double, results[1][7] as Double, - results[2][0] as Double, results[2][1] as Double, results[2][2] as Double, - results[2][3] as Double, results[2][4] as Double, results[2][5] as Double, - results[2][6] as Double, results[2][7] as Double) - } - } - - sql.execute("UPDATE LW_ROADS SET THE_GEOM = ST_UPDATEZ(The_geom,0.05);") - sql.execute("ALTER TABLE LW_ROADS ADD pk INT AUTO_INCREMENT PRIMARY KEY;") - long computationTime = System.currentTimeMillis() - start; - output = "The Table LW_ROADS have been created" - return [result: output] +} - } -} static double[][] computeLw(Long pk, Geometry geom, SpatialResultSet rs) throws SQLException { diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Agent_Exposure.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Agent_Exposure.groovy similarity index 91% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Agent_Exposure.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Agent_Exposure.groovy index e61964c14..ca878b4da 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Agent_Exposure.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Agent_Exposure.groovy @@ -13,16 +13,13 @@ * @Author Valentin Le Bescond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Experimental_Matsim +package org.noise_planet.noisemodelling.scripts.Experimental_Matsim import com.opencsv.CSVParser import com.opencsv.CSVParserBuilder import com.opencsv.CSVReaderHeaderAware import com.opencsv.CSVReaderHeaderAwareBuilder -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.wrapper.ConnectionWrapper import org.matsim.api.core.v01.Id import org.matsim.api.core.v01.Scenario @@ -32,33 +29,32 @@ import org.matsim.core.population.io.PopulationReader import org.matsim.core.scenario.ScenarioUtils import org.slf4j.Logger import org.slf4j.LoggerFactory - import groovy.transform.CompileStatic import java.nio.file.Files import java.nio.file.Paths import java.sql.* import java.util.zip.GZIPInputStream -title = 'Calculate Mastim agents exposure' -description = "Loads a Matsim plans.xml file and calculate agents noise exposure, based on previously claculated timesliced noisemap at receiver positions, linked with matsim activities (facilities)" +title = 'Calculate Matsim agents exposure' +description = "Loads a Matsim plans.xml file and calculate agents noise exposure, based on previously calculated timesliced noisemap at receiver positions, linked with matsim activities (facilities)" inputs = [ plansFile: [ name: 'Path of the Matsim output_plans file', title: 'Path of the Matsim output_plans file', - description: 'Path of the Matsim output_plans file
    For example : /home/mastim/simulation_output/output_plans.xml.gz', + description: 'Path of the Matsim output_plans file
    For example : /home/matsim/simulation_output/output_plans.xml.gz', type: String.class ], experiencedPlansFile: [ name: 'Path of the Matsim output_experienced_plans file', title: 'Path of the Matsim output_experienced_plans file', - description: 'Path of the Matsim output_plans file
    For example : /home/mastim/simulation_output/output_experienced_plans.xml.gz', + description: 'Path of the Matsim output_plans file
    For example : /home/matsim/simulation_output/output_experienced_plans.xml.gz', type: String.class ], personsCsvFile: [ name: 'personsCsvFile', title: 'personsCsvFile', - description: 'Path of the Matsim output_persons csv file
    For example : /home/mastim/simulation_output/output_persons.csv.gz', + description: 'Path of the Matsim output_persons csv file
    For example : /home/matsim/simulation_output/output_persons.csv.gz', min: 0, max: 1, type: String.class @@ -76,7 +72,7 @@ inputs = [ title: 'Table containing the noise data', description: 'Table containing the noise data' + '
    The table must contain the following fields :' + - '
    PK, IDRECEIVER, THE_GEOM, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ000, HZ8000, TIME', + '
    PK, IDRECEIVER, THE_GEOM, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ000, HZ8000, PERIOD', type: String.class ], timeBinSize: [ @@ -92,8 +88,7 @@ inputs = [ name: 'Projection identifier', title: 'Projection identifier', description: 'Original projection identifier (also called SRID) of your tables.' + - 'It should be an EPSG code, a integer with 4 or 5 digits (ex: 3857 is Web Mercator projection).' + - '
    Default value : 4326 ', + 'It should be an EPSG code; an integer with 4 or 5 digits (ex: 3857 is Web Mercator projection).', min: 0, max: 1, type: Integer.class @@ -117,30 +112,6 @@ outputs = [ ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script @CompileStatic @@ -200,21 +171,21 @@ static def exec(Connection connection, input) { String column = rs.getString("COLUMN_NAME"); if (column == "IDRECEIVER") { indexIDRECEIVER = true; - logger.info("index on data table IDSOURCE found") + logger.info("index on column IDSOURCE found") } - else if (column == "TIME") { + else if (column == "PERIOD") { indexTIMESTRING = true; - logger.info("index on data table TIME found") + logger.info("index on column PERIOD found") } } if (!indexIDRECEIVER) { - logger.info("index on data table IDRECEIVER, NOT found, creating one...") + logger.info("index on column IDRECEIVER, NOT found, creating one...") sql.execute("CREATE INDEX ON " + dataTable + " (IDRECEIVER)"); } if (!indexTIMESTRING) { - logger.info("index on data table TIME, NOT found, creating one...") - sql.execute("CREATE INDEX ON " + dataTable + " (TIME)"); + logger.info("index on column PERIOD, NOT found, creating one...") + sql.execute("CREATE INDEX ON " + dataTable + " (PERIOD)"); } logger.info("searching index on receivers table... ") @@ -224,12 +195,12 @@ static def exec(Connection connection, input) { String column = rs.getString("COLUMN_NAME"); if (column == "FACILITY") { indexFACILITY = true; - logger.info("index on receivers table FACILITY found") + logger.info("index on column FACILITY found") } } if (!indexFACILITY) { - logger.info("index on receivers table FACILITY, NOT found, creating one...") + logger.info("index on column FACILITY, NOT found, creating one...") sql.execute("CREATE INDEX ON " + receiversTable + " (FACILITY)"); } @@ -358,17 +329,18 @@ static def exec(Connection connection, input) { } String query = ''' - SELECT D.LEQA, D.TIME + SELECT D.LAEQ, D.PERIOD FROM ''' + dataTable + ''' D INNER JOIN ''' + receiversTable + ''' R ON D.IDRECEIVER = R.PK WHERE R.FACILITY = \'''' + activityId + '''\' + AND D.PERIOD != '' ''' ResultSet result = stmt.executeQuery(query) Map timeSeries = new HashMap() while(result.next()) { - int timeBin = result.getInt("TIME") - Double value = result.getDouble("LEQA") + int timeBin = Integer.parseInt(result.getString("PERIOD")); + Double value = result.getDouble("LAEQ") timeSeries.put(timeBin, value) } activitiesTimeSeries.put(activityId, timeSeries) diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Import_Activities.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Import_Activities.groovy similarity index 82% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Import_Activities.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Import_Activities.groovy index aa80b9cad..d9fb88bd9 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Import_Activities.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Import_Activities.groovy @@ -13,12 +13,9 @@ * @Author Valentin Le Bescond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Experimental_Matsim +package org.noise_planet.noisemodelling.scripts.Experimental_Matsim -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.wrapper.ConnectionWrapper import org.matsim.api.core.v01.Coord import org.matsim.api.core.v01.Scenario @@ -29,7 +26,6 @@ import org.matsim.facilities.ActivityFacility import org.matsim.facilities.MatsimFacilitiesReader import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.* import groovy.sql.Sql @@ -47,8 +43,7 @@ inputs = [ name: 'Projection identifier', title: 'Projection identifier', description: 'Original projection identifier (also called SRID) of your table.' + - 'It should be an EPSG code, a integer with 4 or 5 digits (ex: 3857 is Web Mercator projection).' + - '
    Default value : 4326 ', + 'It should be an EPSG code, a integer with 4 or 5 digits (ex: 3857 is Web Mercator projection).', min: 0, max: 1, type: Integer.class @@ -72,27 +67,6 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - - // Get name of the database - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script @CompileStatic diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Plot_Exposition_Distribution.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Plot_Exposition_Distribution.groovy similarity index 87% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Plot_Exposition_Distribution.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Plot_Exposition_Distribution.groovy index 0f258da9d..04bf1f36b 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Plot_Exposition_Distribution.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Plot_Exposition_Distribution.groovy @@ -13,13 +13,13 @@ * @Author Valentin Le Bescond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Experimental_Matsim +package org.noise_planet.noisemodelling.scripts.Experimental_Matsim + + -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore + import org.h2gis.utilities.wrapper.ConnectionWrapper import org.jfree.chart.ChartFactory import org.jfree.chart.ChartPanel @@ -71,27 +71,10 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} -def run(input) { - // Get name of the database - String dbName = "h2gisdb" - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script @CompileStatic diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Receivers_From_Activities_Closest.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Receivers_From_Activities_Closest.groovy similarity index 87% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Receivers_From_Activities_Closest.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Receivers_From_Activities_Closest.groovy index 2349bcbef..44ced0751 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Receivers_From_Activities_Closest.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Receivers_From_Activities_Closest.groovy @@ -13,23 +13,19 @@ * @Author Valentin Le Bescond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Experimental_Matsim +package org.noise_planet.noisemodelling.scripts.Experimental_Matsim -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.GroovyRowResult import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.wrapper.ConnectionWrapper import org.locationtech.jts.geom.Geometry import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.* import groovy.sql.Sql -title = 'Chose Closest Receivers For Matsim Activities' -description = 'Chose the closest receiver in a RECEIVERS table for every Mastim Activity in an ACTIVITIES table' +title = 'Choose closest receivers for Matsim activities' +description = 'Choose the closest receiver in a RECEIVERS table for every Mastim activity in an ACTIVITIES table' inputs = [ activitiesTable : [ @@ -67,28 +63,6 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - - // Get name of the database - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - // main function of the script @CompileStatic static def exec(Connection connection, input) { diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Receivers_From_Activities_Random.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Receivers_From_Activities_Random.groovy similarity index 88% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Receivers_From_Activities_Random.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Receivers_From_Activities_Random.groovy index 113628e51..61e30c712 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Receivers_From_Activities_Random.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Receivers_From_Activities_Random.groovy @@ -13,23 +13,19 @@ * @Author Valentin Le Bescond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Experimental_Matsim +package org.noise_planet.noisemodelling.scripts.Experimental_Matsim -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.GroovyRowResult import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.wrapper.ConnectionWrapper import org.locationtech.jts.geom.Geometry import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.* import groovy.sql.Sql -title = 'Chose a Random Receivers For Matsim Activities' -description = 'Chose the closest building for every Mastim Activity in an ACTIVITIES table, and then chose a random receiver previously generated around this building.' +title = 'Choose a random receivers for Matsim activities' +description = 'Choose the closest building for every Mastim activity in an ACTIVITIES table, and then chose a random receiver previously generated around this building.' inputs = [ activitiesTable : [ @@ -59,9 +55,8 @@ inputs = [ randomSeed : [ name: 'Random seed', title: 'Random seed', - description: 'Random seed, default: 1234', - min : 0, - max : 1, + description: 'Random seed', + default : 1234, type: Integer.class ], outTableName: [ @@ -83,27 +78,6 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - - // Get name of the database - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script @CompileStatic diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Traffic_From_Events.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Traffic_From_Events.groovy similarity index 61% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Traffic_From_Events.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Traffic_From_Events.groovy index b7d973d9e..61dd23fa6 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Traffic_From_Events.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Experimental_Matsim/Traffic_From_Events.groovy @@ -13,18 +13,16 @@ * @Author Valentin Le Bescond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Experimental_Matsim +package org.noise_planet.noisemodelling.scripts.Experimental_Matsim -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.wrapper.ConnectionWrapper import org.locationtech.jts.geom.Coordinate import org.locationtech.jts.io.WKTWriter import org.matsim.api.core.v01.Coord import org.matsim.api.core.v01.Id +import org.matsim.api.core.v01.Scenario import org.matsim.api.core.v01.events.* import org.matsim.api.core.v01.events.handler.* import org.matsim.api.core.v01.network.Link @@ -36,142 +34,128 @@ import org.matsim.core.events.EventsUtils import org.matsim.core.events.MatsimEventsReader import org.matsim.core.network.io.MatsimNetworkReader import org.matsim.core.scenario.ScenarioUtils +import org.matsim.vehicles.MatsimVehicleReader import org.matsim.vehicles.Vehicle +import org.matsim.vehicles.VehicleType +import org.matsim.vehicles.Vehicles import org.noise_planet.noisemodelling.emission.road.cnossos.RoadCnossos import org.noise_planet.noisemodelling.emission.road.cnossos.RoadCnossosParameters import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.PreparedStatement - import java.io.FileNotFoundException -title = 'Import traffic data from Mastim simultaion output folder' -description = 'Read Mastim events output file in order to get traffic NoiseModelling input' +title = 'Import traffic data from Matsim simulation output folder' +description = 'Read Matsim events output file in order to get traffic NoiseModelling input' inputs = [ - folder: [ - name: 'Path of the Matsim output folder', - title: 'Path of the Matsim output folder', - description: 'Path of the Matsim output folder
    For example : /home/mastim/simulation_output' + - '
    The folder must contain at least the following files: ' + - '

    - output_network.xml.gz' + - '

    - output_events.xml.gz', - type: String.class - ], - timeBinSize: [ - name: 'The size of time bins in seconds.', - title: 'The size of time bins in seconds.', - description: 'This parameter dictates the time resolution of the resulting data ' + - '
    The time information stored will be the starting time of the time bins ' + - '
    For exemple with a timeBinSize of 3600, the data will be analysed using the following timeBins: ' + - '
    0, 3600, 7200, ..., 79200, 82800' + - '
    Default: 3600', - min: 0, - max: 1, - type: Integer.class - ], - populationFactor: [ - name: 'Population Factor', - title: 'Population Factor', - description: 'Set the population factor of the MATSim simulation' + - '
    Must be a decimal number between 0 and 1' + - '
    Default: 1.0', - min: 0, - max: 1, - type: String.class - ], - link2GeometryFile: [ - name: 'Network CSV file', - title: 'Network CSV file', - description: 'The path of the pt2matsim CSV file generated when importing OSM network. Ignored if not set.' + - '
    The file must contain at least two columns : ' + - '

    - The link ID' + - '

    - The WKT geometry', - min: 0, - max: 1, - type: String.class - ], - SRID : [ - name: 'Projection identifier', - title: 'Projection identifier', - description: 'Projection identifier (also called SRID) of the geometric data.' + - 'It should be an EPSG code, a integer with 4 or 5 digits (ex: 3857 is Web Mercator projection).' + - '
    Default value : 4326 ', - min: 0, - max: 1, - type: Integer.class - ], - exportTraffic: [ - name: 'Export additionnal traffic data ?', - title: 'Export additionnal traffic data ?', - description: 'Define if you want to output average speed and flow per vehicle category in an additional table' + - '
    Default: False', - min: 0, - max: 1, - type: Boolean.class - ], - skipUnused: [ - name: 'Skip unused links ?', - title: 'Skip unused links ?', - description: 'Define if links with unused traffic should be omitted in the output table.' + - '
    Default: True', - min: 0, - max: 1, - type: Boolean.class - ], - outTableName: [ - name: 'Output table name', - title: 'Output table name', - description: 'Name of the table you want to create.' + - '
    A table with this name will be created plus another with a "_LW" suffix' + - '
    For exemple if set to "MATSIM_ROADS (default value)":' + - '

    - the table MATSIM_ROADS, with the link ID and the geometry field' + - '

    - the table MATSIM_ROADS_LW, with the link ID and the traffic data', - min: 0, - max: 1, - type: String.class - ] + folder : [ + name : 'Path of the Matsim output folder', + title : 'Path of the Matsim output folder', + description: 'Path of the Matsim output folder
    For example : /home/matsim/simulation_output' + + '
    The folder must contain at least the following files: ' + + '

    - output_network.xml.gz' + + '

    - output_allVehicles.xml.gz' + + '

    - output_events.xml.gz', + type : String.class + ], + timeBinSize : [ + name : 'The size of time bins in seconds.', + title : 'The size of time bins in seconds.', + description: 'This parameter dictates the time resolution of the resulting data ' + + '
    The time information stored will be the starting time of the time bins ' + + '
    For exemple with a timeBinSize of 3600, the data will be analysed using the following timeBins: ' + + '
    0, 3600, 7200, ..., 79200, 82800', + default : 3600, + type : Integer.class + ], + timeBinMin : [ + name : 'The minimum of time bins in seconds', + title : 'The minimum of time bins in seconds', + description: 'The minimum of time bins in seconds', + default : 0, + type : Integer.class + ], + timeBinMax : [ + name : 'The maximum of time bins in seconds', + title : 'The maximum of time bins in seconds', + description: 'The maximum of time bins in seconds, default value: 86400 ', + default : 86400, + type : Integer.class + ], + populationFactor : [ + name : 'Population Factor', + title : 'Population Factor', + description: 'Set the population factor of the MATSim simulation' + + '
    Must be a decimal number between 0 and 1', + default : 1.0, + type : Double.class + ], + link2GeometryFile: [ + name : 'Network CSV file', + title : 'Network CSV file', + description: 'The path of the pt2matsim CSV file generated when importing OSM network. Ignored if not set.' + + '
    The file must contain at least two columns : ' + + '

    - The link ID' + + '

    - The WKT geometry', + min : 0, + max : 1, + type : String.class + ], + SRID : [ + name : 'Projection identifier', + title : 'Projection identifier', + description: 'Projection identifier (also called SRID) of the geometric data.' + + 'It should be an EPSG code, a integer with 4 or 5 digits (ex: 3857 is Web Mercator projection).', + min : 0, + max : 1, + type : Integer.class + ], + exportTraffic : [ + name : 'Export additionnal traffic data ?', + title : 'Export additionnal traffic data ?', + description: 'Define if you want to output average speed and flow per vehicle category in an additional table', + default : false, + type : Boolean.class + ], + skipUnused : [ + name : 'Skip unused links ?', + title : 'Skip unused links ?', + description: 'Define if links with unused traffic should be omitted in the output table.', + default : true, + type : Boolean.class + ], + outTableName : [ + name : 'Output table name', + title : 'Output table name', + description: 'Name of the table you want to create.' + + '
    A table with this name will be created plus another with a "_LW" suffix' + + '
    For exemple if set to "MATSIM_ROADS (default value)":' + + '

    - the table MATSIM_ROADS, with the link ID and the geometry field' + + '

    - the table MATSIM_ROADS_LW, with the link ID and the traffic data', + min : 0, + max : 1, + type : String.class + ] ] outputs = [ - result: [ - name: 'Result output string', - title: 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', - type: String.class - ] + result: [ + name : 'Result output string', + title : 'Result output string', + description: 'This type of result does not allow the blocks to be linked together.', + type : String.class + ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} -// run the script -def run(input) { - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script @CompileStatic -static def exec(Connection connection, input) { +static def exec(Connection connection, Map input) { connection = new ConnectionWrapper(connection) Sql sql = new Sql(connection) @@ -197,18 +181,10 @@ static def exec(Connection connection, input) { link2GeometryFile = input["link2GeometryFile"] } - int timeBinSize = 3600; - if (input["timeBinSize"]) { - timeBinSize = input["timeBinSize"] as int - } - int timeBinMin = 0; - if (input["timeBinMin"]) { - timeBinMin = input["timeBinMin"] as int - } - int timeBinMax = 86400; - if (input["timeBinMax"]) { - timeBinMax = input["timeBinMax"] as int - } + int timeBinSize = input.getOrDefault("timeBinSize",3600) as Integer + int timeBinMin = input.getOrDefault("timeBinMin",0) as Integer + int timeBinMax = input.getOrDefault("timeBinMax",86400) as Integer + String SRID = "4326" if (input['SRID']) { @@ -230,25 +206,27 @@ static def exec(Connection connection, input) { exportTraffic = input["exportTraffic"] as boolean } - double populationFactor = 1.0 - if (input["populationFactor"]) { - populationFactor = input["populationFactor"] as double - } + double populationFactor = input.getOrDefault("populationFactor",1.0) as Double File f String eventFile = folder + "/output_events.xml.gz" f = new File(eventFile) - if(!f.exists() || f.isDirectory()) { + if (!f.exists() || f.isDirectory()) { throw new FileNotFoundException("output_events.xml.gz not found in MATSim folder") } String networkFile = folder + "/output_network.xml.gz" f = new File(networkFile) - if(!f.exists() || f.isDirectory()) { + if (!f.exists() || f.isDirectory()) { throw new FileNotFoundException("output_network.xml.gz not found in MATSim folder") } + String vehiclesFile = folder + "/output_allVehicles.xml.gz" + f = new File(vehiclesFile) + if (!f.exists() || f.isDirectory()) { + throw new FileNotFoundException("output_allVehicles.xml.gz not found in MATSim folder") + } if (link2GeometryFile != "") { f = new File(link2GeometryFile) - if(!f.exists() || f.isDirectory()) { + if (!f.exists() || f.isDirectory()) { throw new FileNotFoundException(link2GeometryFile + " not found") } } @@ -266,57 +244,72 @@ static def exec(Connection connection, input) { sql.execute("DROP TABLE IF EXISTS " + lwTableName) sql.execute("CREATE TABLE " + lwTableName + '''( PK integer PRIMARY KEY AUTO_INCREMENT, - LINK_ID varchar(255), - LW63 double precision, LW125 double precision, LW250 double precision, LW500 double precision, LW1000 double precision, LW2000 double precision, LW4000 double precision, LW8000 double precision, - TIME int + IDSOURCE integer NOT NULL, + HZ63 double precision, HZ125 double precision, HZ250 double precision, HZ500 double precision, HZ1000 double precision, HZ2000 double precision, HZ4000 double precision, HZ8000 double precision, + PERIOD varchar(50) );''') if (exportTraffic) { sql.execute("DROP TABLE IF EXISTS " + trafficTableName) sql.execute("CREATE TABLE " + trafficTableName + '''( PK integer PRIMARY KEY AUTO_INCREMENT, - LINK_ID varchar(255), + IDSOURCE integer NOT NULL, LV_D double precision, LV_SPD_D double precision, MV_D double precision, MV_SPD_D double precision, HGV_D double precision, HGV_SPD_D double precision, - TIME int + WAV_D double precision, + WAV_SPD_D double precision, + WBV_D double precision, + WBV_SPD_D double precision, + PERIOD varchar(50) );''') } if (keepVehicleContrib) { sql.execute("DROP TABLE IF EXISTS " + contribTableName) sql.execute("CREATE TABLE " + contribTableName + '''( PK integer PRIMARY KEY AUTO_INCREMENT, - LINK_ID varchar(255), + IDSOURCE integer NOT NULL, PERSON_ID varchar(255), VEHICLE_ID varchar(255), - LW63 double precision, LW125 double precision, LW250 double precision, LW500 double precision, LW1000 double precision, LW2000 double precision, LW4000 double precision, LW8000 double precision, - TIME int + HZ63 double precision, HZ125 double precision, HZ250 double precision, HZ500 double precision, HZ1000 double precision, HZ2000 double precision, HZ4000 double precision, HZ8000 double precision, + PERIOD varchar(50) );''') } PreparedStatement roadStatement = connection.prepareStatement("INSERT INTO " + outTableName + " (LINK_ID, OSM_ID, THE_GEOM) VALUES (?, ?, ST_UpdateZ(ST_GeomFromText(?, " + SRID + "),0.05))") - PreparedStatement lwStatement = connection.prepareStatement("INSERT INTO " + lwTableName + " (LINK_ID, LW63, LW125, LW250, LW500, LW1000, LW2000, LW4000, LW8000, TIME) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") + PreparedStatement lwStatement = connection.prepareStatement("INSERT INTO " + lwTableName + " (IDSOURCE, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000, PERIOD) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") PreparedStatement trafficStatement; if (exportTraffic) { - trafficStatement = connection.prepareStatement("INSERT INTO " + trafficTableName + " (LINK_ID, LV_D, LV_SPD_D, MV_D, MV_SPD_D, HGV_D, HGV_SPD_D, TIME) VALUES (?, ?, ?, ?, ?, ?, ?, ?)") + trafficStatement = connection.prepareStatement("INSERT INTO " + trafficTableName + " (IDSOURCE, LV_D, LV_SPD_D, MV_D, MV_SPD_D, HGV_D, HGV_SPD_D, WAV_D, WAV_SPD_D, WBV_D, WBV_SPD_D, PERIOD) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") } PreparedStatement contribStatement; if (keepVehicleContrib) { - contribStatement = connection.prepareStatement("INSERT INTO " + contribTableName + " (LINK_ID, PERSON_ID, VEHICLE_ID, LW63, LW125, LW250, LW500, LW1000, LW2000, LW4000, LW8000, TIME) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") + contribStatement = connection.prepareStatement("INSERT INTO " + contribTableName + " (IDSOURCE, PERSON_ID, VEHICLE_ID, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000, PERIOD) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") } logger.info("Done Creating SQL tables") - Network network = ScenarioUtils.loadScenario(ConfigUtils.createConfig()).getNetwork() + Scenario scenario = ScenarioUtils.loadScenario(ConfigUtils.createConfig()); + + Network network = scenario.getNetwork() MatsimNetworkReader networkReader = new MatsimNetworkReader(network) + networkReader.setValidating(false) logger.info("Start reading network file ... ") networkReader.readFile(networkFile) logger.info("Done reading network file ") Map, Link> links = (Map, Link>) network.getLinks() + Vehicles vehicles = scenario.getVehicles(); + MatsimVehicleReader vehicleReader = new MatsimVehicleReader(vehicles); + logger.info("Start reading vehicles file ... ") + vehicleReader.readFile(vehiclesFile); + logger.info("Done reading vehicles file ") + + Map, Vehicle> vehicles_definitions = vehicles.getVehicles(); + EventsManager evMgr = EventsUtils.createEventsManager() ProcessOutputEventHandler evHandler = new ProcessOutputEventHandler() @@ -326,6 +319,7 @@ static def exec(Connection connection, input) { evHandler.setSRID(SRID) evHandler.setPopulationFactor(populationFactor) evHandler.initLinks((Map, Link>) links) + evHandler.initVehicles((Map, Vehicle>) vehicles_definitions) evMgr.addHandler(evHandler) @@ -342,7 +336,7 @@ static def exec(Connection connection, input) { String line = null; while ((line = br.readLine()) != null) { String[] str = line.split(",", 2) - if (str.size() > 1) { + if (str.length > 1) { link2geomData.put(str[0], str[1].trim().replace("\"", "")) } } @@ -359,10 +353,10 @@ static def exec(Connection connection, input) { if (counter >= doprint) { double elapsed = (System.currentTimeMillis() - start + 1) / 1000 logger.info(String.format("Processing Link %d (max:%d) - elapsed : %ss (%.1fit/s) - eta : %ss", - counter, evHandler.links.size(), elapsed, counter/elapsed, (evHandler.links.size() - counter) / (counter / elapsed))) + counter, evHandler.links.size(), elapsed, counter / elapsed, (evHandler.links.size() - counter) / (counter / elapsed))) doprint *= 2 } - counter ++ + counter++ if (skipUnused && !linkStatStruct.isUsed) { continue @@ -380,60 +374,60 @@ static def exec(Connection connection, input) { roadStatement.setString(2, linkStatStruct.getOsmId()) roadStatement.setString(3, geomString) roadStatement.execute() - for (int timeBin = timeBinMin ; timeBin < timeBinMax; timeBin += timeBinSize) { + for (int timeBin = timeBinMin; timeBin < timeBinMax; timeBin += timeBinSize) { int index = 1 lwStatement.setString(index, linkId) List levels = linkStatStruct.getSourceLevels(timeBin) - for (Double level: levels) { - index ++ + for (Double level : levels) { + index++ lwStatement.setDouble(index, level) } - index ++ - lwStatement.setInt(index, timeBin) + index++ + lwStatement.setString(index, timeBin.toString()) lwStatement.addBatch() } lwStatement.executeBatch() if (exportTraffic) { - for (int timeBin = timeBinMin ; timeBin < timeBinMax; timeBin += timeBinSize) { + for (int timeBin = timeBinMin; timeBin < timeBinMax; timeBin += timeBinSize) { int index = 1 trafficStatement.setString(index, linkId) - Trip.Type[] types = [Trip.Type.LV, Trip.Type.MV, Trip.Type.HV] + Trip.Type[] types = [Trip.Type.LV, Trip.Type.MV, Trip.Type.HV, Trip.Type.WAV, Trip.Type.WBV] for (Trip.Type type in types) { int count = linkStatStruct.getVehicleCount(type, timeBin) double speed = 0.0 if (count > 0) { speed = Math.round(3.6 * linkStatStruct.link.getLength() / linkStatStruct.getMeanTravelTime(type, timeBin)) } - index ++ + index++ trafficStatement.setInt(index, count) - index ++ + index++ trafficStatement.setDouble(index, speed) } - index ++ - trafficStatement.setInt(index, timeBin) + index++ + trafficStatement.setString(index, timeBin.toString()) trafficStatement.addBatch() } trafficStatement.executeBatch() } if (keepVehicleContrib) { // sql.execute(linkStatStruct.toSqlInsertContrib(contribTableName)); - for (int timeBin = 0 ; timeBin < 86400; timeBin += timeBinSize) { + for (int timeBin = 0; timeBin < 86400; timeBin += timeBinSize) { for (PersonContribFreq person_contrib : linkStatStruct.contributions.get(timeBin)) { String personId = person_contrib.personId.toString() String vehicleId = person_contrib.vehicleId.toString() List contributions = person_contrib.contributions int index = 1 contribStatement.setString(index, linkId) - index ++ + index++ contribStatement.setString(index, personId) - index ++ + index++ contribStatement.setString(index, vehicleId) - for (Double contrib: contributions) { - index ++ + for (Double contrib : contributions) { + index++ contribStatement.setDouble(index, contrib) } - index ++ - contribStatement.setInt(index, timeBin) + index++ + contribStatement.setString(index, timeBin.toString()) contribStatement.addBatch() } } @@ -443,19 +437,25 @@ static def exec(Connection connection, input) { logger.info("DONE Inserting Into SQL tables...") logger.info("Start Creating indexes on tables ...") - logger.info("CREATE INDEX " + outTableName + "_LINK_ID_IDX ON " + outTableName + " (LINK_ID);") - sql.execute("CREATE INDEX " + outTableName + "_LINK_ID_IDX ON " + outTableName + " (LINK_ID);") - logger.info("CREATE INDEX " + lwTableName + "_LINK_ID_IDX ON " + lwTableName + " (LINK_ID);") - sql.execute("CREATE INDEX " + lwTableName + "_LINK_ID_IDX ON " + lwTableName + " (LINK_ID);") - logger.info("CREATE INDEX " + lwTableName + "_TIME_IDX ON " + lwTableName + " (TIME);") - sql.execute("CREATE INDEX " + lwTableName + "_TIME_IDX ON " + lwTableName + " (TIME);") + String indexSql = "CREATE SPATIAL INDEX " + outTableName + "_GEOM_IDX ON " + outTableName + " (THE_GEOM);" + logger.info(indexSql) + sql.execute(indexSql) + indexSql = "CREATE INDEX " + lwTableName + "_IDSOURCE_IDX ON " + lwTableName + " (IDSOURCE);" + logger.info(indexSql) + sql.execute(indexSql) + indexSql = "CREATE INDEX " + lwTableName + "_PERIOD_IDX ON " + lwTableName + " (PERIOD);" + logger.info(indexSql) + sql.execute(indexSql) if (keepVehicleContrib) { - logger.info("CREATE INDEX " + contribTableName + "_LINK_ID_IDX ON " + contribTableName + " (LINK_ID);") - sql.execute("CREATE INDEX " + contribTableName + "_LINK_ID_IDX ON " + contribTableName + " (LINK_ID);") - logger.info("CREATE INDEX " + contribTableName + "_TIME_IDX ON " + contribTableName + " (TIME);") - sql.execute("CREATE INDEX " + contribTableName + "_TIME_IDX ON " + contribTableName + " (TIME);") - logger.info("CREATE INDEX " + contribTableName + "_PERSON_ID_IDX ON " + contribTableName + " (PERSON_ID);") - sql.execute("CREATE INDEX " + contribTableName + "_PERSON_ID_IDX ON " + contribTableName + " (PERSON_ID);") + indexSql = "CREATE INDEX " + contribTableName + "_IDSOURCE_IDX ON " + contribTableName + " (IDSOURCE);" + logger.info(indexSql) + sql.execute(indexSql) + indexSql = "CREATE INDEX " + contribTableName + "_PERIOD_IDX ON " + contribTableName + " (PERIOD);" + logger.info(indexSql) + sql.execute(indexSql) + indexSql = "CREATE INDEX " + contribTableName + "_PERSON_ID_IDX ON " + contribTableName + " (PERSON_ID);" + logger.info(indexSql) + sql.execute(indexSql) } logger.info("Done Creating indexes on tables.") @@ -470,6 +470,7 @@ class ProcessOutputEventHandler implements PersonEntersVehicleEventHandler, PersonLeavesVehicleEventHandler { Map, LinkStatStruct> links = new HashMap, LinkStatStruct>() + Map, Vehicle> vehicles = new HashMap, Vehicle>() Map, List>> personsInVehicle = new HashMap, List>>() int timeBinSize = 3600; int timeBinMin = 0; @@ -484,9 +485,11 @@ class ProcessOutputEventHandler implements void setTimeBinSize(int timeBinSize) { this.timeBinSize = timeBinSize } + void setTimeBinMin(int timeBinMin) { this.timeBinMin = timeBinMin } + void setTimeBinMax(int timeBinMax) { this.timeBinMax = timeBinMax } @@ -557,6 +560,7 @@ class ProcessOutputEventHandler implements Id linkId = event.getLinkId() Id vehicleId = event.getVehicleId() + Vehicle vehicle = this.vehicles.get(vehicleId); double time = event.getTime() if (!links.containsKey(linkId)) { @@ -565,12 +569,12 @@ class ProcessOutputEventHandler implements } LinkStatStruct stats = links.get(linkId) - stats.vehicleLeaveAt(vehicleId, time, personsInVehicle.get(vehicleId)) + stats.vehicleLeaveAt(vehicle, time, personsInVehicle.get(vehicleId)) links.put(linkId, stats) } void initLinks(Map, Link> netLinks) { - for (Map.Entry, Link> entry: netLinks.entrySet()) { + for (Map.Entry, Link> entry : netLinks.entrySet()) { Id linkId = entry.getKey() Link link = entry.getValue() @@ -582,11 +586,19 @@ class ProcessOutputEventHandler implements } } + def void initVehicles(Map, Vehicle> idVehicleMap) { + vehicles = idVehicleMap + } } class Trip { enum Type { - LV, MV, HV + LV, // Light vehicles + MV, // Medium vehicles + HV, // Heavy vehicles + WAV, // 2 Wheeler, 125cc or smaller + WBV, // 2 Wheeler, more than 125cc + Unknown }; public int timeBin @@ -602,6 +614,42 @@ class Trip { this.travelTime = travelTime this.persons = persons } + + static Type getTypeFromVehicle(Vehicle vehicle) { + Id vehicleId = vehicle.getId(); + VehicleType vehicleType = vehicle.getType(); + Id vehicleTypeId = vehicleType.getId() + Map vehicleAttributes = vehicleType.getAttributes().getAsMap(); + if (vehicleAttributes.containsKey("CnossosCategory")) { + String cnossos = (String) vehicleAttributes.get("CnossosCategory") + switch (cnossos) { + case "1": + return Type.LV; + case "2": + return Type.MV; + case "3": + return Type.HV; + case "4a": + return Type.WAV; + case "4b": + return Type.WBV; + } + } + if (vehicleTypeId.toString() == "Bus") { + return Type.MV + } + if (vehicleTypeId.toString().toLowerCase().contains("car") | vehicleId.toString().toLowerCase().contains("car")) { + return Type.LV + } + if (vehicleTypeId.toString().toLowerCase().contains("bus") | vehicleId.toString().toLowerCase().contains("bus")) { + return Type.MV + } + if (vehicleTypeId.toString().toLowerCase().contains("truck") | vehicleId.toString().toLowerCase().contains("truck")) { + return Type.HV + } + + return Type.Unknown + } } class PersonContrib { @@ -630,7 +678,7 @@ class PersonContribFreq { class LinkStatStruct { - public Map> trips = new HashMap >() + public Map> trips = new HashMap>() public Map, Double> enterTimes = new HashMap, Double>() public Link link @@ -668,7 +716,8 @@ class LinkStatStruct { vehicleLeaveAt(vehicleId, time, new ArrayList>()) } - void vehicleLeaveAt(Id vehicleId, double time, List> persons) { + void vehicleLeaveAt(Vehicle vehicle, double time, List> persons) { + Id vehicleId = vehicle.getId(); int timeBin = getTimeBin(time) if (!trips.containsKey(timeBin)) { trips.put(timeBin, new ArrayList()) @@ -676,15 +725,9 @@ class LinkStatStruct { if (enterTimes.containsKey(vehicleId)) { double enterTime = enterTimes.get(vehicleId) double travelTime = time - enterTime - Trip.Type type = Trip.Type.LV - if (vehicleId.toString().contains("bus")) { - type = Trip.Type.MV - } - if (vehicleId.toString().contains("tram")) { - return - } - if (vehicleId.toString().contains("rail")) { - return + Trip.Type type = Trip.getTypeFromVehicle(vehicle); + if (type == Trip.Type.Unknown) { + return; } Trip trip = new Trip(timeBin, vehicleId, type, travelTime, new ArrayList>(persons)) trips.get(timeBin).add(trip) @@ -750,6 +793,7 @@ class LinkStatStruct { } return min } + private int getTimeBin(double time) { return (time - time % timeBinSize) % 86400; } @@ -762,7 +806,13 @@ class LinkStatStruct { return levels.get(timeBin) } - static double[] calculateSourceLevels(double LVCount, double LVAvgSpeed, double MVCount, double MVAvgSpeed, double HVCount, double HVAvgSpeed) { + static double[] calculateSourceLevels( + double LVCount, double LVAvgSpeed, + double MVCount, double MVAvgSpeed, + double HVCount, double HVAvgSpeed, + double WAVCount, double WAVAvgSpeed, + double WBVCount, double WBVAvgSpeed + ) { int[] freqs = [63, 125, 250, 500, 1000, 2000, 4000, 8000] double[] result = new double[freqs.length] if (LVCount == 0 && MVCount == 0 && HVCount == 0) { @@ -773,18 +823,24 @@ class LinkStatStruct { } for (int i = 0; i < freqs.length; i++) { RoadCnossosParameters rsParametersCnossos = new RoadCnossosParameters( - LVAvgSpeed,MVAvgSpeed,HVAvgSpeed,0.0,0.0, - LVCount,MVCount,HVCount,0.0,0.0, - freqs[i],20.0,"NL08",0.0,0.0, - 100,2) + LVAvgSpeed, MVAvgSpeed, HVAvgSpeed, WAVAvgSpeed, WBVAvgSpeed, + LVCount, MVCount, HVCount, WAVCount, WBVCount, + freqs[i], 20.0, "NL08", 0.0, 0.0, + 100, 2) result[i] = RoadCnossos.evaluate(rsParametersCnossos) } return result } - static double calculateSourceLeq(double LVCount, double LVAvgSpeed, double MVCount, double MVAvgSpeed, double HVCount, double HVAvgSpeed) { - double[] levels = calculateSourceLevels(LVCount, LVAvgSpeed, MVCount, MVAvgSpeed, HVCount, HVAvgSpeed) + static double calculateSourceLeq( + double LVCount, double LVAvgSpeed, + double MVCount, double MVAvgSpeed, + double HVCount, double HVAvgSpeed, + double WAVCount, double WAVAvgSpeed, + double WBVCount, double WBVAvgSpeed + ) { + double[] levels = calculateSourceLevels(LVCount, LVAvgSpeed, MVCount, MVAvgSpeed, HVCount, HVAvgSpeed, WAVCount, WAVAvgSpeed, WBVCount, WBVAvgSpeed) double leq = -99.0 for (double level : levels) { leq = Math.log10(Math.pow(10, leq / 10.0) + Math.pow(10, level / 10.0)) @@ -792,8 +848,14 @@ class LinkStatStruct { return leq } - static double calculateSourceLAeq(double LVCount, double LVAvgSpeed, double MVCount, double MVAvgSpeed, double HVCount, double HVAvgSpeed) { - double[] levels = calculateSourceLevels(LVCount, LVAvgSpeed, MVCount, MVAvgSpeed, HVCount, HVAvgSpeed) + static double calculateSourceLAeq( + double LVCount, double LVAvgSpeed, + double MVCount, double MVAvgSpeed, + double HVCount, double HVAvgSpeed, + double WAVCount, double WAVAvgSpeed, + double WBVCount, double WBVAvgSpeed + ) { + double[] levels = calculateSourceLevels(LVCount, LVAvgSpeed, MVCount, MVAvgSpeed, HVCount, HVAvgSpeed, WAVCount, WAVAvgSpeed, WBVCount, WBVAvgSpeed) double[] aWeights = [-26.2, -16.1, -8.6, -3.2, 0, 1.2, 1.0, -1.1] double leq = -99.0 for (int i = 0; i < levels.length; i++) { @@ -825,6 +887,7 @@ class LinkStatStruct { return result } } + String getGeometryString() { Coordinate[] points = getGeometry() return WKTWriter.toLineString(points); @@ -855,20 +918,31 @@ class LinkStatStruct { } for (Trip trip in trips.get(timeBin)) { double speed = Math.round(3.6 * link.getLength() / trip.travelTime) - List trip_levels = new ArrayList(empty_levels) + double lvCount = 0.0, lvSpeed = 0.0, mvCount = 0.0, mvSpeed = 0.0, hvCount = 0.0, hvSpeed = 0.0, wavCount = 0.0, wavSpeed = 0.0, wbvCount = 0.0, wbvSpeed = 0.0; if (trip.type == Trip.Type.LV) { - trip_levels = calculateSourceLevels(vehicleCount, speed, 0, 0, 0, 0) + lvCount = vehicleCount; + lvSpeed = speed; } else if (trip.type == Trip.Type.MV) { - trip_levels = calculateSourceLevels(0, 0, 0, 0, vehicleCount, speed) + mvCount = vehicleCount; + mvSpeed = speed; } else if (trip.type == Trip.Type.HV) { - trip_levels = calculateSourceLevels(0, 0, vehicleCount, speed, 0, 0) + hvCount = vehicleCount; + hvSpeed = speed; + } else if (trip.type == Trip.Type.WAV) { + wavCount = vehicleCount; + wavSpeed = speed; + } else if (trip.type == Trip.Type.WBV) { + wbvCount = vehicleCount; + wbvSpeed = speed; } + List trip_levels = calculateSourceLevels(lvCount, lvSpeed, mvCount, mvSpeed, hvCount, hvSpeed, wavCount, wavSpeed, wbvCount, wbvSpeed) + List contribution_levels = new ArrayList(empty_levels) for (int freq = 0; freq < empty_levels.size(); freq++) { levels[timeBin][freq] = 10 * Math.log10(Math.pow(10, levels[timeBin][freq] / 10) + Math.pow(10, trip_levels[freq] / 10)) contribution_levels[freq] = trip_levels[freq] - 10 * Math.log10(trip.persons.size()) } - for (Id person_id: trip.persons) { + for (Id person_id : trip.persons) { contributions.get(timeBin).add(new PersonContribFreq(person_id, trip.vehicleId, contribution_levels)) } } diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Change_SRID.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Change_SRID.groovy similarity index 84% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Change_SRID.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Change_SRID.groovy index bf461d446..9c7a27ca5 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Change_SRID.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Change_SRID.groovy @@ -14,29 +14,24 @@ * @Author Pierre Aumond, Université Gustave Eiffel */ +package org.noise_planet.noisemodelling.scripts.Geometric_Tools -package org.noise_planet.noisemodelling.wps.Geometric_Tools - -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation import org.h2gis.utilities.wrapper.ConnectionWrapper import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.Statement title = 'Change or set SRID' -description = '➡️ Affect a new Spatial Reference Identifier (SRID) to the specified table'+ +description = '➡️ Assign a new Spatial Reference Identifier (SRID) to the specified table'+ '
    ' + '🚨 If the table:
    ' + '- has already an associated SRID: the new SRID is applied to the table and a reprojection of geometries is done,
    '+ '- has no associated SRID: the new SRID is applied to the table but without doing a reprojection of geometries.

    '+ - 'Change SRID' + 'Change SRID' inputs = [ newSRID : [ @@ -63,16 +58,6 @@ outputs = [ ] ] - -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - def exec(Connection connection, input) { //Need to change the ConnectionWrapper to WpsConnectionWrapper to work under postGIS database @@ -157,18 +142,3 @@ def exec(Connection connection, input) { // print to WPS Builder return resultString } - - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Clean_Buildings_Table.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Clean_Buildings_Table.groovy similarity index 84% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Clean_Buildings_Table.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Clean_Buildings_Table.groovy index 577c2acda..9886dcb36 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Clean_Buildings_Table.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Clean_Buildings_Table.groovy @@ -15,25 +15,21 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ +package org.noise_planet.noisemodelling.scripts.Geometric_Tools -package org.noise_planet.noisemodelling.wps.Geometric_Tools - -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation +import org.noise_planet.noisemodelling.jdbc.utils.DataBaseUtilities import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection title = 'Clean BUILDINGS Table' description = '➡️ Clean the BUILDINGS table, avoiding overlapping areas and unclosed polygons.' + '
    ' + - 'NoiseModelling propagation code does not support well intersecting polygons

    ' + + 'NoiseModelling propagation code does not support intersecting polygons well

    ' + '✅ The input table will be erased and replaced by the cleaned one.' inputs = [ @@ -58,31 +54,6 @@ outputs = [ ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - // main function of the script def exec(Connection connection, input) { @@ -111,7 +82,7 @@ def exec(Connection connection, input) { //get SRID of the table int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(building_table_name)) - if (srid == 3785 || srid == 4326) throw new IllegalArgumentException("Error : This SRID is not metric. Please use another SRID for your table.") + if (!DataBaseUtilities.isSridMetric(connection, srid)) throw new IllegalArgumentException("Error : This SRID is not metric. Please use another SRID for your table.") if (srid == 0) throw new IllegalArgumentException("Error : The table does not have an associated SRID.") diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM.groovy similarity index 89% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM.groovy index a70febac0..9169c2507 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM.groovy @@ -1,7 +1,7 @@ /** * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. * - * This version is developed by the DECIDE team FROM the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). * * * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. @@ -16,10 +16,7 @@ * @Author Gwendall Petit, Lab-STICC CNRS UMR 6285 */ - -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore +package org.noise_planet.noisemodelling.scripts.Geometric_Tools import groovy.sql.Sql import groovy.text.SimpleTemplateEngine @@ -33,7 +30,6 @@ import org.h2gis.utilities.wrapper.ConnectionWrapper import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.SQLException import java.sql.Statement @@ -52,11 +48,11 @@ description = '➡️ Insert altimetric points coming from input layer 'And six parameters:
    ' + '
      ' + '
    • Road width (roadWidth): Name of column where the road width is stored (Mandatory)
    • ' + - '
    • Roads platform height (hRoad) (Optionnal). Default value = 0m
    • ' + + '
    • Roads platform height (hRoad) (Optional). Default value = 0m
    • ' + '
    • Railroads right-of-way (railWidth): Name of column where the railroad right-of-way is stored (Mandatory)
    • ' + - '
    • Rail platform height (hRail) (Optionnal). Default value = 0.5m
    • ' + - '
    • Input SRID (inputSRID): SRID of the input tables (Optionnal)
    • ' + - '
    • Output suffixe (outputSuffixe): Suffixe applied at the end of the resuling table name (Optionnal). If not specified, "ENRICHED" is applied
    • ' + + '
    • Rail platform height (hRail) (Optional). Default value = 0.5m
    • ' + + '
    • Input SRID (inputSRID): SRID of the input tables (Optional)
    • ' + + '
    • Output suffixe (outputSuffixe): Suffixe applied at the end of the resuling table name (Optional). If not specified, "ENRICHED" is applied
    • ' + '
    ' + '
    ' + 'In the schema below, orange points will be inserted into the DEM. d2, d3 and d4 are deduced from the information provided in the parameter railWidth, using the following formula:' + @@ -110,10 +106,9 @@ inputs = [ hRoad : [ name : 'Roads platform height', title : 'Roads platform height', - description: 'Roads platform height (in meters) (Optionnal)

    '+ - '🛠 Default value = 0', - min : 0, max: 1, - type : double.class + description: 'Roads platform height (in meters) (Optional)', + default : 0, + type : Double.class ], inputRail : [ name : 'Input Railways', @@ -130,17 +125,15 @@ inputs = [ hRail : [ name : 'Rail platform height', title : 'Railways platform height', - description: 'Railways platform height (in meters) (Optionnal)

    '+ - '🛠 Default value = 0.5', - min : 0, max: 1, + description: 'Railways platform height (in meters) (Optional)', + default : 0.5, type : double.class ], outputSuffixe : [ - name : 'Output suffixe', - title : 'Output suffixe', - description: 'Suffixe applied at the end of the resuling table name

    '+ - '🛠 If not specified, "ENRICHED" is applied', - min : 0, max: 1, + name : 'Output suffix', + title : 'Output suffix', + description: 'Suffix applied at the end of the resulting table name', + default : 'ENRICHED', type : String.class ] ] @@ -191,34 +184,13 @@ static def parseScript(String sqlInstructions, Sql sql, ProgressVisitor progress } -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} -// run the script -def run(input) { - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} -def exec(Connection connection, input) { +def exec(Connection connection, Map input) { //------------------------------------------------------ @@ -279,16 +251,10 @@ def exec(Connection connection, input) { String roadWidth = input["roadWidth"] // Initialize rail platform height. Default value is 0.5m - double hRail = 0.5 - if ('hRail' in input) { - hRail = input["hRail"] as double - } + double hRail = input.getOrDefault("hRail",0.5) as Double // Initialize road platform height. Default value is 0m - double hRoad = 0 - if ('hRoad' in input) { - hRoad = input["hRoad"] as double - } + double hRoad = input.getOrDefault("hRoad",0.0) as Double // If no SRID provided, the one from DEM layer is applied Integer srid = 0 diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM_with_lines.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM_with_lines.groovy similarity index 83% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM_with_lines.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM_with_lines.groovy index b51294fe5..f87dd479c 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM_with_lines.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM_with_lines.groovy @@ -1,7 +1,7 @@ /** * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. * - * This version is developed by the DECIDE team FROM the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). * * * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. @@ -16,10 +16,7 @@ * @Author Gwendall Petit, Lab-STICC CNRS UMR 6285 */ - -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore +package org.noise_planet.noisemodelling.scripts.Geometric_Tools import groovy.sql.Sql import groovy.text.SimpleTemplateEngine @@ -33,7 +30,6 @@ import org.h2gis.utilities.wrapper.ConnectionWrapper import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.SQLException import java.sql.Statement @@ -46,11 +42,11 @@ description = '➡️ Insert altimetric points coming from linestring '
  • Digital Elevation Model (DEM) to be enriched
  • ' + '
  • A linestring layer (e.g: hydrographic network, ...) in which coordinates have a Z dimension
  • ' + '' + - 'And three optionnal parameters:
    ' + + 'And three optional parameters:
    ' + '
      ' + '
    • Input SRID (inputSRID): SRID of the input tables
    • ' + '
    • Source (source): Text indicating the source of the linestring layer. Can be useful to distinguish the points in the resulting DEM . If not specified, "LINESTRING" is applied
    • ' + - '
    • Output suffixe (outputSuffixe): Suffixe applied at the end of the resuling table name. If not specified, "ENRICHED" is applied
    • ' + + '
    • Output suffix (outputsuffix): suffix applied at the end of the resuling table name. If not specified, "ENRICHED" is applied
    • ' + '
    ' inputs = [ @@ -77,17 +73,15 @@ inputs = [ source : [ name : 'Source', title : 'Source', - description: 'Text indicating the source of the linestring layer (Optionnal)

    '+ - '🛠 If not specified, "LINESTRING" is applied', - min : 0, max: 1, + description: 'Text indicating the source of the linestring layer (Optional)', + default : 'LINESTRING', type : String.class ], - outputSuffixe : [ - name : 'Output suffixe', - title : 'Output suffixe', - description: 'Suffixe applied at the end of the resuling table name

    '+ - '🛠 If not specified, "ENRICHED" is applied', - min : 0, max: 1, + outputsuffix : [ + name : 'Output suffix', + title : 'Output suffix', + description: 'Suffix applied at the end of the resulting table name', + default : 'ENRICHED', type : String.class ] ] @@ -138,33 +132,6 @@ static def parseScript(String sqlInstructions, Sql sql, ProgressVisitor progress } -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - - - def exec(Connection connection, input) { @@ -235,14 +202,14 @@ def exec(Connection connection, input) { } - // If no output table name (outputSuffixe) provided, ENRICHED is applied + // If no output table name (outputsuffix) provided, ENRICHED is applied - String outputSuffixe = 'ENRICHED' - if ('outputSuffixe' in input) { - outputSuffixe = input["outputSuffixe"] as String + String outputsuffix = 'ENRICHED' + if ('outputsuffix' in input) { + outputsuffix = input["outputsuffix"] as String } - String enrichedDEM = input["inputDEM"] + "_" + input["outputSuffixe"] as String + String enrichedDEM = input["inputDEM"] + "_" + input["outputsuffix"] as String // print to command window @@ -252,7 +219,7 @@ def exec(Connection connection, input) { logger.info('# DEM table: ' + inputDEM) logger.info('# Linestring table: ' + inputLine) logger.info('# Source: ' + source) - logger.info('# Output suffixe: ' + outputSuffixe) + logger.info('# Output suffix: ' + outputsuffix) logger.info('--------------------------------------------') logger.info('Start enrich the DEM') @@ -341,7 +308,7 @@ def exec(Connection connection, input) { stringBuilder.append(enrich_line) stringBuilder.append(enrich_final) - def binding = ["inputDEM": inputDEM, "inputLine":inputLine, "source": source, "outputSuffixe": outputSuffixe, "srid": srid] + def binding = ["inputDEM": inputDEM, "inputLine":inputLine, "source": source, "outputsuffix": outputsuffix, "srid": srid] def template = engine.createTemplate(stringBuilder.toString()).make(binding) parseScript(template.toString(), sql, progress, logger) diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM_with_rail.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM_with_rail.groovy similarity index 85% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM_with_rail.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM_with_rail.groovy index 52902b04f..223c5cbc2 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM_with_rail.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM_with_rail.groovy @@ -1,7 +1,7 @@ /** * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. * - * This version is developed by the DECIDE team FROM the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). * * * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. @@ -16,10 +16,7 @@ * @Author Gwendall Petit, Lab-STICC CNRS UMR 6285 */ - -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore +package org.noise_planet.noisemodelling.scripts.Geometric_Tools import groovy.sql.Sql import groovy.text.SimpleTemplateEngine @@ -33,7 +30,6 @@ import org.h2gis.utilities.wrapper.ConnectionWrapper import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.SQLException import java.sql.Statement @@ -49,9 +45,9 @@ description = '➡️ Insert altimetric points coming from railways in 'And four parameters:
    ' + '
      ' + '
    • Railroads right-of-way (railWidth): Name of column where the railroad right-of-way is stored (Mandatory)
    • ' + - '
    • Rail platform height (hRail): Railways platform height (Optionnal). Default value = 0.5m
    • ' + - '
    • Input SRID (inputSRID): SRID of the input tables (Optionnal)
    • ' + - '
    • Output suffixe (outputSuffixe): Suffixe applied at the end of the resuling table name (Optionnal). If not specified, "ENRICHED" is applied
    • ' + + '
    • Rail platform height (hRail): Railways platform height (Optional). Default value = 0.5m
    • ' + + '
    • Input SRID (inputSRID): SRID of the input tables (Optional)
    • ' + + '
    • Output suffix (outputsuffix): suffix applied at the end of the resuling table name (Optional). If not specified, "ENRICHED" is applied
    • ' + '
    ' + '
    ' + 'In the schema below, orange points will be inserted into the DEM. d2, d3 and d4 are deduced from the information provided in the parameter railWidth, using the following formula:' + @@ -92,17 +88,16 @@ inputs = [ hRail : [ name : 'Rail platform height', title : 'Railways platform height', - description: 'Railways platform height (in meters) (Optionnal)

    '+ - '🛠 Default value = 0.5', - min : 0, max: 1, + description: 'Railways platform height (in meters) (Optional)', + default : 0.5, type : double.class ], - outputSuffixe : [ - name : 'Output suffixe', - title : 'Output suffixe', - description: 'Suffixe applied at the end of the resuling table name

    '+ + outputsuffix : [ + name : 'Output suffix', + title : 'Output suffix', + description: 'Suffix applied at the end of the resulting table name

    '+ '🛠 If not specified, "ENRICHED" is applied', - min : 0, max: 1, + default : 'ENRICHED', type : String.class ] ] @@ -153,33 +148,6 @@ static def parseScript(String sqlInstructions, Sql sql, ProgressVisitor progress } -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - - - def exec(Connection connection, input) { @@ -237,10 +205,7 @@ def exec(Connection connection, input) { String railWidth = input["railWidth"] // Initialize rail platform height. Default value is 0.5m - double hRail = 0.5 - if ('hRail' in input) { - hRail = input["hRail"] as double - } + double hRail = input.getOrDefault("hRail",0.5) as Double // If no SRID provided, the one from DEM layer is applied Integer srid = 0 @@ -251,12 +216,12 @@ def exec(Connection connection, input) { srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(inputDEM)) } - // If no output table name (outputSuffixe) provided, ENRICHED is applied - String outputSuffixe = 'ENRICHED' - if ('outputSuffixe' in input) { - outputSuffixe = input["outputSuffixe"] as String + // If no output table name (outputsuffix) provided, ENRICHED is applied + String outputsuffix = 'ENRICHED' + if ('outputsuffix' in input) { + outputsuffix = input["outputsuffix"] as String } - String enrichedDEM = input["inputDEM"] + "_" + input["outputSuffixe"] as String + String enrichedDEM = input["inputDEM"] + "_" + input["outputsuffix"] as String // print to command window logger.info('List of the input parameters:') @@ -266,7 +231,7 @@ def exec(Connection connection, input) { logger.info('# Railways network table: ' + inputRail) logger.info('# Railways width column: ' + railWidth) logger.info('# Railways platform height: ' + hRail) - logger.info('# Output suffixe: ' + outputSuffixe) + logger.info('# Output suffix: ' + outputsuffix) logger.info('--------------------------------------------') logger.info('Start enrich the DEM') @@ -352,7 +317,7 @@ def exec(Connection connection, input) { stringBuilder.append(enrich_rail) stringBuilder.append(enrich_final) - def binding = ["inputDEM": inputDEM, "inputRail": inputRail, "railWidth": railWidth, "outputSuffixe": outputSuffixe, "srid": srid, "hRail": hRail] + def binding = ["inputDEM": inputDEM, "inputRail": inputRail, "railWidth": railWidth, "outputsuffix": outputsuffix, "srid": srid, "hRail": hRail] def template = engine.createTemplate(stringBuilder.toString()).make(binding) parseScript(template.toString(), sql, progress, logger) diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM_with_road.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM_with_road.groovy similarity index 87% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM_with_road.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM_with_road.groovy index e6eef2fd8..da8449975 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_DEM_with_road.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_DEM_with_road.groovy @@ -1,9 +1,7 @@ -package org.noise_planet.noisemodelling.wps.Geometric_Tools - /** * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. * - * This version is developed by the DECIDE team FROM the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). * * * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. @@ -18,14 +16,11 @@ package org.noise_planet.noisemodelling.wps.Geometric_Tools * @Author Gwendall Petit, Lab-STICC CNRS UMR 6285 */ +package org.noise_planet.noisemodelling.scripts.Geometric_Tools - -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql import groovy.text.SimpleTemplateEngine import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore import org.h2.util.ScriptReader import org.h2gis.api.ProgressVisitor import org.h2gis.utilities.GeometryTableUtilities @@ -34,7 +29,6 @@ import org.h2gis.utilities.TableLocation import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.SQLException import java.sql.Statement @@ -86,17 +80,15 @@ inputs = [ hRoad : [ name : 'Roads platform height', title : 'Roads platform height', - description: 'Roads platform height (in meters) (Optional)

    '+ - '🛠 Default value = 0', - min : 0, max: 1, - type : double.class + description: 'Roads platform height (in meters) (Optional)', + default : 0, + type : Double.class ], outputSuffix : [ name : 'Output suffix', title : 'Output suffix', - description: 'Suffix applied at the end of the resulting table name

    '+ - '🛠 If not specified, "ENRICHED" is applied', - min : 0, max: 1, + description: 'Suffix applied at the end of the resulting table name', + default : 'ENRICHED', type : String.class ] ] @@ -147,33 +139,6 @@ static def parseScript(String sqlInstructions, Sql sql, ProgressVisitor progress } -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - - - def exec(Connection connection, input) { // Create a logger to display messages in the geoserver logs and in the command prompt. @@ -196,10 +161,7 @@ def exec(Connection connection, input) { String roadWidth = input["roadWidth"] // Initialize road platform height. Default value is 0m - double hRoad = 0 - if ('hRoad' in input) { - hRoad = input["hRoad"] as double - } + double hRoad = input.getOrDefault("hRoad",0.0) as Double // If no SRID provided, the one from DEM layer is applied Integer srid = 0 diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_Landcover_with_rail.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_Landcover_with_rail.groovy similarity index 88% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_Landcover_with_rail.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_Landcover_with_rail.groovy index a770fa56f..8e389f7ea 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Enrich_Landcover_with_rail.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Enrich_Landcover_with_rail.groovy @@ -1,7 +1,7 @@ /** * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. * - * This version is developed by the DECIDE team FROM the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). * * * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. @@ -16,10 +16,7 @@ * @Author Gwendall Petit, Lab-STICC CNRS UMR 6285 */ - -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore +package org.noise_planet.noisemodelling.scripts.Geometric_Tools import groovy.sql.Sql import groovy.text.SimpleTemplateEngine @@ -33,7 +30,6 @@ import org.h2gis.utilities.wrapper.ConnectionWrapper import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.SQLException import java.sql.Statement @@ -49,9 +45,9 @@ description = '➡️ Insert rail ground surfaces into the input LANDC 'And four parameters:
    ' + '
      ' + '
    • Railroads right-of-way (railWidth): Name of column where the railroad right-of-way is stored (Mandatory)
    • ' + - '
    • Rail platform height (hRail): Railways platform height (Optionnal). Default value = 0.5m
    • ' + - '
    • Input SRID (inputSRID): SRID of the input tables (Optionnal)
    • ' + - '
    • Output suffixe (outputSuffixe): Suffixe applied at the end of the resuling table name (Optionnal). If not specified, "ENRICHED" is applied
    • ' + + '
    • Rail platform height (hRail): Railways platform height (Optional). Default value = 0.5m
    • ' + + '
    • Input SRID (inputSRID): SRID of the input tables (Optional)
    • ' + + '
    • Output suffix (outputsuffix): suffix applied at the end of the resuling table name (Optional). If not specified, "ENRICHED" is applied
    • ' + '
    ' + '
    ' + 'In the schema below, orange points will be inserted into the DEM. d2, d3 and d4 are deduced from the information provided in the parameter railWidth, using the following formula:' + @@ -80,7 +76,7 @@ inputs = [ gColumn : [ name : 'G column', title : 'G column', - description: 'Ground absorption coeffecient (G) column name', + description: 'Ground absorption coefficient (G) column name', type : String.class ], inputRail : [ @@ -95,12 +91,11 @@ inputs = [ description: 'Name of column where the railways width is stored', type : String.class ], - outputSuffixe : [ - name : 'Output suffixe', - title : 'Output suffixe', - description: 'Suffixe applied at the end of the resuling table name

    '+ - '🛠 If not specified, "ENRICHED" is applied', - min : 0, max: 1, + outputsuffix : [ + name : 'Output suffix', + title : 'Output suffix', + description: 'Suffix applied at the end of the resulting table name', + default : 'ENRICHED', type : String.class ] ] @@ -151,30 +146,9 @@ static def parseScript(String sqlInstructions, Sql sql, ProgressVisitor progress } -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} -// run the script -def run(input) { - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} @@ -244,12 +218,12 @@ def exec(Connection connection, input) { srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(inputLandcover)) } - // If no output table name (outputSuffixe) provided, ENRICHED is applied - String outputSuffixe = 'ENRICHED' - if ('outputSuffixe' in input) { - outputSuffixe = input["outputSuffixe"] as String + // If no output table name (outputsuffix) provided, ENRICHED is applied + String outputsuffix = 'ENRICHED' + if ('outputsuffix' in input) { + outputsuffix = input["outputsuffix"] as String } - String enrichedLandcover = input["inputLandcover"] + "_" + input["outputSuffixe"] as String + String enrichedLandcover = input["inputLandcover"] + "_" + input["outputsuffix"] as String // print to command window logger.info('List of the input parameters:') @@ -259,7 +233,7 @@ def exec(Connection connection, input) { logger.info('# Landcover G column: ' + gColumn) logger.info('# Railways network table: ' + inputRail) logger.info('# Railways width column: ' + railWidth) - logger.info('# Output suffixe: ' + outputSuffixe) + logger.info('# Output suffix: ' + outputsuffix) logger.info('--------------------------------------------') logger.info('Start enrich the Landcover') @@ -375,7 +349,7 @@ def exec(Connection connection, input) { stringBuilder.append(import_rail) stringBuilder.append(queries_landcover_rail) - def binding = ["inputLandcover": inputLandcover, "gColumn": gColumn, "inputRail": inputRail, "railWidth": railWidth, "outputSuffixe": outputSuffixe, "srid": srid] + def binding = ["inputLandcover": inputLandcover, "gColumn": gColumn, "inputRail": inputRail, "railWidth": railWidth, "outputsuffix": outputsuffix, "srid": srid] def template = engine.createTemplate(stringBuilder.toString()).make(binding) parseScript(template.toString(), sql, progress, logger) diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Point_Source_0dB_From_Network.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Point_Source_0dB_From_Network.groovy similarity index 78% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Point_Source_0dB_From_Network.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Point_Source_0dB_From_Network.groovy index ba62c0e86..6e55d287d 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Point_Source_0dB_From_Network.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Point_Source_0dB_From_Network.groovy @@ -13,12 +13,9 @@ * @Author Valentin Le Bescond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Geometric_Tools +package org.noise_planet.noisemodelling.scripts.Geometric_Tools -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.GeometryMetaData import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.TableLocation @@ -26,10 +23,9 @@ import org.h2gis.utilities.dbtypes.DBUtils import org.h2gis.utilities.wrapper.ConnectionWrapper import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection -title = 'Create 0db Source From Roads' +title = 'Create 0 dB Source From Roads' description = '➡️ Creates a SOURCE table from a ROAD table.' + '
    ' + 'The SOURCE table can then be used in the Noise_level_from_source WPS block with the "confExportSourceId" set to true.

    ' + @@ -47,7 +43,8 @@ inputs = [ ], gridStep : [name : 'gridStep', title : "gridStep", - description : "Distance between location of vehicle along the network in meters.
    Default value : 10 ", + description : "Distance between location of vehicle along the network in meters.", + default : 10, type: Integer.class] ] @@ -60,30 +57,7 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - - // Get name of the database - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - - -def exec(connection, input) { +def exec(connection,Map input) { double h = 0.05 // height of the source (0.05 m) @@ -97,16 +71,11 @@ def exec(connection, input) { logger.info('Start : Create_0db_Source_From_Roads') logger.info("inputs {}", input) - int gridStep = 10 - if (input['gridStep']) { - gridStep = Integer.valueOf(input['gridStep'] as String) - } - + int gridStep = input.getOrDefault("gridStep",10) as Integer String roadsTableName = input['tableRoads'] - sql.execute("DROP TABLE IF EXISTS SOURCES_0dB") sql.execute("CREATE TABLE SOURCES_0DB (PK BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, ROAD_ID BIGINT, THE_GEOM GEOMETRY, HZ63 FLOAT, HZ125 FLOAT, HZ250 FLOAT, HZ500 FLOAT, HZ1000 FLOAT, HZ2000 FLOAT, HZ4000 FLOAT, HZ8000 FLOAT);"); sql.execute("INSERT INTO SOURCES_0DB (ROAD_ID, THE_GEOM, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000) SELECT r.PK AS ROAD_ID, ST_Densify(r.THE_GEOM, "+gridStep+") AS THE_GEOM, 0.0 AS HZ63, 0.0 AS HZ125, 0.0 AS HZ250, 0.0 AS HZ500, 0.0 AS HZ1000, 0.0 AS HZ2000, 0.0 AS HZ4000, 0.0 AS HZ8000 FROM "+roadsTableName+" r;"); @@ -127,4 +96,3 @@ def exec(connection, input) { logger.info('Result : ' + resultString) return resultString } - diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Screen_to_building.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Screen_to_building.groovy similarity index 86% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Screen_to_building.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Screen_to_building.groovy index 5305e7dc3..f6cc2ddf5 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Screen_to_building.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Screen_to_building.groovy @@ -15,23 +15,19 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ +package org.noise_planet.noisemodelling.scripts.Geometric_Tools -package org.noise_planet.noisemodelling.wps.Geometric_Tools - -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.GeometryTableUtilities +import org.noise_planet.noisemodelling.jdbc.utils.DataBaseUtilities import org.h2gis.utilities.TableLocation import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection -title = 'Convert screens to building format.' -description = '➡️ Convert the screens to the building format. ' + +title = 'Convert screens to building format' +description = '➡️ Convert the screens to the building format.' + '
    ' + 'A width of 10 cm will be defined. If you also give a building table, this WPS script allows you to merge the two layers together.

    ' + 'Tables must be projected in a same metric coordinate system (SRID). Use "Change_SRID" WPS Block if needed.

    ' + @@ -51,7 +47,8 @@ inputs = [ type : String.class ], tableScreens : [ - name : 'Screens table name', title: 'Screens table name', + name : 'Screens table name', + title : 'Screens table name', description: 'Name of the Screens table.

    ' + 'The table must contain:
    ' + '- THE_GEOM : the 2D geometry of the screens (POLYGON or MULTIPOLYGON).
    ' + @@ -69,31 +66,6 @@ outputs = [ ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - // main function of the script def exec(Connection connection, input) { @@ -133,12 +105,12 @@ def exec(Connection connection, input) { //get SRID of the table int sridScreens = GeometryTableUtilities.getSRID(connection, TableLocation.parse(screen_table_name)) - if (sridScreens == 3785 || sridScreens == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for Screens.") + if (!DataBaseUtilities.isSridMetric(connection, sridScreens)) throw new IllegalArgumentException("Error : Please use a metric projection for Screens.") if (sridScreens == 0) throw new IllegalArgumentException("Error : The table screens does not have an associated SRID.") //get SRID of the table int sridBuildings = GeometryTableUtilities.getSRID(connection, TableLocation.parse(building_table_name)) - if (sridBuildings == 3785 || sridBuildings == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for Buildings.") + if (!DataBaseUtilities.isSridMetric(connection, sridBuildings)) throw new IllegalArgumentException("Error : Please use a metric projection for Buildings.") if (sridBuildings == 0) throw new IllegalArgumentException("Error : The table buildings does not have an associated SRID.") if (sridBuildings != sridScreens) throw new IllegalArgumentException("Error : The SRID of table screens and buildings are not the same.") @@ -208,4 +180,3 @@ def exec(Connection connection, input) { return resultString } - diff --git a/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Set_Height.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Set_Height.groovy new file mode 100644 index 000000000..c2591fc0b --- /dev/null +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Set_Height.groovy @@ -0,0 +1,121 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + +/** + * @Author Aumond Pierre, Université Gustave Eiffel + */ + +package org.noise_planet.noisemodelling.scripts.Geometric_Tools + +import groovy.sql.Sql +import org.h2gis.utilities.GeometryMetaData +import org.h2gis.utilities.GeometryTableUtilities +import org.h2gis.utilities.TableLocation +import org.h2gis.utilities.dbtypes.DBUtils +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.sql.Connection + +title = 'Set Height' +description = '➡️ Update the geometry by adding a height from the column in the input table that contains the heights or elevations or from a static value.' + +inputs = [ + tableName: [ + title : 'Name of the table', + name : 'Name of the table', + description: 'Name of the table on which the height will be modified.', + type : String.class + ], + height: [ + name : 'New height', + title : 'New height', + description: 'New height for the input table (in meters) (FLOAT)', + type : Double.class, + min : 0, max: 1, + ], + heightColumn: [ + name : 'heightColumn', + title : 'heightColumn', + description: 'The column name in the input table that contains the heights', + type : String.class, + min : 0, max: 1, + ] + +] + +outputs = [ + result: [ + name : 'Result output string', + title : 'Result output string', + description: 'This type of result does not allow the blocks to be linked together.', + type : String.class + ] +] + +def exec(Connection connection, Map input) { + + // output string, the information given back to the user + String resultString = "" + + // Create a sql connection to interact with the database in SQL + Sql sql = new Sql(connection) + + // Create a logger to display messages in the geoserver logs and in the command prompt. + Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") + + // print to command window + logger.info('Start : Set new height') + logger.info("inputs {}", input) // log inputs of the run + + String table_name = input['tableName'] as String + table_name = table_name.toUpperCase() + String geometryColumnName = GeometryTableUtilities.getGeometryColumnNames(connection, table_name).get(0) + + if(input.containsKey('height')){ + Double h = input['height'] as Double + GeometryMetaData metaData = GeometryTableUtilities.getMetaData(connection, TableLocation.parse(table_name, DBUtils.getDBType(connection)), "THE_GEOM"); + metaData.setHasZ(true) + metaData.initGeometryType() + connection.createStatement().execute(String.format(Locale.ROOT, "ALTER TABLE %s ALTER COLUMN %s %s USING ST_UPDATEZ(%s, %f)", + TableLocation.parse(table_name, DBUtils.getDBType(connection)), geometryColumnName , metaData.getSQL(), geometryColumnName, h)) + + resultString = "Process done. Table of " + table_name + " has now a new height set to " + h + "." + + logger.info('End : Set new height') + + return resultString + } else if(input.containsKey('heightColumn')){ + def st = connection.createStatement() + String height_column = input['heightColumn'] as String + height_column = st.enquoteIdentifier(height_column, false) + GeometryMetaData metaData = GeometryTableUtilities.getMetaData(connection, TableLocation.parse(table_name, DBUtils.getDBType(connection)), "THE_GEOM"); + metaData.setHasZ(true) + metaData.initGeometryType() + String sqlUpdate = String.format(Locale.ROOT, + "ALTER TABLE %s ALTER COLUMN %s %s USING ST_UPDATEZ(%s, %s)", + TableLocation.parse(table_name, DBUtils.getDBType(connection)), + geometryColumnName, + metaData.getSQL(), + geometryColumnName, + height_column + ) + + connection.createStatement().execute(sqlUpdate) + + resultString = "Process done. The " + table_name + " table has now new heights set from column " + height_column + "." + + logger.info('End : Set height by column name') + + return resultString + } + +} diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Simplify_Geometries.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Simplify_Geometries.groovy similarity index 67% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Simplify_Geometries.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Simplify_Geometries.groovy index 2ae6ccde1..72cafc22b 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Simplify_Geometries.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Simplify_Geometries.groovy @@ -1,139 +1,120 @@ -/** - * @Author Tomáš Anda - */ - -package org.noise_planet.noisemodelling.wps.Geometric_Tools - -import geoserver.GeoServer -import geoserver.catalog.Store -import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore -import org.h2gis.utilities.TableLocation -import org.h2gis.utilities.wrapper.ConnectionWrapper -import org.h2gis.utilities.GeometryTableUtilities -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import java.sql.Connection -import java.sql.SQLException - -title = 'Simplify geometries' - -description = '➡️ Use Douglas-Peucker algorithm to simplify geometries in the selected table.' + - '
    ' + - '✅ The input table geometries will be updated.' - -inputs = [ - tableName: [ - title : 'Name of the table', - name : 'Name of the table', - description: 'Name of the table on which geometries will be simplified.', - type : String.class - ], - distanceTolerance: [ - name : 'Distance tolerance', - title : 'Distance tolerance', - description: 'Sets the tolerance distance for the simplification (FLOAT).

    ' + - '🛠 Default value: 1 ', - min : 0, max: 1, - type : Double.class - ], - preserveTopology: [ - title : 'Preserve topology ?', - name : 'Preserve topology ?', - description: 'Do you want to preserve topology?

    ' + - '🛠 Default value: false ', - min : 0, max: 1, - type : Boolean.class - ] -] - -outputs = [ - result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', - type : String.class - ] -] - -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -def exec(Connection connection, input) { - - // Need to change the ConnectionWrapper to WpsConnectionWrapper to work under postGIS database - connection = new ConnectionWrapper(connection) - - // Create a sql connection to interact with the database in SQL - Sql sql = new Sql(connection) - - // Output string, the information given back to the user - String resultString = null - - // Create a logger to display messages in the geoserver logs and in the command prompt. - Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") - - // Print to command window - logger.info('Start : Template') - logger.info("inputs {}", input) // log inputs of the run - - Double distanceTolerance = 1 - if (input['distanceTolerance']) { - distanceTolerance = input['distanceTolerance'] as Double - } - - String table_name = input['tableName'] as String - table_name = table_name.toUpperCase() - - // Get the geometry field of the source table - TableLocation sourceTableIdentifier = TableLocation.parse(table_name) - List geomFields = GeometryTableUtilities.getGeometryFields(connection, sourceTableIdentifier) - if (geomFields.isEmpty()) { - throw new SQLException(String.format("The table %s does not exists or does not contain a geometry field", sourceTableIdentifier)) - } - - // Get the SRID of the table and check if it's in a metric projection - int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(table_name)) - if (srid == 3785 || srid == 4326) throw new IllegalArgumentException("Error : This SRID is not metric. Please use another SRID for your table.") - if (srid == 0) throw new IllegalArgumentException("Error : The table does not have an associated SRID.") - - Boolean preserveTopology = false; - if (input['preserveTopology']) { - preserveTopology = input['preserveTopology'] - } - - if (preserveTopology) { - sql.execute("UPDATE " + table_name + " SET THE_GEOM = ST_SETSRID(ST_SimplifyPreserveTopology(THE_GEOM, " + distanceTolerance + "), " + srid + ");") - } else { - logger.info('Topology may not be preserved and may result in invalid geometries') - sql.execute("UPDATE " + table_name + " SET THE_GEOM = ST_SETSRID(ST_Simplify(THE_GEOM, " + distanceTolerance + "), " + srid + ");") - } - - resultString = "Process done. Geometries in table " + table_name + " have been simplified." - - logger.info('End : Geometries simplified') - - return resultString -} - +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + +/** + * @Author Tomáš Anda + */ + +package org.noise_planet.noisemodelling.scripts.Geometric_Tools + +import groovy.sql.Sql +import org.h2gis.utilities.TableLocation +import org.h2gis.utilities.wrapper.ConnectionWrapper +import org.h2gis.utilities.GeometryTableUtilities +import org.noise_planet.noisemodelling.jdbc.utils.DataBaseUtilities +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.sql.Connection +import java.sql.SQLException + +title = 'Simplify geometries' + +description = '➡️ Use Douglas-Peucker algorithm to simplify geometries in the selected table.' + + '
    ' + + '✅ The input table geometries will be updated.' + +inputs = [ + tableName: [ + title : 'Name of the table', + name : 'Name of the table', + description: 'Name of the table on which geometries will be simplified', + type : String.class + ], + distanceTolerance: [ + name : 'Distance tolerance', + title : 'Distance tolerance', + description: 'Sets the tolerance distance for the simplification (FLOAT)', + default : 1, + type : Double.class + ], + preserveTopology: [ + title : 'Preserve topology ?', + name : 'Preserve topology ?', + description: 'Do you want to preserve topology?', + default : false, + type : Boolean.class + ] +] + +outputs = [ + result: [ + name : 'Result output string', + title : 'Result output string', + description: 'This type of result does not allow the blocks to be linked together.', + type : String.class + ] +] + + +def exec(Connection connection, Map input) { + + // Need to change the ConnectionWrapper to WpsConnectionWrapper to work under postGIS database + connection = new ConnectionWrapper(connection) + + // Create a sql connection to interact with the database in SQL + Sql sql = new Sql(connection) + + // Output string, the information given back to the user + String resultString = null + + // Create a logger to display messages in the geoserver logs and in the command prompt. + Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") + + // Print to command window + logger.info('Start : Template') + logger.info("inputs {}", input) // log inputs of the run + + Double distanceTolerance = input.getOrDefault("distanceTolerance",1.0) as Double + + String table_name = input['tableName'] as String + table_name = table_name.toUpperCase() + + // Get the geometry field of the source table + TableLocation sourceTableIdentifier = TableLocation.parse(table_name) + List geomFields = GeometryTableUtilities.getGeometryFields(connection, sourceTableIdentifier) + if (geomFields.isEmpty()) { + throw new SQLException(String.format("The table %s does not exists or does not contain a geometry field", sourceTableIdentifier)) + } + + // Get the SRID of the table and check if it's in a metric projection + int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(table_name)) + if (!DataBaseUtilities.isSridMetric(connection, srid)) throw new IllegalArgumentException("Error : This SRID is not metric. Please use another SRID for your table.") + if (srid == 0) throw new IllegalArgumentException("Error : The table does not have an associated SRID.") + + Boolean preserveTopology = false; + if (input['preserveTopology']) { + preserveTopology = input['preserveTopology'] + } + + if (preserveTopology) { + sql.execute("UPDATE " + table_name + " SET THE_GEOM = ST_SETSRID(ST_SimplifyPreserveTopology(THE_GEOM, " + distanceTolerance + "), " + srid + ");") + } else { + logger.info('Topology may not be preserved and may result in invalid geometries') + sql.execute("UPDATE " + table_name + " SET THE_GEOM = ST_SETSRID(ST_Simplify(THE_GEOM, " + distanceTolerance + "), " + srid + ");") + } + + resultString = "Process done. Geometries in table " + table_name + " have been simplified." + + logger.info('End : Geometries simplified') + + return resultString +} diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Export_Table.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Export_Table.groovy similarity index 74% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Export_Table.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Export_Table.groovy index 8cdd1f3d9..8242eed44 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Export_Table.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Export_Table.groovy @@ -15,12 +15,9 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Import_and_Export +package org.noise_planet.noisemodelling.scripts.Import_and_Export -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore -import org.h2gis.api.EmptyProgressVisitor +import org.h2gis.api.ProgressVisitor import org.h2gis.functions.io.csv.CSVDriverFunction import org.h2gis.functions.io.dbf.DBFDriverFunction import org.h2gis.functions.io.fgb.FGBDriverFunction @@ -29,19 +26,19 @@ import org.h2gis.functions.io.json.JsonDriverFunction import org.h2gis.functions.io.kml.KMLDriverFunction import org.h2gis.functions.io.shp.SHPDriverFunction import org.h2gis.functions.io.tsv.TSVDriverFunction -import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.GeometryTableUtilities +import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation +import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection title = 'Export table' description = '➡️ Export table from the database into a local file.
    '+ '
    ' + 'Valid file extensions: csv, dbf, geojson, gpx, bz2, gz, osm, shp, tsv, fgb

    ' + - 'Export table' + 'Export table' inputs = [ exportPath : [ @@ -54,30 +51,26 @@ inputs = [ tableToExport: [ name: 'Name of the table to export', title: 'Name of the table', - description: 'Name of the table you want to export', + description: 'Table Name or SQL Query

    ' + + 'Option 1: Simple table name
    ' + + 'Enter the name of an existing table, e.g.: mytable

    ' + + 'Option 2: SQL query with parenthesis
    ' + + 'Wrap your SELECT query in parenthesis to export filtered or joined data
    ' + + 'Example:
    (SELECT * FROM mytable WHERE field = 1)', type: String.class ] ] outputs = [ result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', + name : 'Exported table name', + title : 'Exported table name', + description: 'The name of the exported table, can be used as input for another process', type : String.class ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -def exec(Connection connection, input) { +def exec(Connection connection, Map input, ProgressVisitor progress) { // output string, the information given back to the user String resultString = null @@ -110,35 +103,35 @@ def exec(Connection connection, input) { switch (ext) { case "csv": CSVDriverFunction csvDriver = new CSVDriverFunction() - csvDriver.exportTable(connection, tableToExport, new File(exportPath), true, new EmptyProgressVisitor()) + csvDriver.exportTable(connection, tableToExport, new File(exportPath), true, progress) break case "dbf": DBFDriverFunction dbfDriver = new DBFDriverFunction() - dbfDriver.exportTable(connection, tableToExport, new File(exportPath),true, new EmptyProgressVisitor()) + dbfDriver.exportTable(connection, tableToExport, new File(exportPath),true, progress) break case "geojson": GeoJsonDriverFunction geoJsonDriver = new GeoJsonDriverFunction() - geoJsonDriver.exportTable(connection, tableToExport, new File(exportPath),true, new EmptyProgressVisitor()) + geoJsonDriver.exportTable(connection, tableToExport, new File(exportPath),true, progress) break case "json": JsonDriverFunction jsonDriver = new JsonDriverFunction() - jsonDriver.exportTable(connection, tableToExport, new File(exportPath),true, new EmptyProgressVisitor()) + jsonDriver.exportTable(connection, tableToExport, new File(exportPath),true, progress) break case "kml": KMLDriverFunction kmlDriver = new KMLDriverFunction() - kmlDriver.exportTable(connection, tableToExport, new File(exportPath),true, new EmptyProgressVisitor()) + kmlDriver.exportTable(connection, tableToExport, new File(exportPath),true, progress) break case "shp": SHPDriverFunction shpDriver = new SHPDriverFunction() - shpDriver.exportTable(connection, tableToExport, new File(exportPath),true, new EmptyProgressVisitor()) + shpDriver.exportTable(connection, tableToExport, new File(exportPath),true, progress) break case "tsv": TSVDriverFunction tsvDriver = new TSVDriverFunction() - tsvDriver.exportTable(connection, tableToExport, new File(exportPath), true, new EmptyProgressVisitor()) + tsvDriver.exportTable(connection, tableToExport, new File(exportPath), true, progress) break case "fgb": FGBDriverFunction fgbDriver = new FGBDriverFunction() - fgbDriver.exportTable(connection, tableToExport, new File(exportPath), true, new EmptyProgressVisitor()) + fgbDriver.exportTable(connection, tableToExport, new File(exportPath), true, progress) break default: throw new Exception("The file extension is not valid. No table has been exported.") @@ -163,20 +156,11 @@ def exec(Connection connection, input) { logger.info(resultString) logger.info('End : Export File') // print to WPS Builder - return resultString + return [result: tableToExport] } -def run(input) { - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } +def exec(Connection connection, Map input) { + return exec(connection, input, new RootProgressVisitor(1, true, 5)) } \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Asc_File.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Asc_File.groovy similarity index 81% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Asc_File.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Asc_File.groovy index 7f59059ce..72e52fb3c 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Asc_File.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Asc_File.groovy @@ -14,11 +14,8 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Import_and_Export +package org.noise_planet.noisemodelling.scripts.Import_and_Export -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore import org.h2gis.functions.io.asc.AscReaderDriver import org.h2gis.functions.io.utility.PRJUtil import org.h2gis.functions.spatial.crs.ST_SetSRID @@ -30,23 +27,22 @@ import org.locationtech.jts.io.WKTWriter import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.Statement title = 'Import Asc File.' description = '➡️ Import ESRI Ascii Raster file and convert into a Digital Elevation Model (DEM) compatible with NoiseModelling (X,Y,Z).
    '+ '
    ' + - ' Valid file extensions : asc.

    ' + + ' Valid file extensions : asc and asc.gz .

    ' + '✅ The output table is called: DEM and contain:
    ' + '- THE_GEOM: the 3D point cloud of the DEM (POINT)

    ' + - 'Import asc file' + 'Import asc file' inputs = [ pathFile : [ name : 'Path of the input File', title : 'Path of the ESRI Ascii Raster file', - description: '📂 Path of the ESRI Ascii Raster file you want to import, including its extension. Can be gzip compressed.

    ' + + description: '📂 Path of the ESRI Ascii Raster file you want to import, including its extension. Files can be gzip compressed.

    ' + 'For example: c:/home/receivers.asc or c:/home/receivers.asc.gz', type : String.class ], @@ -54,10 +50,10 @@ inputs = [ name : 'Projection identifier', title : 'Projection identifier', description: '🌍 Original projection identifier (also called SRID) of the .asc files.

    ' + - 'It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Pseudo-Mercator projection).

    ' + - '🛠 Default value: 4326 ', - type : Integer.class, - min : 0, max: 1 + 'It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Pseudo-Mercator projection)', + min : 0, + max : 1, + type : Integer.class ], fence : [ name : 'Fence geometry', @@ -69,9 +65,8 @@ inputs = [ downscale: [ name : 'Skip pixels on each axis', title : 'Skip pixels on each axis', - description: 'Divide the number of rows and columns read by the following coefficient (FLOAT)

    ' + - '🛠 Default value: 1.0 ', - min : 0, max: 1, + description: 'Divide the number of rows and columns read by the following coefficient (FLOAT)', + default : 1.0, type : Integer.class ] ] @@ -85,30 +80,7 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -def exec(Connection connection, input) { +def exec(Connection connection,Map input) { // output string, the information given back to the user String resultString = null @@ -128,11 +100,7 @@ def exec(Connection connection, input) { defaultSRID = input['inputSRID'] as Integer } - Integer downscale = 1 - if (input['downscale']) { - downscale = Math.max(1, input['downscale'] as Integer) - } - + Integer downscale =Math.max(1, input.getOrDefault("downscale",1) as Integer) String fence = null if (input['fence']) { fence = (String) input['fence'] diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Asc_Folder.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Asc_Folder.groovy similarity index 79% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Asc_Folder.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Asc_Folder.groovy index 5b6d3388b..d566158f1 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Asc_Folder.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Asc_Folder.groovy @@ -14,13 +14,10 @@ * @Author Pierre Aumond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Import_and_Export +package org.noise_planet.noisemodelling.scripts.Import_and_Export -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.io.FileType import org.apache.commons.io.FilenameUtils -import org.geotools.jdbc.JDBCDataStore import org.h2gis.functions.io.utility.PRJUtil import org.h2gis.utilities.TableLocation import org.h2gis.utilities.dbtypes.DBUtils @@ -28,7 +25,6 @@ import org.noise_planet.noisemodelling.jdbc.utils.AscReaderDriver import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.Statement @@ -36,7 +32,7 @@ title = 'Import all .asc files from a folder' description = '➡️ Import all files with .asc extension from a folder to the database
    ' + '
    ' + '✅ The resulting tables will have the same name as the input files

    ' + - 'Import asc folder' + 'Import asc folder' inputs = [ pathFolder: [ @@ -50,17 +46,16 @@ inputs = [ name : 'Projection identifier', title : 'Projection identifier', description: '🌍 Original projection identifier (also called SRID) of the .asc file.

    ' + - 'It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Pseudo-Mercator projection).

    ' + - '🛠 Default value: 4326 ', - type : Integer.class, - min : 0, max: 1 + 'It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Pseudo-Mercator projection)', + min : 0, + max : 1, + type : Integer.class ], downscale: [ name : 'Skip pixels on each axis', title : 'Skip pixels on each axis', - description: 'Divide the number of rows and columns read by the following coefficient (FLOAT)

    ' + - '🛠 Default value: 1.0 ', - min : 0, max: 1, + description: 'Divide the number of rows and columns read by the following coefficient (FLOAT)', + default : 1.0, type : Integer.class ] ] @@ -74,28 +69,6 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} def exec(Connection connection, input) { @@ -117,10 +90,8 @@ def exec(Connection connection, input) { defaultSRID = input['inputSRID'] as Integer } - Integer downscale = 1 - if (input['downscale']) { - downscale = Math.max(1, input['downscale'] as Integer) - } + + Integer downscale =Math.max(1, input.getOrDefault("downscale",1) as Integer) // Get path of the folder String folder = input["pathFolder"] as String diff --git a/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_File.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_File.groovy new file mode 100644 index 000000000..e91b350c8 --- /dev/null +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_File.groovy @@ -0,0 +1,279 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + +/** + * @Author Pierre Aumond, Université Gustave Eiffel + * @Author Nicolas Fortin, Université Gustave Eiffel + */ + +package org.noise_planet.noisemodelling.scripts.Import_and_Export + +import org.apache.commons.io.FilenameUtils +import org.h2gis.api.EmptyProgressVisitor +import org.h2gis.api.ProgressVisitor +import org.h2gis.functions.io.csv.CSVDriverFunction +import org.h2gis.functions.io.dbf.DBFDriverFunction +import org.h2gis.functions.io.fgb.FGBDriverFunction +import org.h2gis.functions.io.geojson.GeoJsonDriverFunction +import org.h2gis.functions.io.gpx.GPXDriverFunction +import org.h2gis.functions.io.osm.OSMDriverFunction +import org.h2gis.functions.io.shp.SHPDriverFunction +import org.h2gis.functions.io.tsv.TSVDriverFunction +import org.h2gis.utilities.GeometryTableUtilities +import org.h2gis.utilities.JDBCUtilities +import org.h2gis.utilities.TableLocation +import org.h2gis.utilities.dbtypes.DBTypes +import org.h2gis.utilities.dbtypes.DBUtils +import org.noise_planet.noisemodelling.jdbc.utils.DataBaseUtilities +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.sql.Connection +import java.sql.ResultSet +import java.sql.SQLException +import java.sql.Statement + +title = 'Import File' +description = '➡️ Import file into the database.
    '+ + '
    ' + + 'Valid file extensions: csv, dbf, geojson, json, geojson.gz, gpx, osm.bz2, osm.gz, osm, shp, tsv

    ' + + 'Import file' + +inputs = [ + pathFile : [ + name : 'Path of the input File', + title : 'Path of the input File', + description: '📂 Path of the file you want to import, including its extension.

    ' + + 'For example: c:/home/buildings.geojson', + type : String.class + ], + inputSRID: [ + name : 'Projection identifier', + title : 'Projection identifier', + description: '🌍 Original projection identifier (also called SRID) of your table.

    ' + + 'It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Pseudo-Mercator projection).

    ' + + 'This entry is optional because many formats already include the projection and you can also import files without geometry attributes.

    ' + + 'If the table is geometric and if this parameter is not filled and:
    ' + + '- the file has a .prj file associated: the SRID is deduced from the .prj
    ' + + '- the file has no .prj file associated: we apply the WGS84 (EPSG:4326) code', + min : 0, max: 1, + type : Integer.class + ], + tableName: [ + name : 'Output table name', + title : 'Name of created table', + description: 'Name of the table you want to create from the file.

    ' + + '🛠 Default value: it will take the name of the file without its extension (special characters will be removed and whitespaces will be replace by an underscore.', + min : 0, max: 1, + type : String.class + ], + ifTableExists: [ + name : 'Table exists operation', + title : 'Table exists operation', + description : 'What to do if a table with the same name already exists ?', + allowedValues: ["Overwrite", "Skip import", "Raise error"], + default : 'Overwrite', + type : String.class + ] +] + +outputs = [ + outputTable: [ + name: 'Name of the created table', + title: 'Name of the created table', + description: 'Name of the created table', + type: String.class + ] +] + +/** + * Main method + * @param connection SQL Connection + * @param input Map of inputs, should provide the same keys as described in the input metadata + * @param progress Can be used to display the progression of the computation, and to check if the user canceled the execution + * @return A map as described in the result metadata + * @throws SQLException if something went wrong + */ +def exec(Connection connection, Map input, ProgressVisitor progress) { + + DBTypes dbType = DBUtils.getDBType(connection.unwrap(Connection.class)) + // output string, the information given back to the user + String resultString = null + + + // Create a logger to display messages in the geoserver logs and in the command prompt. + Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") + + // print to command window + logger.info('Start : Import File') + logger.info("inputs {}", input) // log inputs of the run + + + // Default SRID (WGS84) + Integer srid = 4326 + // Get user SRID + if (input['inputSRID']) { + srid = input['inputSRID'] as Integer + } + + // Get the path of the file to import + String pathFile = input["pathFile"] as String + if (!input["pathFile"]) { + resultString = "pathFile argument has not been provided." + throw new Exception('ERROR : ' + resultString) + } + + def file = new File(pathFile) + if (!file.exists()) { + resultString = pathFile + " is not found." + throw new Exception('ERROR : ' + resultString) + } + + // Get name of the table + String tableName = input["tableName"] as String + + // By default the name of the output table is the same than the file name + if (!tableName) { + // get the name of the fileName + String fileName = FilenameUtils.removeExtension(new File(pathFile).getName()) + // replace whitespaces by _ in the file name + fileName.replaceAll("\\s", "_") + // remove special characters in the file name + fileName.replaceAll("[^a-zA-Z0-9 ]+", "_") + // the tableName will be called as the fileName + tableName = fileName + } + + // Apply table name for the database type + tableName = TableLocation.capsIdentifier(tableName, dbType) + + // Create a connection statement to interact with the database in SQL + Statement stmt = connection.createStatement() + + def tableExistsOperation = input.getOrDefault("ifTableExists", "Overwrite") + + boolean tableExists = JDBCUtilities.tableExists(connection, tableName) + if(tableExists && "Overwrite" == tableExistsOperation) { + // Drop the table if already exists + logger.info("Table already exists drop the table..") + String dropOutputTable = "drop table if exists " + tableName + stmt.execute(dropOutputTable) + } else if(tableExists && "Skip import" == tableExistsOperation) { + logger.info("Table already exists skip importing the file") + return [outputTable: tableName] + } else if(tableExists) { + throw new IllegalStateException("Table already exists and user choose to raise an error in this case") + } + + + // Get the extension of the file and import + String pathFileLower = pathFile.toLowerCase() + if (pathFileLower.endsWith(".csv")) { + CSVDriverFunction csvDriver = new CSVDriverFunction() + csvDriver.importFile(connection, tableName, new File(pathFile), progress) + } else if (pathFileLower.endsWith(".dbf")) { + DBFDriverFunction dbfDriver = new DBFDriverFunction() + dbfDriver.importFile(connection, tableName, new File(pathFile), progress) + } else if (pathFileLower.endsWith(".geojson") || pathFileLower.endsWith(".json") || pathFileLower.endsWith(".geojson.gz")) { + GeoJsonDriverFunction geoJsonDriver = new GeoJsonDriverFunction() + geoJsonDriver.importFile(connection, tableName, new File(pathFile), progress) + } else if (pathFileLower.endsWith(".gpx")) { + GPXDriverFunction gpxDriver = new GPXDriverFunction() + gpxDriver.importFile(connection, tableName, new File(pathFile), progress) + } else if (pathFileLower.endsWith(".osm.bz2") || pathFileLower.endsWith(".osm.gz") || pathFileLower.endsWith(".osm")) { + OSMDriverFunction osmDriver = new OSMDriverFunction() + osmDriver.importFile(connection, tableName, new File(pathFile), progress) + } else if (pathFileLower.endsWith(".shp")) { + SHPDriverFunction shpDriver = new SHPDriverFunction() + shpDriver.importFile(connection, tableName, new File(pathFile), progress) + def columnNames = JDBCUtilities.getColumnNames(connection, TableLocation.parse(tableName, dbType)).collect {it.toLowerCase(Locale.ROOT)} + if (columnNames.contains("pk") && columnNames.contains("pk2")) { + stmt.execute("ALTER TABLE " + tableName + " DROP COLUMN PK2;") + logger.warn("The PK2 column automatically created by the SHP driver has been deleted.") + } + } else if (pathFileLower.endsWith(".fgb")) { + FGBDriverFunction fgbDriver = new FGBDriverFunction() + fgbDriver.importFile(connection, tableName, new File(pathFile), progress) + } else if (pathFileLower.endsWith(".tsv")) { + TSVDriverFunction tsvDriver = new TSVDriverFunction() + tsvDriver.importFile(connection, tableName, new File(pathFile), progress) + } + + // Read Geometry Index and type of the table + List spatialFieldNames = GeometryTableUtilities.getGeometryColumnNames(connection, TableLocation.parse(tableName, DBUtils.getDBType(connection))) + + // If the table does not contain a geometry field + if (spatialFieldNames.isEmpty()) { + logger.warn("The table " + tableName + " does not contain a geometry field.") + } else { + String geomCol = GeometryTableUtilities.getFirstGeometryColumnNameAndIndex(connection, tableName).first(); + if(!JDBCUtilities.isSpatialIndexed(connection, tableName, geomCol)) { + logger.info("Creating spatial index on $tableName..") + JDBCUtilities.createSpatialIndex(connection, tableName, geomCol); + } + + // Get the SRID of the table + Integer tableSrid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(tableName)) + + // If the user explicitly provided an SRID and it differs from the table's SRID, raise an error + if (tableSrid != 0 && tableSrid != srid && input.containsKey('inputSRID') && input['inputSRID'] != null) { + resultString = "The table already has a different SRID than the one you gave." + throw new Exception('ERROR : ' + resultString) + } + + // Replace default SRID by the srid of the table + if (tableSrid != 0) srid = tableSrid + + // Display the actual SRID in the command window + logger.info("The SRID of the table is " + srid) + + // If the table does not have an associated SRID, add a SRID + if (tableSrid == 0 && !spatialFieldNames.isEmpty()) { + connection.createStatement().execute(String.format("SELECT UpdateGeometrySRID('%s', '" + spatialFieldNames.get(0) + "', %d);", + TableLocation.parse(tableName).toString(), srid)) + } + + } + + + // If the table has a PK column and doesn't have any Primary Key Constraint, then automatically associate a Primary Key + ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName) + int pkUserIndex = JDBCUtilities.getFieldIndex(rs.getMetaData(), "PK") + int pkIndex = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(tableName, dbType)) + + resultString = "The table " + tableName + " has been uploaded to the database!" + + if (pkIndex == 0) { // no primary key in the table + if (pkUserIndex > 0) { // there is a field with name PK + try { + stmt.execute("ALTER TABLE " + tableName + " ALTER COLUMN PK SET NOT NULL;") + stmt.execute("ALTER TABLE " + tableName + " ADD PRIMARY KEY (PK); ") + resultString += String.format(" $tableName has a new primary key constraint on the field named PK") + logger.info(String.format("$tableName has a new primary key constraint on PK")) + } catch (SQLException ex) { + logger.info("Could not set PK as a primary key", ex) + } + } + } + + // print to command window + logger.info(resultString) + logger.info('End : Import File') + + // Output the name of the output table + return [outputTable: tableName] + +} + + +def exec(Connection connection, Map input) { + return exec(connection, input, new EmptyProgressVisitor()) +} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Folder.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Folder.groovy similarity index 90% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Folder.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Folder.groovy index f954cc02b..e56335ed4 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Folder.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Folder.groovy @@ -15,13 +15,10 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Import_and_Export +package org.noise_planet.noisemodelling.scripts.Import_and_Export -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.io.FileType import org.apache.commons.io.FilenameUtils -import org.geotools.jdbc.JDBCDataStore import org.h2gis.api.EmptyProgressVisitor import org.h2gis.functions.io.csv.CSVDriverFunction import org.h2gis.functions.io.dbf.DBFDriverFunction @@ -37,7 +34,6 @@ import org.h2gis.utilities.TableLocation import org.h2gis.utilities.dbtypes.DBUtils import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.ResultSet import java.sql.SQLException @@ -48,14 +44,14 @@ description = '➡️ Import all files with a specified extension from '
    ' + 'Valid file extensions: csv, dbf, geojson, gpx, bz2, gz, osm, shp, tsv.

    '+ '✅ The resulting tables will have the same name as the input files

    ' + - 'Import folder' + 'Import folder' inputs = [ pathFolder: [ name : 'Path of the folder', title : 'Path of the folder', description: '📂 Path of the folder

    ' + - ' For example : c:/home/inputdata/ ', + 'For example : c:/home/inputdata/ ', type : String.class ], inputSRID: [ @@ -66,10 +62,10 @@ inputs = [ 'This entry is optional because many formats already include the projection and you can also import files without geometry attributes.

    ' + 'If the table is geometric and if this parameter is not filled and:
    ' + '- the file has a .prj file associated: the SRID is deduced from the .prj
    ' + - '- the file has no .prj file associated: we apply the WGS84 (EPSG:4326) code

    ' + - '🛠 Default value: 4326 ', - type : Integer.class, - min : 0, max: 1 + '- the file has no .prj file associated: we apply the WGS84 (EPSG:4326) code', + min : 0, + max : 1, + type : Integer.class ], importExt: [ name : 'Extension to import', @@ -89,14 +85,6 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} def exec(Connection connection, input) { @@ -275,17 +263,3 @@ def exec(Connection connection, input) { return resultString } - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_OSM.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_OSM.groovy similarity index 96% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_OSM.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_OSM.groovy index d122b59c4..519fa43a0 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_OSM.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_OSM.groovy @@ -17,14 +17,11 @@ * @Author buildingParams.json is from https://github.com/orbisgis/geoclimate/ */ -package org.noise_planet.noisemodelling.wps.Import_and_Export +package org.noise_planet.noisemodelling.scripts.Import_and_Export import crosby.binary.osmosis.OsmosisReader -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.json.JsonSlurper import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.wrapper.ConnectionWrapper import org.locationtech.jts.geom.Coordinate import org.locationtech.jts.geom.Geometry @@ -39,7 +36,6 @@ import org.openstreetmap.osmosis.xml.common.CompressionMethod import org.openstreetmap.osmosis.xml.v0_6.XmlReader import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection title = 'Import BUILDINGS, GROUND and ROADS tables from OSM' @@ -51,7 +47,7 @@ description = '➡️ Convert .osm, .osm.gz or .osm.p '- GROUND : a table containing ground acoustic absorption, based on OSM landcover surfaces
    ' + '- ROADS : a table containing the roads. As OSM does not include data on road traffic flows, default values are assigned according to the -Good Practice Guide for Strategic Noise Mapping and the Production of Associated Data on Noise Exposure - Version 2

    ' + '💡 The user can choose to avoid creating some of these tables by checking the dedicated boxes

    ' + - 'Import OSM file' + 'Import OSM file' inputs = [ pathFile : [ @@ -67,6 +63,7 @@ inputs = [ description: '🌍 Target projection identifier (also called SRID) of your table.
    ' + 'It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Web Mercator projection).

    ' + '🚨 The target SRID must be in metric coordinates.', + min : 0, max: 1, type : Integer.class ], ignoreBuilding : [ @@ -79,8 +76,7 @@ inputs = [ '- HEIGHT : The height of the building (FLOAT). ' + 'If this information is not available then it is deduced from the number of floors (if available) with the addition of a small random variation from one building to another. ' + 'Finally, if no information is available, a height of 5m is set by default.', - min : 0, - max : 1, + default : false, type : Boolean.class ], ignoreGround : [ @@ -93,8 +89,7 @@ inputs = [ '- THE_GEOM : The 2D geometry of the sources (POLYGON or MULTIPOLYGON)
    ' + '- PRIORITY : Since NoiseModelling does not allowed overlapping geometries, if this is the case, this column is used to prioritize the geometry that will win over the other one when cutting. The order is given according to the type of land use
    ' + '- G : The acoustic absorption of a ground (FLOAT) (between 0 : very hard and 1 : very soft)', - min : 0, - max : 1, + default : false, type : Boolean.class ], ignoreRoads : [ @@ -119,16 +114,14 @@ inputs = [ '- HGV_SPD_N : Hourly average heavy vehicle speed (22-6h) (DOUBLE)
    ' + '- PVMT : CNOSSOS road pavement identifier (ex: NL05) (VARCHAR)

    ' + '💡 These information are deduced from the roads importance in OSM..', - min : 0, - max : 1, + default : false, type : Boolean.class ], removeTunnels : [ name : 'Remove tunnels from OSM data', title : 'Remove tunnels from OSM data', description: '✅ If checked, remove roads from OSM data that contain OSM tag tunnel=yes.', - min : 0, - max : 1, + default : false, type : Boolean.class ], eliminateNoTrafficRoads : [ @@ -157,8 +150,7 @@ inputs = [ '- traffic_calming: Traffic calming features (speed bumps, etc.)
    ' + '- traffic_island: Traffic islands

    ' + 'If not checked, all roads are processed as before.', - min : 0, - max : 1, + default : false, type : Boolean.class ] ] @@ -172,28 +164,8 @@ outputs = [ ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} // run the script -def run(input) { - - // Get name of the database - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script def exec(Connection connection, input) { @@ -240,8 +212,9 @@ def exec(Connection connection, input) { } def reader + InputStream inputStream = null if (pathFile.toLowerCase(Locale.getDefault()).endsWith(".pbf")) { - InputStream inputStream = new FileInputStream(pathFile); + inputStream = new FileInputStream(pathFile); reader = new OsmosisReader(inputStream); } else if (pathFile.toLowerCase(Locale.getDefault()).endsWith(".osm")) { reader = new XmlReader(new File(pathFile), true, CompressionMethod.None); @@ -251,21 +224,23 @@ def exec(Connection connection, input) { throw new IllegalArgumentException("File extension not known.Should be pbf, osm or osm.gz but got " + pathFile) } - OsmHandler handler = new OsmHandler(logger, ignoreBuilding, ignoreRoads, ignoreGround, removeTunnels) - reader.setSink(handler); - reader.run(); - - logger.info('OSM Read done') - - // If eliminateNoTrafficRoads is true, filter the roads by the allowed list. - if (eliminateNoTrafficRoads && !ignoreRoads) { - def validRoadTypes = [ - "bus_guideway", "busway", "living_street", "motorway", "motorway_link", "primary", "primary_link", - "raceway", "residential", "road", "secondary", "secondary_link", "service", "tertiary", "tertiary_link", - "trunk", "trunk_link", "unclassified", "rest_area", "traffic_calming", "traffic_island" - ] - handler.roads = handler.roads.findAll { validRoadTypes.contains(it.type) } - } + OsmHandler handler; + try { + handler = new OsmHandler(logger, ignoreBuilding, ignoreRoads, ignoreGround, removeTunnels) + reader.setSink(handler); + reader.run(); + + logger.info('OSM Read done') + + // If eliminateNoTrafficRoads is true, filter the roads by the allowed list. + if (eliminateNoTrafficRoads && !ignoreRoads) { + def validRoadTypes = [ + "bus_guideway", "busway", "living_street", "motorway", "motorway_link", "primary", "primary_link", + "raceway", "residential", "road", "secondary", "secondary_link", "service", "tertiary", "tertiary_link", + "trunk", "trunk_link", "unclassified", "rest_area", "traffic_calming", "traffic_island" + ] + handler.roads = handler.roads.findAll { validRoadTypes.contains(it.type) } + } if (!ignoreBuilding) { @@ -290,7 +265,7 @@ def exec(Connection connection, input) { -- Alter that small area buildings by removing shared area DROP TABLE IF EXISTS tmp_buildings_truncated; - CREATE TABLE tmp_buildings_truncated AS SELECT PK_BUILDING, ST_DIFFERENCE(s1.the_geom, ST_BUFFER(ST_Collect(s2.the_geom), 0.1, 'join=mitre')) the_geom, s1.HEIGHT HEIGHT from tmp_relation_buildings_buildings r, MAP_BUILDINGS_GEOM s1, MAP_BUILDINGS_GEOM s2 WHERE PK_BUILDING = S1.ID_WAY AND PK2_BUILDING = S2.ID_WAY GROUP BY PK_BUILDING; + CREATE TABLE tmp_buildings_truncated AS SELECT PK_BUILDING, ST_DIFFERENCE(s1.the_geom, ST_BUFFER(ST_ACCUM(s2.the_geom), 0.1, 'join=mitre')) the_geom, s1.HEIGHT HEIGHT from tmp_relation_buildings_buildings r, MAP_BUILDINGS_GEOM s1, MAP_BUILDINGS_GEOM s2 WHERE PK_BUILDING = S1.ID_WAY AND PK2_BUILDING = S2.ID_WAY GROUP BY PK_BUILDING; -- Merge original buildings with altered buildings DROP TABLE IF EXISTS BUILDINGS; @@ -352,6 +327,12 @@ def exec(Connection connection, input) { sql.execute("CREATE SPATIAL INDEX IF NOT EXISTS GROUND_GEOM_INDEX ON " + "GROUND" + "(THE_GEOM)") } + } finally { + if (inputStream != null) { + inputStream.close() + } + } + logger.info('SQL INSERT done') resultString = "nodes : " + handler.nb_nodes @@ -1296,8 +1277,12 @@ public class Building { h = h - 4 + Double.parseDouble(tag.getValue().replaceAll("[^0-9]+", "")) * 3.0; } if ("height".equalsIgnoreCase(tag.getKey())) { - h = Double.parseDouble(tag.getValue().replaceAll("[^0-9]+", "")); - trueHeightFound = true; + String cleanHeight = tag.getValue().replaceAll("[^0-9.]+", "") + try { + h = Double.parseDouble(cleanHeight); + trueHeightFound = true; + } + catch (NumberFormatException e) {} } } this.height = h; diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_OSM_Pedestrian.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_OSM_Pedestrian.groovy similarity index 98% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_OSM_Pedestrian.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_OSM_Pedestrian.groovy index ec3876337..86cbc380c 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_OSM_Pedestrian.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_OSM_Pedestrian.groovy @@ -9,6 +9,7 @@ * Contact: contact@noise-planet.org * */ + /** * @Author Pierre Aumond, Université Gustave Eiffel * @Author Nicolas Fortin, Université Gustave Eiffel @@ -16,13 +17,10 @@ * @Author Part of this file are inspired of https://github.com/orbisgis/geoclimate/wiki */ -package org.noise_planet.noisemodelling.wps.Import_and_Export; +package org.noise_planet.noisemodelling.scripts.Import_and_Export; -import geoserver.GeoServer; -import geoserver.catalog.Store import groovy.json.JsonSlurper; import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.wrapper.ConnectionWrapper; import org.locationtech.jts.geom.Geometry import org.locationtech.jts.geom.GeometryFactory; @@ -37,10 +35,8 @@ import org.openstreetmap.osmosis.core.domain.v0_6.Relation; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.task.v0_6.Sink; - import org.openstreetmap.osmosis.xml.v0_6.XmlReader; import org.openstreetmap.osmosis.xml.common.CompressionMethod; - import crosby.binary.osmosis.OsmosisReader import org.slf4j.Logger import org.slf4j.LoggerFactory; @@ -59,7 +55,7 @@ inputs = [ name : 'Path of the OSM file', title : 'Path of the OSM file', description: '📂 Path of the OSM file, including its extension (.osm, .osm.gz or .osm.pbf).
    ' + - 'For example: c:/home/area.osm.pbf', + 'For example: c:/home/area.osm.pbf', type : String.class ], targetSRID : [ @@ -81,31 +77,6 @@ outputs = [ ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script def exec(Connection connection, input) { @@ -133,20 +104,22 @@ def exec(Connection connection, input) { // Read the OSM file, depending on its extension def reader + InputStream inputStream = null if (pathFile.endsWith(".pbf")) { - InputStream inputStream = new FileInputStream(pathFile); + inputStream = new FileInputStream(pathFile); reader = new OsmosisReader(inputStream); } else if (pathFile.endsWith(".osm")) { reader = new XmlReader(new File(pathFile), true, CompressionMethod.None); } else if (pathFile.endsWith(".osm.gz")) { reader = new XmlReader(new File(pathFile), true, CompressionMethod.GZip); } + OsmHandlerPedestrian handler + try { + handler = new OsmHandlerPedestrian(logger) + reader.setSink(handler); + reader.run(); - OsmHandlerPedestrian handler = new OsmHandlerPedestrian(logger) - reader.setSink(handler); - reader.run(); - - logger.info('OSM Read done') + logger.info('OSM Read done') String tableName = "MAP_BUILDINGS_GEOM"; @@ -170,7 +143,7 @@ def exec(Connection connection, input) { -- Alter that small area buildings by removing shared area DROP TABLE IF EXISTS tmp_buildings_truncated; - CREATE TABLE tmp_buildings_truncated AS SELECT PK_BUILDING, ST_DIFFERENCE(s1.the_geom, ST_BUFFER(ST_Collect(s2.the_geom), 0.1, 'join=mitre')) the_geom, s1.HEIGHT HEIGHT from tmp_relation_buildings_buildings r, MAP_BUILDINGS_GEOM s1, MAP_BUILDINGS_GEOM s2 WHERE PK_BUILDING = S1.ID_WAY AND PK2_BUILDING = S2.ID_WAY GROUP BY PK_BUILDING; + CREATE TABLE tmp_buildings_truncated AS SELECT PK_BUILDING, ST_DIFFERENCE(s1.the_geom, ST_BUFFER(ST_ACCUM(s2.the_geom), 0.1, 'join=mitre')) the_geom, s1.HEIGHT HEIGHT from tmp_relation_buildings_buildings r, MAP_BUILDINGS_GEOM s1, MAP_BUILDINGS_GEOM s2 WHERE PK_BUILDING = S1.ID_WAY AND PK2_BUILDING = S2.ID_WAY GROUP BY PK_BUILDING; -- Merge original buildings with altered buildings DROP TABLE IF EXISTS BUILDINGS; @@ -376,6 +349,12 @@ def exec(Connection connection, input) { logger.info('SQL Compute Pedestrian Areas Done !') + } finally { + if (inputStream != null) { + inputStream.close() + } + } + resultString = "nodes : " + handler.nb_nodes resultString += "
    \n" resultString += "ways : " + handler.nb_ways diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Symuvia.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Symuvia.groovy similarity index 95% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Symuvia.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Symuvia.groovy index d2e86250b..506bcc8c2 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_Symuvia.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_Symuvia.groovy @@ -1,14 +1,22 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by Université Gustave Eiffel and CNRS + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + /** * @Author Aumond Pierre, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.Import_and_Export +package org.noise_planet.noisemodelling.scripts.Import_and_Export -import geoserver.GeoServer -import geoserver.catalog.Store -import jdk.internal.org.xml.sax.SAXException import org.apache.commons.io.FilenameUtils -import org.geotools.jdbc.JDBCDataStore import org.h2gis.api.EmptyProgressVisitor import org.h2gis.api.ProgressVisitor import org.h2gis.utilities.GeometryTableUtilities @@ -24,9 +32,6 @@ import org.xml.sax.XMLReader import org.xml.sax.helpers.DefaultHandler import org.xml.sax.helpers.XMLReaderFactory import org.xml.sax.SAXException - -import javax.xml.parsers.SAXParser -import javax.xml.parsers.SAXParserFactory import java.nio.channels.FileChannel import java.sql.Connection import java.sql.PreparedStatement @@ -74,30 +79,6 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - def exec(Connection connection, input) { diff --git a/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Linked_Table.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Linked_Table.groovy new file mode 100644 index 000000000..44080a7eb --- /dev/null +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Linked_Table.groovy @@ -0,0 +1,137 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + + /** + * @Author Nicolas Fortin, Université Gustave Eiffel + */ + +package org.noise_planet.noisemodelling.scripts.Import_and_Export + +import org.h2gis.api.ProgressVisitor +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.sql.Connection + +title = 'Linked Table' +description = '➡️ Create a table into the database linked to an external database. The data is not stored into the database' + +inputs = [ + localTableName: [ + name : 'Local table name', + title : 'Name of created table', + description: 'Name of the local linked table.', + type : String.class + ], + driverClass: [ + name : 'Driver name', + title : 'Driver name', + description: 'Name of the class to connect to the external database.', + allowedValues: ["org.h2gis.postgis_jts.Driver", "org.h2.Driver"], + default : "org.h2gis.postgis_jts.Driver", + type : String.class + ], + databaseUrl: [ + name : 'Database URL', + title : 'Database URL', + description: 'Connection url of the database. ' + + 'For PostGIS
    jdbc:postgresql_h2://hostname:5432/databaseName
    .
    ' + + 'For H2
    jdbc:h2:tcp://localhost/D:/data/test
    ', + type : String.class + ], + username: [ + name : 'User name', + title : 'User name', + description: 'User name when connecting to the external database', + type : String.class + ], + password: [ + name : 'User password', + title : 'User password', + description: 'User password when connecting to the external database', + type : String.class + ], + remoteSchemaName: [ + name : 'External table schema', + title : 'External table schema', + description: 'External Table Schema ex: public', + default: 'public', + type : String.class + ], + remoteTableName: [ + name : 'External table name', + title : 'External table name', + description: 'External Table name or query. If a query is used instead of the original table name, then' + + ' the table is read only. Queries must be enclosed in parenthesis: (SELECT * FROM ORDERS).', + type : String.class + ], + force: [ + name : 'Force', + title : 'Force', + description: 'Create the LINKED TABLE even if the remote database/table does not exist.', + min: 0, + max: 1, + type : Boolean.class + ], + fetchSize: [ + name : 'Fetch size', + title : 'Fetch size', + description: 'the number of rows fetched, a hint with non-negative number of rows to fetch from' + + ' the external table at once, may be ignored by the driver of external database.' + + ' 0 is default and means no hint. The value is passed to java.sql.Statement.setFetchSize() method.', + default: 0, + type : Integer.class + ] +] + +outputs = [ + result: [ + name : 'Local table name', + title : 'Local table name', + description: 'The name of the local linked table, can be used as an input for another process', + type : String.class + ] +] + +def exec(Connection connection, Map input, ProgressVisitor progress) { + + // Create a logger to display messages in the geoserver logs and in the command prompt. + Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") + + def fetchSizeStatement = "" + if (input['fetchSize'] && input['fetchSize'] instanceof Integer) { + fetchSizeStatement = " FETCH_SIZE " + (input['fetchSize'] as Integer) + } + + def localTableName = input['localTableName'] as String + def driverClass = input.getOrDefault('driverClass', 'org.h2gis.postgis_jts.Driver') + def databaseUrl = input['databaseUrl'] as String + def username = input['username'] as String + def password = input['password'] as String + def remoteSchemaName = input['remoteSchemaName'] ? (input['remoteSchemaName'] as String) : "public" + def remoteTableName = input['remoteTableName'] as String + def force = input['force'] ? "FORCE" : "" + + logger.info("Create linked table $localTableName with the server $databaseUrl") + + connection.createStatement().with { + execute("""CREATE $force LINKED TABLE $localTableName(${enquoteLiteral(driverClass)}, ${ + enquoteLiteral(databaseUrl)}, ${enquoteLiteral(username)}, ${enquoteLiteral(password)}, ${ + enquoteLiteral(remoteSchemaName)}, ${enquoteLiteral(remoteTableName)}) $fetchSizeStatement;""".toString()) + close() + } + + def result = "Table $localTableName created" + logger.info(result) + + return [result: result] +} + diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/GenerateAtmosphericSettingsTemplate.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Atmospheric_Template.groovy similarity index 75% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/GenerateAtmosphericSettingsTemplate.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Atmospheric_Template.groovy index 3ebabe3a6..26d138a34 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/GenerateAtmosphericSettingsTemplate.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Atmospheric_Template.groovy @@ -10,12 +10,9 @@ * */ -package org.noise_planet.noisemodelling.wps.NoiseModelling +package org.noise_planet.noisemodelling.scripts.NoiseModelling -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.dbtypes.DBTypes import org.h2gis.utilities.dbtypes.DBUtils @@ -25,10 +22,10 @@ import org.slf4j.Logger import org.slf4j.LoggerFactory import java.sql.Connection -title = 'Generate default atmospherics settings from the PERIOD field of a noise emission table' +title = 'Generate default atmospheric settings from the PERIOD field of a noise emission table' description = '➡️ Generate default atmospherics settings from the PERIOD field of a noise emission table.' + - ' It is used to export the result table to be edited and reimported to be used into Noise_level_from_source or' + - ' Noise_level_from_traffic. This table make you able to change the temperature and other settings for each time period of the simulation' + ' It is used to export the result table to be edited and reimported to be used into Noise_level_from_source.' + + ' This table make you able to change the temperature and other settings for each time period of the simulation' inputs = [ tableSourcesEmission : [ @@ -51,9 +48,9 @@ inputs = [ '
  • PRESSURE : air pressure in pascal (FLOAT)
  • ' + '
  • HUMIDITY : air humidity in percentage (FLOAT)
  • ' + '
  • GDISC : choose between accept G discontinuity or not (BOOLEAN) default true
  • ' + - '
  • PRIME2520 : choose to use prime values to compute eq. 2.5.20 (BOOLEAN) default false
  • ' + - ' Default to SOURCES_ATMOSPHERIC' , - min : 0, max: 1, type: String.class + '
  • PRIME2520 : choose to use prime values to compute eq. 2.5.20 (BOOLEAN) default false
  • ', + default : 'SOURCES_ATMOSPHERIC', + type: String.class ], ] @@ -66,30 +63,6 @@ outputs = [ ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script def exec(Connection connection, Map input) { @@ -121,5 +94,5 @@ def exec(Connection connection, Map input) { defaultParameters.writeToDatabase(connection, tablePeriodAtmosphericSettings, period) } - return "Calculation Done ! The table $tablePeriodAtmosphericSettings have been created, you can now export it, edit it and reimport to be used into Noise_level_from_source or Noise_level_from_traffic." + return "Calculation Done ! The table $tablePeriodAtmosphericSettings have been created, you can now export it, edit it and reimport to be used into Noise_level_from_source." } diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Noise_level_from_source.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Noise_level_from_source.groovy similarity index 74% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Noise_level_from_source.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Noise_level_from_source.groovy index 075a81a48..ea8092881 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Noise_level_from_source.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Noise_level_from_source.groovy @@ -16,13 +16,11 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.NoiseModelling +package org.noise_planet.noisemodelling.scripts.NoiseModelling -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore +import org.h2gis.api.EmptyProgressVisitor +import org.h2gis.api.ProgressVisitor import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation @@ -31,12 +29,12 @@ import org.h2gis.utilities.dbtypes.DBUtils import org.h2gis.utilities.wrapper.ConnectionWrapper import org.noise_planet.noisemodelling.jdbc.NoiseMapByReceiverMaker import org.noise_planet.noisemodelling.jdbc.NoiseMapDatabaseParameters +import org.noise_planet.noisemodelling.jdbc.utils.DataBaseUtilities import org.noise_planet.noisemodelling.jdbc.input.DefaultTableLoader import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor import org.noise_planet.noisemodelling.propagation.AttenuationParameters import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.SQLException import java.time.LocalDateTime @@ -92,7 +90,8 @@ inputs = [ '
  • IDSOURCE * : an identifier. It shall be linked to the primary key of tableRoads (INTEGER)
  • ' + '
  • PERIOD * : Time period, you will find this column on the output (VARCHAR)
  • ' + '
  • HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000 : Emission noise level in dB can be third-octave 50Hz to 10000Hz (FLOAT)
  • ', - min : 0, max: 1, type: String.class + min : 0, max: 1, + type: String.class ], tableReceivers : [ name : 'Receivers table name', @@ -111,7 +110,8 @@ inputs = [ 'The table must contain:
      ' + '
    • THE_GEOM : the 3D geometry of the sources (POINT, MULTIPOINT)
    ' + '💡 This table can be generated from the WPS Block "Import_Asc_File"', - min : 0, max: 1, type: String.class + min : 0, max: 1, + type: String.class ], tableGroundAbs : [ name : 'Ground absorption table name', @@ -120,7 +120,8 @@ inputs = [ 'The table must contain:
      ' + '
    • THE_GEOM : the 2D geometry of the sources (POLYGON or MULTIPOLYGON)
    • ' + '
    • G : the acoustic absorption of a ground (FLOAT between 0 : very hard and 1 : very soft)
    ', - min : 0, max: 1, type: String.class + min : 0, max: 1, + type: String.class ], tableSourceDirectivity : [ name : 'Source directivity table name', @@ -132,7 +133,8 @@ inputs = [ '
  • THETA : [-90;90] Vertical angle in degree. 0° front 90° top -90° bottom (FLOAT)
  • ' + '
  • PHI : [0;360] Horizontal angle in degree. 0° front 90° right (FLOAT)
  • ' + '
  • HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000 : attenuation levels in dB for each octave or third octave (FLOAT)
  • ' , - min : 0, max: 1, type: String.class + min : 0, max: 1, + type: String.class ], tablePeriodAtmosphericSettings : [ name : 'Atmospheric settings table name for each time period', @@ -147,160 +149,145 @@ inputs = [ '
  • GDISC : choose between accept G discontinuity or not (BOOLEAN) default true
  • ' + '
  • PRIME2520 : choose to use prime values to compute eq. 2.5.20 (BOOLEAN) default false
  • ' + '' , - min : 0, max: 1, type: String.class + min : 0, max: 1, + type: String.class ], paramWallAlpha : [ name : 'wallAlpha', title : 'Wall absorption coefficient', - description: 'Wall absorption coefficient (FLOAT)

    ' + - 'This coefficient is going
      ' + - '
    • from 0 : fully absorbent
    • ' + - '
    • to strictly less than 1 : fully reflective.
    ' + - '🛠 Default value: 0.1 ', - min : 0, max: 1, type: String.class + description: 'Wall absorption coefficient [0,1] (between ``0`` : "fully reflective" and ``1`` : "fully absorbent")', + default : 0.1, + type: Double.class ], confReflOrder : [ name : 'Order of reflexion', title : 'Order of reflexion', description: 'Maximum number of reflections to be taken into account (INTEGER).

    ' + - '🚨 Adding 1 order of reflexion can significantly increase the processing time.

    ' + - '🛠 Default value: 1 ', - min : 0, max: 1, type: String.class + '🚨 Adding 1 order of reflexion can significantly increase the processing time.', + default : 1, + type: Integer.class ], confMaxSrcDist : [ name : 'Maximum source-receiver distance', title : 'Maximum source-receiver distance', description: 'Maximum distance between source and receiver (FLOAT, in meters).

    ' + - '🛠 Default value: 150 ', - min : 0, max: 1, type: String.class + 'Noise level from source', + default : 150, + type: Double.class ], confMaxReflDist : [ name : 'Maximum source-reflexion distance', title : 'Maximum source-reflexion distance', - description: 'Maximum reflection distance from the source (FLOAT, in meters).

    ' + - '🛠 Default value: 50 ', - min : 0, max: 1, type: String.class + description: 'Maximum search distance of walls / facades from the "Source-Receiver" segment, for the calculation of specular reflections (meters).

    ' + + 'Noise level from source', + default : 50, + type: Double.class + ], + confMinWallReflDist: [ + name : 'Ignore close reflections', + title : 'Ignore close reflections', + description: 'Optional maximum receiver-to-wall distance (meters) below which reflection cut profiles are ignored. With regard to the population’s exposure to noise, it is recommended that the contribution due to reflection off the façade wall of the building where the resident lives should be disregarded. If you have placed the receivers 0.1 m from the façades, you can set this parameter to 0.2 m. This offset is set to ensure that the contribution from the nearby wall is ignored. ' + + 'Use 0 to keep all reflections.', + default: 0, + type: Double.class ], confThreadNumber : [ name : 'Thread number', title : 'Thread number', description: 'Number of thread to use on the computer (INTEGER).

    ' + - 'To set this value, look at the number of cores you have.
    ' + - 'If it is set to 0, use the maximum number of cores available.

    ' + - '🛠 Default value: 0 ', - min : 0, max: 1, type: String.class + '🛠 Default value: 0 = Automatic. Will check the number of cores and apply -1. (*e.g*: 8 cores = 7 cores will be used)', + default : 0, + type: Integer.class ], confDiffVertical : [ name : 'Diffraction on vertical edges', title : 'Diffraction on vertical edges', - description: 'Compute or not the diffraction on vertical edges. Following Directive 2015/996, enable this option for rail and industrial sources only.

    ' + - '🛠 Default value: false ', - min : 0, max: 1, type: Boolean.class + description: 'Compute or not the diffraction on vertical edges. Following Directive 2015/996, enable this option for rail and industrial sources only', + default : false, + type: Boolean.class ], confDiffHorizontal : [ name : 'Diffraction on horizontal edges', title : 'Diffraction on horizontal edges', - description: 'Compute or not the diffraction on horizontal edges.

    ' + - '🛠 Default value: false ', - min : 0, max: 1, type: Boolean.class + description: 'Compute or not the diffraction on horizontal edges', + default : false, + type: Boolean.class ], confExportSourceId : [ name : 'Keep source id', title : 'Separate receiver level by source identifier', - description: 'Keep source identifier in output in order to get noise contribution of each noise source.

    ' + - '🛠 Default value: false ', - min : 0, max: 1, + description: 'Keep source identifier in output in order to get noise contribution of each noise source. When only the source geometry is given, the attenuation between each pair of "source-receiver" points is specified (commonly referred to as the "attenuation matrix")', + default : false, type : Boolean.class ], confHumidity : [ name : 'Relative humidity', title : 'Relative humidity', - description: '🌧 Humidity for noise propagation.

    ' + - '🛠 Default value: 70', - min : 0, max: 1, + description: '🌧 Humidity for noise propagation (%) [0,100]', + default : 70, type : Double.class ], confTemperature : [ name : 'Temperature', title : 'Air temperature', - description: '🌡 Air temperature in degree celsius

    ' + - '🛠 Default value: 15', - min : 0, max: 1, + description: '🌡 Air temperature (°C)', + default : 15, type : Double.class ], confFavourableOccurrencesDefault: [ name : 'Probability of occurrences', title : 'Probability of occurrences', - description: 'Comma-delimited string containing the default probability of occurrences of favourable propagation conditions.

    ' + - 'The north slice is the last array index not the first one
    ' + - 'Slice width are 22.5°: (16 slices)
      ' + - '
    • The first column 22.5° contain occurrences between 11.25 to 33.75 °
    • ' + - '
    • The last column 360° contains occurrences between 348.75° to 360° and 0 to 11.25°
    ' + - '🛠 Default value: 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5', - min : 0, max: 1, + description: 'Comma-delimited string containing the probability ([0,1]) of occurrences of favourable propagation conditions. Follow the clockwise direction. The north slice is the last array index (n°16 in the schema below) not the first one.

    ' + + 'Noise level from source', + default : '0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5', type : String.class ], confRaysName : [ name : '', title : 'Export scene', description: 'Save each mnt, buildings and propagation rays into the specified table (ex:RAYS) or file URL (ex: file:///Z:/dir/map.kml)

    ' + - 'You can set a table name here in order to save all the rays computed by NoiseModelling.

    ' + - 'The number of rays has been limited in this script in order to avoid memory exception.

    ' + - '🛠 Default value: empty (do not keep rays)', - min : 0, max: 1, type: String.class + 'You can set a table name here in order to save all the rays computed by NoiseModelling.

    ' + + 'The number of rays has been limited in this script in order to avoid memory exception.

    ' + + '🛠 If not provided, then do not keep rays', + min : 0, max: 1, + type: String.class ], confMaxError : [ name : 'Max Error (dB)', title : 'Max Error (dB)', - description: 'Threshold for excluding negligible sound sources in calculations. Default value: 0.1', - min : 0, max: 1, + description: 'Threshold for excluding negligible sound sources in calculations.' + + 'This parameter is ignored if no emission level is specified or if you set it to 0 dB. This parameter have a great impact on computation time.', + default : 0.1, type : Double.class ], frequencyFieldPrepend : [ name : 'Frequency field name', title : 'Frequency field name', - description: 'Frequency field name prepend. Ex. for 1000 Hz frequency the default column name is HZ1000.' + - '🛠 Default value: HZ', - min : 0, max: 1, type: String.class + description: 'Frequency field name prepend. Ex. for 1000 Hz frequency the default column name is HZ1000.', + default : 'HZ', + type: String.class + ], + confLineSourceSpacingRatio: [ + name : 'Line source spacing ratio', + title : 'Line source spacing ratio', + description: 'Dictates the density of source points created from a line sound source. A higher value means more points and finer discretization : DistanceBetweenPoints = DistanceSourceToReceiver / LineSourceSpacingRatio (this parameter)', + default : 2.0, + type : Double.class ] ] outputs = [ result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', + name : 'Created table', + title : 'Created table', + description: 'Name of the table containing the results of the computation. Can be used as input for another process.', type : String.class ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script -@CompileStatic -def exec(Connection connection, Map input) { +def exec(Connection connection, Map input, ProgressVisitor progress) { long startCompute = System.currentTimeMillis() DBTypes dbType = DBUtils.getDBType(connection.unwrap(Connection.class)) @@ -311,7 +298,7 @@ def exec(Connection connection, Map input) { // Create a sql connection to interact with the database in SQL Sql sql = new Sql(connection) - sql.execute("DROP TABLE RECEIVERS_LEVEL IF EXISTS;") + sql.execute("DROP TABLE IF EXISTS RECEIVERS_LEVEL;") // Create a logger to display messages in the geoserver logs and in the command prompt. Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") @@ -325,65 +312,61 @@ def exec(Connection connection, Map input) { // ------------------- String sources_table_name = input['tableSources'] - // do it case-insensitive - sources_table_name = sources_table_name.toUpperCase() + // Check if srid are in metric projection. - int sridSources = GeometryTableUtilities.getSRID(connection, TableLocation.parse(sources_table_name)) - if (sridSources == 3785 || sridSources == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+sources_table_name+".") + int sridSources = GeometryTableUtilities.getSRID(connection, TableLocation.parse(sources_table_name, dbType)) + if (!DataBaseUtilities.isSridMetric(connection, sridSources)) throw new IllegalArgumentException("Error : Please use a metric projection for "+sources_table_name+".") if (sridSources == 0) throw new IllegalArgumentException("Error : The table "+sources_table_name+" does not have an associated SRID.") //Get the geometry field of the source table - TableLocation sourceTableIdentifier = TableLocation.parse(sources_table_name) + TableLocation sourceTableIdentifier = TableLocation.parse(sources_table_name, dbType) List geomFields = GeometryTableUtilities.getGeometryColumnNames(connection, sourceTableIdentifier) if (geomFields.isEmpty()) { throw new SQLException(String.format("The table %s does not exists or does not contain a geometry field", sourceTableIdentifier)) } //Get the primary key field of the source table - int pkIndex = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(sources_table_name)) + int pkIndex = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(sources_table_name, dbType)) if (pkIndex < 1) { throw new IllegalArgumentException(String.format("Source table %s does not contain a primary key", sourceTableIdentifier)) } String receivers_table_name = input['tableReceivers'] - // do it case-insensitive - receivers_table_name = receivers_table_name.toUpperCase() + //Get the geometry field of the receiver table - TableLocation receiverTableIdentifier = TableLocation.parse(receivers_table_name) + TableLocation receiverTableIdentifier = TableLocation.parse(receivers_table_name, dbType) List geomFieldsRcv = GeometryTableUtilities.getGeometryColumnNames(connection, receiverTableIdentifier) if (geomFieldsRcv.isEmpty()) { throw new SQLException(String.format("The table %s does not exists or does not contain a geometry field", receiverTableIdentifier)) } // Check if srid are in metric projection and are all the same. - int sridReceivers = GeometryTableUtilities.getSRID(connection, TableLocation.parse(receivers_table_name)) - if (sridReceivers == 3785 || sridReceivers == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+receivers_table_name+".") + int sridReceivers = GeometryTableUtilities.getSRID(connection, TableLocation.parse(receivers_table_name, dbType)) + if (!DataBaseUtilities.isSridMetric(connection, sridReceivers)) throw new IllegalArgumentException("Error : Please use a metric projection for "+receivers_table_name+".") if (sridReceivers == 0) throw new IllegalArgumentException("Error : The table "+receivers_table_name+" does not have an associated SRID.") if (sridReceivers != sridSources) throw new IllegalArgumentException("Error : The SRID of table "+sources_table_name+" and "+receivers_table_name+" are not the same.") //Get the primary key field of the receiver table - int pkIndexRecv = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(receivers_table_name)) + int pkIndexRecv = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(receivers_table_name, dbType)) if (pkIndexRecv < 1) { throw new IllegalArgumentException(String.format("Source table %s does not contain a primary key", receiverTableIdentifier)) } String building_table_name = input['tableBuilding'] - // do it case-insensitive - building_table_name = building_table_name.toUpperCase() + // Check if srid are in metric projection and are all the same. - int sridBuildings = GeometryTableUtilities.getSRID(connection, TableLocation.parse(building_table_name)) - if (sridBuildings == 3785 || sridReceivers == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+building_table_name+".") + int sridBuildings = GeometryTableUtilities.getSRID(connection, TableLocation.parse(building_table_name, dbType)) + if (!DataBaseUtilities.isSridMetric(connection, sridBuildings)) throw new IllegalArgumentException("Error : Please use a metric projection for "+building_table_name+".") if (sridBuildings == 0) throw new IllegalArgumentException("Error : The table "+building_table_name+" does not have an associated SRID.") if (sridReceivers != sridBuildings) throw new IllegalArgumentException("Error : The SRID of table "+building_table_name+" and "+receivers_table_name+" are not the same.") String dem_table_name = "" if (input['tableDEM']) { dem_table_name = input['tableDEM'] - // do it case-insensitive - dem_table_name = dem_table_name.toUpperCase() + // Check if srid are in metric projection and are all the same. - int sridDEM = GeometryTableUtilities.getSRID(connection, TableLocation.parse(dem_table_name)) - if (sridDEM == 3785 || sridReceivers == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+dem_table_name+".") + int sridDEM = GeometryTableUtilities.getSRID(connection, TableLocation.parse(dem_table_name, dbType)) + if (!DataBaseUtilities.isSridMetric(connection, sridDEM)) throw new IllegalArgumentException("Error : Please use a metric projection for "+dem_table_name+".") if (sridDEM == 0) throw new IllegalArgumentException("Error : The table "+dem_table_name+" does not have an associated SRID.") if (sridDEM != sridSources) throw new IllegalArgumentException("Error : The SRID of table "+sources_table_name+" and "+dem_table_name+" are not the same.") } @@ -391,11 +374,10 @@ def exec(Connection connection, Map input) { String ground_table_name = "" if (input['tableGroundAbs']) { ground_table_name = input['tableGroundAbs'] - // do it case-insensitive - ground_table_name = ground_table_name.toUpperCase() + // Check if srid are in metric projection and are all the same. - int sridGROUND = GeometryTableUtilities.getSRID(connection, TableLocation.parse(ground_table_name)) - if (sridGROUND == 3785 || sridReceivers == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+ground_table_name+".") + int sridGROUND = GeometryTableUtilities.getSRID(connection, TableLocation.parse(ground_table_name, dbType)) + if (!DataBaseUtilities.isSridMetric(connection, sridGROUND)) throw new IllegalArgumentException("Error : Please use a metric projection for "+ground_table_name+".") if (sridGROUND == 0) throw new IllegalArgumentException("Error : The table "+ground_table_name+" does not have an associated SRID.") if (sridGROUND != sridSources) throw new IllegalArgumentException("Error : The SRID of table "+ground_table_name+" and "+sources_table_name+" are not the same.") } @@ -403,8 +385,6 @@ def exec(Connection connection, Map input) { String tableSourceDirectivity = "" if (input['tableSourceDirectivity']) { tableSourceDirectivity = input['tableSourceDirectivity'] - // do it case-insensitive - tableSourceDirectivity = tableSourceDirectivity.toUpperCase() } boolean recordProfile = false @@ -412,31 +392,31 @@ def exec(Connection connection, Map input) { recordProfile = input['confRecordProfile'] } - int reflexion_order = 0 - if (input['confReflOrder']) { - reflexion_order = Integer.valueOf(input['confReflOrder'] as String) - } + int reflexion_order = input.getOrDefault("confReflOrder",1) as Integer - double max_src_dist = 150 + double max_src_dist = 150.0 if (input['confMaxSrcDist']) { max_src_dist = Double.valueOf(input['confMaxSrcDist'] as String) } - double max_ref_dist = 50 + double max_ref_dist = 50.0 if (input['confMaxReflDist']) { max_ref_dist = Double.valueOf(input['confMaxReflDist'] as String) } - double wall_alpha = 0.1 - if (input['paramWallAlpha']) { - wall_alpha = Double.valueOf(input['paramWallAlpha'] as String) + double close_receiver_reflection_wall_distance = input.getOrDefault("confMinWallReflDist", 0.0) as Double + if (close_receiver_reflection_wall_distance < 0) { + throw new IllegalArgumentException("Error : confMinWallReflDist must be greater than or equal to 0.") } - - int n_thread = 0 - if (input['confThreadNumber']) { - n_thread = Integer.valueOf(input['confThreadNumber'] as String) + if (close_receiver_reflection_wall_distance > 2.0) { + logger.warn("confMinWallReflDist is set to {} m, which is unusually high. Many reflections may be ignored.", + close_receiver_reflection_wall_distance) } + double wall_alpha = input.getOrDefault("paramWallAlpha",0.1) as Double + + int n_thread = input.getOrDefault("confThreadNumber",0) as Integer + boolean compute_vertical_diffraction = false if (input['confDiffVertical']) { compute_vertical_diffraction = input['confDiffVertical'] @@ -452,16 +432,18 @@ def exec(Connection connection, Map input) { confExportSourceId = input['confExportSourceId'] } - double confMaxError = 0.1 - if (input['confMaxError']) { - confMaxError = Double.valueOf(input['confMaxError'] as String) - } + double confMaxError = input.getOrDefault("confMaxError",0.1) as Double String frequencyFieldPrepend = "HZ" if (input['frequencyFieldPrepend']) { frequencyFieldPrepend = input['frequencyFieldPrepend'] as String } + double confLineSourceSpacingRatio = input.getOrDefault("confLineSourceSpacingRatio", 2.0) as Double + if (confLineSourceSpacingRatio <= 0) { + throw new IllegalArgumentException("Error : confLineSourceSpacingRatio must be greater than 0.") + } + // -------------------------------------------- // Initialize NoiseModelling propagation part // -------------------------------------------- @@ -495,7 +477,7 @@ def exec(Connection connection, Map input) { pointNoiseMap.setSourcesEmissionTableName(tableSourceEmission) } - sql.execute("drop table if exists " + TableLocation.parse(pointNoiseMap.noiseMapDatabaseParameters.receiversLevelTable)) + sql.execute("drop table if exists " + TableLocation.parse(pointNoiseMap.noiseMapDatabaseParameters.receiversLevelTable, dbType)) if (input['confRaysName'] && !((input['confRaysName'] as String).isEmpty())) { parameters.setRaysTable(input['confRaysName'] as String) @@ -509,6 +491,7 @@ def exec(Connection connection, Map input) { pointNoiseMap.setComputeVerticalDiffraction(compute_horizontal_diffraction) pointNoiseMap.setSoundReflectionOrder(reflexion_order) pointNoiseMap.setFrequencyFieldPrepend(frequencyFieldPrepend) + pointNoiseMap.getSceneInputSettings().setLineSourceSpacingRatio(confLineSourceSpacingRatio) // Set environmental parameters @@ -523,12 +506,12 @@ def exec(Connection connection, Map input) { } environmentalData.setWindRose(favOccurrences) } - if (input.containsKey('confHumidity')) { - environmentalData.setHumidity(input['confHumidity'] as Double) - } - if (input.containsKey('confTemperature')) { - environmentalData.setTemperature(input['confTemperature'] as Double) - } + double confHumidity = input.getOrDefault("confHumidity",70.0) as Double + environmentalData.setHumidity(confHumidity) + + double confTemperature = input.getOrDefault("confTemperature",15.0) as Double + environmentalData.setTemperature(confTemperature) + if(input.containsKey("tablePeriodAtmosphericSettings")) { pointNoiseMap.getSceneInputSettings().setPeriodAtmosphericSettingsTableName(input.get("tablePeriodAtmosphericSettings") as String) } @@ -546,6 +529,7 @@ def exec(Connection connection, Map input) { pointNoiseMap.setMaximumPropagationDistance(max_src_dist) pointNoiseMap.setMaximumReflectionDistance(max_ref_dist) + pointNoiseMap.setCloseReceiverReflectionWallDistance(close_receiver_reflection_wall_distance) pointNoiseMap.setWallAbsorption(wall_alpha) pointNoiseMap.setThreadCount(n_thread) @@ -564,13 +548,9 @@ def exec(Connection connection, Map input) { // -------------------------------------------- // Run Calculations // -------------------------------------------- - - // Init ProgressLogger (loading bar) - RootProgressVisitor progressLogger = new RootProgressVisitor(1, true, 1) - logger.info("Start calculation... ") - pointNoiseMap.run(connection, progressLogger) + pointNoiseMap.run(connection, progress) long elapsed = System.currentTimeMillis() - startCompute; long hours = TimeUnit.MILLISECONDS.toHours(elapsed) @@ -579,7 +559,11 @@ def exec(Connection connection, Map input) { elapsed -= TimeUnit.MINUTES.toMillis(minutes) long seconds = TimeUnit.MILLISECONDS.toSeconds(elapsed) String timeString = String.format(Locale.ROOT, "%02d:%02d:%02d", hours, minutes, seconds) - logger.info( "Calculation Done in $timeString ! ") + logger.info( "Calculation done in $timeString ! ") + + return [result : pointNoiseMap.noiseMapDatabaseParameters.receiversLevelTable] +} - return "Calculation Done ! The table $pointNoiseMap.noiseMapDatabaseParameters.receiversLevelTable have been created." +def exec(Connection connection, Map input) { + return exec(connection, input, new EmptyProgressVisitor()) } diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/PlotDirectivity.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/PlotDirectivity.groovy similarity index 77% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/PlotDirectivity.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/PlotDirectivity.groovy index ea79f7b11..0f3064c4e 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/PlotDirectivity.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/PlotDirectivity.groovy @@ -15,25 +15,19 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ +package org.noise_planet.noisemodelling.scripts.NoiseModelling -package org.noise_planet.noisemodelling.wps.NoiseModelling - -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore import org.noise_planet.noisemodelling.emission.directivity.DiscreteDirectivitySphere import org.noise_planet.noisemodelling.emission.directivity.OmnidirectionalDirection import org.noise_planet.noisemodelling.emission.directivity.PolarGraphDirectivity import org.noise_planet.noisemodelling.emission.railway.nmpb.RailWayNMPBParameters import org.noise_planet.noisemodelling.emission.railway.nmpb.TrainAttenuation - import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection -title = 'Plot the directivity graph of the specified DIR_ID' -description = '➡️ Plot the directivity graph of the specified "DIR_ID"' +title = 'Plots the directivity graph of the specified DIR_ID' +description = '➡️ Plots the directivity graph of the specified "DIR_ID"' inputs = [ tableSourceDirectivity : [ @@ -46,7 +40,8 @@ inputs = [ '
  • THETA : [-90;90] Vertical angle in degree. 0° front 90° top -90° bottom (FLOAT)
  • ' + '
  • PHI : [0;360] Horizontal angle in degree. 0° front 90° right (FLOAT)
  • ' + '
  • LW63, LW125, LW250, LW500, LW1000, LW2000, LW4000, LW8000 : attenuation levels in dB for each octave or third octave (FLOAT).
  • ' , - min : 0, max: 1, type: String.class + min : 0, max: 1, + type: String.class ], confDirId : [ name : 'Directivity Index', @@ -71,17 +66,15 @@ inputs = [ confScaleMinimum : [ name : 'Minimum scale attenuation (dB)', title : 'Minimum scale attenuation (dB)', - description: 'Minimum scale attenuation (in dB)

    '+ - '🛠 Default value: -35 dB', - min : 0, max: 1, + description: 'Minimum scale attenuation (in dB)', + default : -35, type : Double.class ], confScaleMaximum : [ name : 'Maximum scale attenuation (dB)', title : 'Maximum scale attenuation (dB)', - description: 'Maximum scale attenuation (in dB)

    '+ - '🛠 Default value: 0 dB', - min : 0, max: 1, + description: 'Maximum scale attenuation (in dB)', + default : 0, type : Double.class ] ] @@ -95,16 +88,8 @@ outputs = [ ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} -def exec(Connection connection, input) { +def exec(Connection connection, Map input) { // Create a logger to display messages in the geoserver logs and in the command prompt. Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") @@ -141,14 +126,10 @@ def exec(Connection connection, input) { } - double scaleMinimum = -35 - if (input['confScaleMinimum']) { - scaleMinimum = input['confScaleMinimum'] as Double - } - double scaleMaximum = 0 - if (input['confScaleMaximum']) { - scaleMaximum = input['confScaleMaximum'] as Double - } + double scaleMinimum = input.getOrDefault("confScaleMinimum",-35) as Double + + double scaleMaximum = input.getOrDefault("confScaleMaximum",0) as Double + directionAttributes = directivityData.get(directivityIndex) PolarGraphDirectivity polarGraphDirectivity = new PolarGraphDirectivity() StringBuilder sb = new StringBuilder() @@ -160,18 +141,3 @@ def exec(Connection connection, input) { sb.append(polarGraphDirectivity.generatePolarGraph(directionAttributes, frequency, scaleMinimum, scaleMaximum, PolarGraphDirectivity.ORIENTATION.FRONT)) return sb.toString() } - - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Railway_Emission_from_Traffic.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Railway_Emission_from_Traffic.groovy similarity index 70% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Railway_Emission_from_Traffic.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Railway_Emission_from_Traffic.groovy index 988621ae7..24bedc7e9 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Railway_Emission_from_Traffic.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Railway_Emission_from_Traffic.groovy @@ -10,13 +10,15 @@ * */ + /** + * @Author Pierre Aumond, Univ Gustave Eiffel + * @Author Adrien Le Bellec, Univ Gustave Eiffel + * @Author Olivier Chiello, Univ Gustave Eiffel + */ -package org.noise_planet.noisemodelling.wps.NoiseModelling +package org.noise_planet.noisemodelling.scripts.NoiseModelling -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.GeometryMetaData import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.SpatialResultSet @@ -24,22 +26,19 @@ import org.h2gis.utilities.TableLocation import org.h2gis.utilities.dbtypes.DBUtils import org.h2gis.utilities.wrapper.ConnectionWrapper import org.noise_planet.noisemodelling.jdbc.EmissionTableGenerator +import org.noise_planet.noisemodelling.jdbc.utils.DataBaseUtilities +import org.noise_planet.noisemodelling.jdbc.railway.RailWayLWIterator; import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.PreparedStatement import java.sql.SQLException -/** - * @Author Pierre Aumond, Univ Gustave Eiffel - * @Author Adrien Le Bellec, Univ Gustave Eiffel - * @Author Olivier Chiello, Univ Gustave Eiffel - */ + title = 'Compute railway emission noise map from vehicule, traffic table AND section table.' description = '➡️ Compute Rail Emission Noise Map from Day, Evening and Night traffic flow rate and speed estimates (specific format, see input details).
    ' + - '
    ' + - '✅ The output table is called LW_RAILWAY' + '
    ' + + '✅ The output table is called LW_RAILWAY' inputs = [ tableRailwayTraffic: [ @@ -62,48 +61,47 @@ inputs = [ '
  • IDSECTION* : A section identifier (PRIMARY KEY) (INTEGER)
  • ' + '
  • NTRACK* : Number of tracks (INTEGER)
  • ' + '
  • TRACKSPD* : Maximum speed on the section (in km/h) (DOUBLE)
  • ' + - '
  • TRANSFER : Track transfer function identifier (INTEGER)
  • ' + - '
  • ROUGHNESS : Rail roughness identifier (INTEGER)
  • ' + - '
  • IMPACT : Impact noise coefficient identifier (INTEGER)
  • ' + + '
  • TRANSFER : Track transfer function identifier, e.g. "SNCF5" or "EU7" (VARCHAR)
  • ' + + '
  • ROUGHNESS : Rail roughness identifier, e.g. "SNCF1" or "EU3" (VARCHAR)
  • ' + + '
  • IMPACT : Impact noise coefficient identifier, e.g. "SNCF1" or "EU1", empty for none (VARCHAR)
  • ' + '
  • CURVATURE : Listed code describing the curvature of the section (INTEGER)
  • ' + - '
  • BRIDGE : Bridge transfer function identifier (INTEGER)
  • ' + + '
  • BRIDGE : Bridge transfer function identifier, e.g. "EU3", empty for none (VARCHAR)
  • ' + '
  • TRACKSPD : Commercial speed on the section (in km/h) (DOUBLE)
  • ' + '
  • ISTUNNEL : Indicates whether the section is a tunnel or not (0 = no / 1 = yes) (BOOLEAN)
  • ', type: String.class + ], + vehicleDataFile : [ + name : 'Railway vehicle data file', + title : 'Railway vehicle data file', + description : 'URL of the railway vehicle data file in CNOSSOS format (json). By default, the file provided with NoiseModelling is used.', + type: String.class, + min: 0, max: 1 + ], + trainSetDataFile : [ + name : 'Railway train set data file', + title : 'Railway train set data file', + description : 'URL of the railway train set data file in CNOSSOS format (json). By default, the file provided with NoiseModelling is used.', + type: String.class, + min: 0, max: 1 + ], + railwayEmissionDataFile : [ + name : 'Railway emission data file', + title : 'Railway emission data file', + description : 'URL of the railway emission data file in CNOSSOS format (json). By default, the file provided with NoiseModelling is used.', + type: String.class, + min: 0, max: 1 ] ] -outputs = [result: [name: 'Result output string', - title: 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', - type: String.class -] +outputs = [ + result: [ + name: 'Result output string', + title: 'Result output string', + description: 'This type of result does not allow the blocks to be linked together.', + type: String.class + ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script def exec(Connection connection, input) { @@ -124,7 +122,7 @@ def exec(Connection connection, input) { sources_geom_table_name = sources_geom_table_name.toUpperCase() int sridSources = GeometryTableUtilities.getSRID(connection, TableLocation.parse(sources_geom_table_name)) - if (sridSources == 3785 || sridSources == 4326) throw new IllegalArgumentException("Error : Please use a metric projection for "+sources_geom_table_name+".") + if (!DataBaseUtilities.isSridMetric(connection, sridSources)) throw new IllegalArgumentException("Error : Please use a metric projection for "+sources_geom_table_name+".") if (sridSources == 0) throw new IllegalArgumentException("Error : The table "+sources_geom_table_name+" does not have an associated spatial reference system. (missing prj file on import ?)") String sources_table_traffic_name = input['tableRailwayTraffic'] as String @@ -155,9 +153,22 @@ def exec(Connection connection, input) { nSection = rs1.getInt("total") System.println('The table Rail Geom has ' + nSection + ' rail segments.') } + // Collect optional fields for input JSON + String vehicleDataFile = RailWayLWIterator.RAILWAY_VEHICLES_CNOSSOS_JSON + if(input['vehicleDataFile'] != null && !(input['vehicleDataFile'] as String).trim().isEmpty()) { + vehicleDataFile = input['vehicleDataFile'] as String + } + String trainSetDataFile = RailWayLWIterator.RAILWAY_TRAINSETS_JSON + if(input['trainSetDataFile'] != null && !(input['trainSetDataFile'] as String).trim().isEmpty()) { + trainSetDataFile = input['trainSetDataFile'] as String + } + String railwayEmissionDataFile = RailWayLWIterator.RAILWAY_EMISSION_CNOSSOS_JSON + if(input['railwayEmissionDataFile'] != null && !(input['railwayEmissionDataFile'] as String).trim().isEmpty()) { + railwayEmissionDataFile = input['railwayEmissionDataFile'] as String + } EmissionTableGenerator.makeTrainLWTable(connection, sources_geom_table_name, sources_table_traffic_name, - "LW_RAILWAY", "HZ") + "LW_RAILWAY", "HZ", vehicleDataFile, trainSetDataFile, railwayEmissionDataFile) TableLocation alterTable = TableLocation.parse("LW_RAILWAY", DBUtils.getDBType(connection)) GeometryMetaData metaData = GeometryTableUtilities.getMetaData(connection, alterTable, "THE_GEOM"); @@ -176,5 +187,3 @@ def exec(Connection connection, input) { return resultString } - - diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Road_Emission_from_Traffic.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Road_Emission_from_Traffic.groovy similarity index 62% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Road_Emission_from_Traffic.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Road_Emission_from_Traffic.groovy index 2e4ecaa7e..38ec7932f 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/NoiseModelling/Road_Emission_from_Traffic.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/NoiseModelling/Road_Emission_from_Traffic.groovy @@ -14,12 +14,9 @@ * @Author Pierre Aumond, Université Gustave Eiffel */ -package org.noise_planet.noisemodelling.wps.NoiseModelling +package org.noise_planet.noisemodelling.scripts.NoiseModelling -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.SpatialResultSet @@ -28,24 +25,19 @@ import org.h2gis.utilities.Tuple import org.h2gis.utilities.dbtypes.DBTypes import org.h2gis.utilities.dbtypes.DBUtils import org.h2gis.utilities.wrapper.ConnectionWrapper -import org.hsqldb.Table -import org.locationtech.jts.geom.Geometry import org.noise_planet.noisemodelling.jdbc.EmissionTableGenerator -import org.noise_planet.noisemodelling.jdbc.input.DefaultTableLoader import org.noise_planet.noisemodelling.pathfinder.utils.AcousticIndicatorsFunctions import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.sql.PreparedStatement import java.sql.ResultSet -import java.sql.SQLException import java.util.stream.Collectors title = 'Compute road emission noise map from road table.' description = '➡️ Compute Road Emission Noise Map from Day Evening Night traffic flow rate and speed estimates (specific format, see input details).
    ' + '
    ' + - '✅ The output table is called: LW_ROADS ' + '✅ The output table is called: LW_ROADS' inputs = [ tableRoads: [ @@ -56,28 +48,28 @@ inputs = [ " This function recognize the following columns (* mandatory) :
      " + '
    • PK : If there is a primary key defined, it will be copied with the same name and set as a primary for the output table
    • ' + '
    • IDSOURCE : an identifier, if present will be copied as is. It is expected if you will use LW_ROADS as SOURCES_EMISSION in the Noise_Level_From_Source script input (INTEGER)
    • ' + - "
    • PERIOD Any text that could be time period ex. D, E, N, DEN (Varchar), if present will be copied as is
    • " + - '
    • LV : Hourly average light vehicle count (DOUBLE)
    • ' + + "
    • PERIOD : Any text that could be time period ex. D, E, N, DEN (Varchar), if present will be copied as is
    • " + + '
    • LV : Hourly average light vehicle count (DOUBLE)
    • ' + '
    • MV : Hourly average medium heavy vehicles, delivery vans > 3.5 tons, buses, touring cars, etc. with two axles and twin tyre mounting on rear axle count (DOUBLE)
    • ' + - '
    • HGV : Hourly average heavy duty vehicles, touring cars, buses, with three or more axles (DOUBLE)
    • ' + - '
    • WAV : Hourly average mopeds, tricycles or quads ≤ 50 cc count (DOUBLE)
    • ' + - '
    • WBV : Hourly average motorcycles, tricycles or quads > 50 cc count (DOUBLE)
    • ' + - '
    • LV_SPD : Hourly average light vehicle speed (DOUBLE)
    • ' + - '
    • MV_SPD : Hourly average medium heavy vehicles speed (DOUBLE)
    • ' + - '
    • HGV_SPD : Hourly average heavy duty vehicles speed (DOUBLE)
    • ' + - '
    • WAV_SPD : Hourly average mopeds, tricycles or quads ≤ 50 cc speed (DOUBLE)
    • ' + - '
    • WBV_SPD : Hourly average motorcycles, tricycles or quads > 50 cc speed (DOUBLE)
    • ' + + '
    • HGV : Hourly average heavy duty vehicles, touring cars, buses, with three or more axles (DOUBLE)
    • ' + + '
    • WAV : Hourly average mopeds, tricycles or quads ≤ 50 cc count (DOUBLE)
    • ' + + '
    • WBV : Hourly average motorcycles, tricycles or quads > 50 cc count (DOUBLE)
    • ' + + '
    • LV_SPD : Hourly average light vehicle speed (DOUBLE)
    • ' + + '
    • MV_SPD : Hourly average medium heavy vehicles speed (DOUBLE)
    • ' + + '
    • HGV_SPD : Hourly average heavy duty vehicles speed (DOUBLE)
    • ' + + '
    • WAV_SPD : Hourly average mopeds, tricycles or quads ≤ 50 cc speed (DOUBLE)
    • ' + + '
    • WBV_SPD : Hourly average motorcycles, tricycles or quads > 50 cc speed (DOUBLE)
    • ' + "
    • LV_D LV_E LV_N : Hourly average light vehicle count (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + "
    • MV_D MV_E MV_N : Hourly average medium heavy vehicles, delivery vans > 3.5 tons, buses, touring cars, etc. with two axles and twin tyre mounting on rear axle count (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + - "
    • HGV_D HGV_E HGV_N : Hourly average heavy duty vehicles, touring cars, buses, with three or more axles (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + - "
    • WAV_D WAV_E WAV_N : Hourly average mopeds, tricycles or quads ≤ 50 cc count (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + - "
    • WBV_D WBV_E WBV_N : Hourly average motorcycles, tricycles or quads > 50 cc count (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + - "
    • LV_SPD_D LV_SPD_E LV_SPD_N : Hourly average light vehicle speed (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + - "
    • MV_SPD_D MV_SPD_E MV_SPD_N : Hourly average medium heavy vehicles speed (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + - "
    • HGV_SPD_D HGV_SPD_E HGV_SPD_N : Hourly average heavy duty vehicles speed (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + - "
    • WAV_SPD_D WAV_SPD_E WAV_SPD_N : Hourly average mopeds, tricycles or quads ≤ 50 cc speed (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + - "
    • WBV_SPD_D WBV_SPD_E WBV_SPD_N : Hourly average motorcycles, tricycles or quads > 50 cc speed (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + - "
    • PVMT : CNOSSOS road pavement identifier (ex: NL05)(default NL08) (VARCHAR)
    • " + + "
    • HGV_D HGV_E HGV_N : Hourly average heavy duty vehicles, touring cars, buses, with three or more axles (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + + "
    • WAV_D WAV_E WAV_N : Hourly average mopeds, tricycles or quads ≤ 50 cc count (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + + "
    • WBV_D WBV_E WBV_N : Hourly average motorcycles, tricycles or quads > 50 cc count (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + + "
    • LV_SPD_D LV_SPD_E LV_SPD_N : Hourly average light vehicle speed (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + + "
    • MV_SPD_D MV_SPD_E MV_SPD_N : Hourly average medium heavy vehicles speed (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + + "
    • HGV_SPD_D HGV_SPD_E HGV_SPD_N : Hourly average heavy duty vehicles speed (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + + "
    • WAV_SPD_D WAV_SPD_E WAV_SPD_N : Hourly average mopeds, tricycles or quads ≤ 50 cc speed (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + + "
    • WBV_SPD_D WBV_SPD_E WBV_SPD_N : Hourly average motorcycles, tricycles or quads > 50 cc speed (6-18h)(18-22h)(22-6h) (DOUBLE)
    • " + + "
    • PVMT : CNOSSOS road pavement identifier (ex: NL05)(default NL08) (VARCHAR)
    • " + "
    • TS_STUD : A limited period Ts (in months) over the year where a average proportion pm of light vehicles are equipped with studded tyres (0-12) (DOUBLE)
    • " + "
    • PM_STUD : Average proportion of vehicles equipped with studded tyres during TS_STUD period (0-1) (DOUBLE)
    • " + "
    • JUNC_DIST : Distance to junction in meters (DOUBLE)
    • " + @@ -85,16 +77,15 @@ inputs = [ "
    • SLOPE : Slope (in %) of the road section. If the field is not filled in, the LINESTRING z-values will be used to calculate the slope and the traffic direction (way field) will be force to 3 (bidirectional). (DOUBLE)
    • " + "
    • WAY : Define the way of the road section. 1 = one way road section and the traffic goes in the same way that the slope definition you have used, 2 = one way road section and the traffic goes in the inverse way that the slope definition you have used, 3 = bi-directional traffic flow, the flow is split into two components and correct half for uphill and half for downhill (INTEGER)
    • " + "

    This table can be generated from the WPS Block 'Import_OSM'. .", - type : String.class, + type : String.class + ], coefficientVersion : [ name : 'Coefficient version', title : 'Coefficient version', - description: '🌧 Cnossos coefficient version (1 = 2015, 2 = 2020)

    ' + - '🛠 Default value: 2', - min : 0, max: 1, + description: '🌧 Cnossos coefficient version (1 = 2015, 2 = 2020)', + default : 2, type : Double.class - ], - ] + ] ] outputs = [ @@ -105,41 +96,18 @@ outputs = [ type : String.class ] ] -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} // main function of the script -def exec(Connection connection, input) { +def exec(Connection connection, Map input) { + + int coefficientVersion = input.getOrDefault("coefficientVersion",2) as Integer - int coefficientVersion = 2 - if (input.containsKey('coefficientVersion')) { - coefficientVersion = Integer.parseInt(input['confHumidity'] as String) - } DBTypes dbType = DBUtils.getDBType(connection) + def outputTableName = TableLocation.capsIdentifier("lw_roads", dbType) + //Need to change the ConnectionWrapper to WpsConnectionWrapper to work under postGIS database connection = new ConnectionWrapper(connection) @@ -168,7 +136,7 @@ def exec(Connection connection, input) { List geomFields = GeometryTableUtilities.getGeometryColumnNames(connection, sourceTableIdentifier) //Get the primary key field of the source table - Tuple primaryKeyColumn = JDBCUtilities.getIntegerPrimaryKeyNameAndIndex(connection, TableLocation.parse( sources_table_name)) + Tuple primaryKeyColumn = JDBCUtilities.getIntegerPrimaryKeyNameAndIndex(connection, TableLocation.parse( sources_table_name, dbType)) // ------------------- // Init table LW_ROADS @@ -186,82 +154,68 @@ def exec(Connection connection, input) { boolean hasIdSourceField = lowerCaseColumnNames.contains("idsource") // drop table LW_ROADS if exists and the create and prepare the table - sql.execute("drop table if exists LW_ROADS;") + sql.execute("drop table if exists $outputTableName;" as String) - def createTableQuery = new StringBuilder("CREATE TABLE LW_ROADS (") - def preparedInsertQuery = new StringBuilder("INSERT INTO LW_ROADS(") - int fieldCount = 0 + // Use lists to collect the column definitions and column names + def createDefinitions = [] + def columnNames = [] - if(primaryKeyColumn != null) { - createTableQuery.append(primaryKeyColumn.first()) - createTableQuery.append(" integer not null, ") - preparedInsertQuery.append(primaryKeyColumn.first()) - preparedInsertQuery.append(", ") - fieldCount++ + if (primaryKeyColumn != null) { + def pkName = primaryKeyColumn.first() + createDefinitions << "${pkName} integer not null" + columnNames << pkName } - if(hasIdSourceField) { - createTableQuery.append("IDSOURCE integer, ") - preparedInsertQuery.append("IDSOURCE, ") - fieldCount++ + if (hasIdSourceField) { + createDefinitions << "IDSOURCE integer" + columnNames << "IDSOURCE" } def force3D = false - if(geomFields.size() > 0) { - createTableQuery.append(geomFields.get(0)) - createTableQuery.append(" Geometry, ") - preparedInsertQuery.append(geomFields.get(0)) - preparedInsertQuery.append(", ") - fieldCount++ + if (geomFields.size() > 0) { + def geomName = geomFields.get(0) + columnNames << geomName + def tupMeta = GeometryTableUtilities.getFirstColumnMetaData(connection, sourceTableIdentifier) - if(tupMeta != null && !tupMeta.second().hasZ()) { - force3D = true - logger.warn("The geometry field "+geomFields.get(0)+" is not 3D. The z value will be forced to 0.05m height.") + if (tupMeta != null) { + createDefinitions << "$geomName ${tupMeta.second().SQL}" + if (!tupMeta.second().hasZ()) { + force3D = true + logger.warn("The geometry field ${geomName} is not 3D. The z value will be forced to 0.05m height.") + } } } - if(!hasPeriodField) { + if (!hasPeriodField) { ["D", "E", "N"].each { period -> ["63", "125", "250", "500", "1000", "2000", "4000", "8000"].each { freq -> - createTableQuery.append("HZ") - createTableQuery.append(period) - createTableQuery.append(freq) - createTableQuery.append(" double precision, ") - preparedInsertQuery.append("HZ") - preparedInsertQuery.append(period) - preparedInsertQuery.append(freq) - preparedInsertQuery.append(", ") - fieldCount++ + def col = "HZ${period}${freq}" + createDefinitions << "${col} double precision" + columnNames << col } } } else { - createTableQuery.append("PERIOD varchar, ") - fieldCount++ - preparedInsertQuery.append("PERIOD, ") + createDefinitions << "PERIOD varchar" + columnNames << "PERIOD" + ["63", "125", "250", "500", "1000", "2000", "4000", "8000"].each { freq -> - createTableQuery.append("HZ") - createTableQuery.append(freq) - createTableQuery.append(" double precision, ") - preparedInsertQuery.append("HZ") - preparedInsertQuery.append(freq) - preparedInsertQuery.append(", ") - fieldCount++ + def col = "HZ${freq}" + createDefinitions << "${col} double precision" + columnNames << col } } - // Create table - createTableQuery.setLength(createTableQuery.length() - 2) // remove last comma - createTableQuery.append(");") - sql.execute(createTableQuery.toString()) + // 1. Create the Table Query + // join() adds commas only between elements + def createTableQuery = "CREATE TABLE $outputTableName (${createDefinitions.join(", ")});" + sql.execute(createTableQuery as String) - // Prepared insert query - preparedInsertQuery.setLength(preparedInsertQuery.length() - 2) // remove last comma - preparedInsertQuery.append(") VALUES (") - String.join(", ", Collections.nCopies(fieldCount, "?")).each { - preparedInsertQuery.append(it) - } - preparedInsertQuery.append(");") - def qry = preparedInsertQuery.toString() + // 2. Prepared Insert Query + int fieldCount = columnNames.size() + // Create a list of '?' characters equal to the number of fields + def placeholders = (["?"] * fieldCount).join(", ") + + def qry = "INSERT INTO $outputTableName (" + columnNames.join(", ") + ") VALUES (" + placeholders + ");" // -------------------------------------- // Start calculation and fill the table @@ -320,23 +274,21 @@ def exec(Connection connection, input) { if(force3D) { // Force the Z height to the road segments - sql.execute("UPDATE LW_ROADS SET THE_GEOM = ST_UPDATEZ(The_geom, 0.05);") + sql.execute("UPDATE $outputTableName SET THE_GEOM = ST_UPDATEZ(The_geom, 0.05);" as String) } if(primaryKeyColumn != null) { // Set primary key to the road table - sql.execute("ALTER TABLE LW_ROADS ADD PRIMARY KEY ("+primaryKeyColumn.first()+"); ") + sql.execute("ALTER TABLE $outputTableName ADD PRIMARY KEY (${primaryKeyColumn.first()}); " as String) } - resultString = "Calculation Done ! The table LW_ROADS has been created." + resultString = "Calculation Done ! The table $outputTableName has been created." // print to command window logger.info('\nResult : ' + resultString) - logger.info('End : LW_ROADS from Emission') + logger.info("End : $outputTableName from Emission") // print to WPS Builder - return resultString + return [result: outputTableName] } - - diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Building_Grid.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Building_Grid.groovy similarity index 72% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Building_Grid.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Building_Grid.groovy index 2fc191625..2316c19c8 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Building_Grid.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Building_Grid.groovy @@ -1,473 +1,447 @@ -/** - * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. - * - * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). - * - * - * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. - * - * Contact: contact@noise-planet.org - * - */ - -/** - * @Author Nicolas Fortin, Université Gustave Eiffel - * @Contributor Ignacio Soto Molina, Ministry for Ecological Transition (MITECO), Spain - Delete Recivers Inside Buildings - */ - - -package org.noise_planet.noisemodelling.wps.Receivers - -import geoserver.GeoServer -import geoserver.catalog.Store -import groovy.sql.Sql -import groovy.time.TimeCategory -import org.geotools.jdbc.JDBCDataStore -import org.h2.util.geometry.EWKTUtils -import org.h2.util.geometry.JTSUtils -import org.h2gis.functions.spatial.crs.ST_SetSRID -import org.h2gis.functions.spatial.crs.ST_Transform -import org.h2gis.utilities.JDBCUtilities -import org.h2gis.utilities.GeometryTableUtilities -import org.h2gis.utilities.TableLocation -import org.h2gis.utilities.dbtypes.DBUtils -import org.locationtech.jts.geom.* -import org.locationtech.jts.io.WKTReader -import org.noise_planet.noisemodelling.jdbc.DelaunayReceiversMaker -import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import java.sql.Connection - -title = 'Buildings Grid' -description = '➡️ Generates receivers, 2m around the building facades, at a given height.
    ' + - '
    ' + - '✅ The output table is called RECEIVERS

    '+ - 'Building grid output' - -inputs = [ - tableBuilding : [ - name : 'Buildings table name', - title : 'Buildings table name', - description: 'Name of the Buildings table.

    ' + - 'The table must contain:
      ' + - '
    • THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON)
    • ' + - '
    • HEIGHT : the height of the building (in meter) (FLOAT)
    • ' + - '
    • POP : (optional field) building population to add in the receiver attribute (FLOAT)
    ', - type : String.class - ], - fence : [ - name : 'Fence geometry', - title : 'Extent filter', - description: 'Create receivers only in the provided polygon (fence)', - min : 0, - max : 1, - type : Geometry.class - ], - fenceTableName : [ - name : 'Fence geometry from table', - title : 'Filter using table bounding box', - description: 'Filter receivers, using the bounding box of the given table name:
      ' + - '
    1. Extract the bounding box of the specified table,
    2. ' + - '
    3. then create only receivers on the table bounding box.
    ' + - 'The given table must contain:
      ' + - '
    • THE_GEOM : any geometry type.
    ', - min : 0, - max : 1, - type : String.class - ], - sourcesTableName : [ - name : 'Sources table name', - title : 'Sources table name', - description: 'Keep only receivers that are at least 1 meter from the provided source geometries.

    ' + - 'The source geometries table must contain:
      ' + - '
    • THE_GEOM : any geometry type.
    ', - min : 0, - max : 1, - type : String.class - ], - delta : [ - name : 'Receivers minimal distance', - title : 'Distance between receivers', - description: 'Distance between receivers (in the Cartesian plane - in meter) (FLOAT)

    '+ - '🛠 Default value: 10 ', - min : 0, - max : 1, - type : Double.class - ], - height : [ - name : 'Height', - title : 'Height', - description: 'Height of receivers (in meter) (FLOAT)

    ' + - '🛠 Default value: 4', - min : 0, - max : 1, - type : Double.class - ], - distance : [ - name : 'Distance', - title : 'Distance from wall', - description: 'Distance of receivers from the wall in meters (FLOAT)

    ' + - '🛠 Default value: 2 ', - min : 0, max: 1, - type : Double.class - ] -] - -outputs = [ - result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', - type : String.class - ] -] - -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - - -def exec(Connection connection, input) { - - // output string, the information given back to the user - String resultString = null - - // Create a logger to display messages in the geoserver logs and in the command prompt. - Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") - - // print to command window - logger.info('Start : Receivers grid around buildings') - logger.info("inputs {}", input) // log inputs of the run - - - String receivers_table_name = "RECEIVERS" - - Double delta = 10 - if (input['delta']) { - delta = input['delta'] as Double - } - - Double h = 4.0d - if (input['height']) { - h = input['height'] as Double - } - - Double distance = 2.0d - if (input['distance']) { - distance = input['distance'] as Double - } - - String sources_table_name = "SOURCES" - if (input['sourcesTableName']) { - sources_table_name = input['sourcesTableName'] - } - sources_table_name = sources_table_name.toUpperCase() - - - String building_table_name = input['tableBuilding'] - building_table_name = building_table_name.toUpperCase() - - Boolean hasPop = JDBCUtilities.hasField(connection, building_table_name, "POP") - if (hasPop) logger.info("The building table has a column named POP.") - if (!hasPop) logger.info("The building table has not a column named POP.") - - if (!JDBCUtilities.hasField(connection, building_table_name, "HEIGHT")) { - resultString = "Buildings table must have HEIGHT field" - return resultString - } - - //Statement sql = connection.createStatement() - Sql sql = new Sql(connection) - sql.execute(String.format("DROP TABLE IF EXISTS %s", receivers_table_name)) - - // Reproject fence - int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(building_table_name)) - if (srid == 0 && input['sourcesTableName']) { - srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(sources_table_name)) - } - - Geometry fence = null - if (input['fence']) { - if(input['fence'] instanceof Geometry) { - fence = input['fence'] - } else { - fence = JTSUtils.ewkb2geometry(EWKTUtils.ewkt2ewkb(input['fence'] as String)) - } - } - - // Fence handling (two options): - // 1) Direct geometry passed as 'fence' (handled above) - // 2) Bounding box extracted from another table via 'fenceTableName' - // Implemented by IsotoCedex (adapted from Building_Grid.groovy) - if (input['fenceTableName']) { - fence = GeometryTableUtilities.getEnvelope(connection, TableLocation.parse(input['fenceTableName'] as String), 'THE_GEOM') - } - - if (fence != null && srid != 0 && fence.getSRID() != srid) { - if (fence.getSRID() == 0) { - // If the provided srid is not known, it is considered being in the WGS84 projection system - fence = ST_SetSRID.setSRID(fence, 4326) - } - // Transform fence to the same coordinate system than the buildings & sources - fence = ST_Transform.ST_Transform(connection, fence, srid) - } - - - def buildingPk = JDBCUtilities.getColumnName(connection, building_table_name, - JDBCUtilities.getIntegerPrimaryKey(connection, - TableLocation.parse(building_table_name, DBUtils.getDBType(connection)))) - if (buildingPk == "") { - return "Buildings table must have a primary key" - } - - sql.execute("drop table if exists tmp_receivers_lines") - - if (fence != null) { - sql.execute("create table tmp_receivers_lines(pk int not null primary key, the_geom geometry) as select " + buildingPk + " as pk, st_simplifypreservetopology(ST_ToMultiLine(ST_Buffer(the_geom, :distance_wall, 'join=bevel')), 0.05) the_geom from " + building_table_name + " WHERE the_geom && :fenceGeom AND ST_INTERSECTS(the_geom, :fenceGeom)", [fenceGeom : fence, distance_wall : distance]) - } else { - sql.execute("create table tmp_receivers_lines(pk int not null primary key, the_geom geometry) as select " + buildingPk + " as pk, st_simplifypreservetopology(ST_ToMultiLine(ST_Buffer(the_geom, :distance_wall, 'join=bevel')), 0.05) the_geom from " + building_table_name, [distance_wall : distance]) - } - - logger.info('create line of receivers') - - sql.execute("drop table if exists tmp_relation_screen_building;") - sql.execute("create spatial index on tmp_receivers_lines(the_geom)") - logger.info('list buildings that will remove receivers (if height is superior than receiver height)') - - sql.execute("create table tmp_relation_screen_building as select b." + buildingPk + " as PK_building, s.pk as pk_screen from " + building_table_name + " b, tmp_receivers_lines s where b.the_geom && s.the_geom and s.pk != b." + buildingPk + " and ST_Intersects(b.the_geom, s.the_geom) and b.height > " + h) - - sql.execute("CREATE INDEX ON tmp_relation_screen_building(PK_building);") - sql.execute("CREATE INDEX ON tmp_relation_screen_building(pk_screen);") - sql.execute("drop table if exists tmp_screen_truncated;") - logger.info('truncate receiver lines') - sql.execute("create table tmp_screen_truncated(pk_screen integer not null, the_geom geometry) as select r.pk_screen, ST_DIFFERENCE(s.the_geom, ST_BUFFER(ST_ACCUM(b.the_geom), :distance_wall)) the_geom from tmp_relation_screen_building r, " + building_table_name + " b, tmp_receivers_lines s WHERE PK_building = b." + buildingPk + " AND pk_screen = s.pk GROUP BY pk_screen, s.the_geom;", [distance_wall : distance]) - logger.info('Add primary key') - sql.execute("ALTER TABLE tmp_screen_truncated add primary key(pk_screen)") - sql.execute("DROP TABLE IF EXISTS TMP_SCREENS_MERGE;") - sql.execute("DROP TABLE IF EXISTS TMP_SCREENS;") - logger.info('union of truncated receivers and non tructated') - sql.execute("create table TMP_SCREENS_MERGE (pk integer not null, the_geom geometry) as select s.pk, s.the_geom the_geom from tmp_receivers_lines s where not st_isempty(s.the_geom) and pk not in (select pk_screen from tmp_screen_truncated) UNION ALL select pk_screen, the_geom from tmp_screen_truncated where not st_isempty(the_geom);") - logger.info('Add primary key') - sql.execute("ALTER TABLE TMP_SCREENS_MERGE add primary key(pk)") - logger.info('Collect all lines and convert into points using custom method') - sql.execute("CREATE TABLE TMP_SCREENS(pk integer, the_geom geometry)") - def qry = 'INSERT INTO TMP_SCREENS(pk , the_geom) VALUES (?,?);' - GeometryFactory factory = new GeometryFactory(new PrecisionModel(), srid); - logger.info('Split line to points') - int nrows = sql.firstRow('SELECT COUNT(*) FROM TMP_SCREENS_MERGE')[0] as Integer - RootProgressVisitor progressLogger = new RootProgressVisitor(nrows, true, 1) - sql.withBatch(100, qry) { ps -> - sql.eachRow("SELECT pk, the_geom from TMP_SCREENS_MERGE") { row -> - List pts = new ArrayList() - def geom = row[1] as Geometry - if (geom instanceof LineString) { - splitLineStringIntoPoints(geom as LineString, delta, pts) - } else if (geom instanceof MultiLineString) { - for (int idgeom = 0; idgeom < geom.numGeometries; idgeom++) { - splitLineStringIntoPoints(geom.getGeometryN(idgeom) as LineString, delta, pts) - } - } - for (int idp = 0; idp < pts.size(); idp++) { - Coordinate pt = pts.get(idp); - if (!Double.isNaN(pt.x) && !Double.isNaN(pt.y)) { - // define coordinates of receivers - Coordinate newCoord = new Coordinate(pt.x, pt.y, h) - ps.addBatch(row[0] as Integer, factory.createPoint(newCoord)) - } - } - progressLogger.endStep() - } - } - sql.execute("drop table if exists TMP_SCREENS_MERGE") - sql.execute("drop table if exists " + receivers_table_name) - - if (!hasPop) { - logger.info('create RECEIVERS table...') - - - sql.execute("create table " + receivers_table_name + "(pk integer not null AUTO_INCREMENT, the_geom geometry,build_pk integer)") - sql.execute("insert into " + receivers_table_name + "(the_geom, build_pk) select ST_SetSRID(the_geom," + srid.toInteger() + ") , pk building_pk from TMP_SCREENS;") - logger.info('Add primary key') - sql.execute("ALTER TABLE "+receivers_table_name+" add primary key(pk)") - // Remove receivers left inside buildings (non-POP case) - sql.execute("delete from " + receivers_table_name + " g " + - "where exists (" + - " select 1 from " + building_table_name + " b " + - " where b.the_geom && g.the_geom " + - " and ST_Contains(b.the_geom, g.the_geom) " + - " limit 1)") - - - if (input['sourcesTableName']) { - // Delete receivers near sources - logger.info('Delete receivers near sources...') - sql.execute("delete from " + receivers_table_name + " g where exists (select 1 from " + sources_table_name + " r where st_expand(g.the_geom, 1, 1) && r.the_geom and st_distance(g.the_geom, r.the_geom) < 1 limit 1);") - } - - if (fence != null) { - // delete receiver not in fence filter - sql.execute("delete from " + receivers_table_name + " g where not ST_INTERSECTS(g.the_geom , :fenceGeom);", [fenceGeom : fence]) - } - } else { - logger.info('create RECEIVERS table...') - // building have population attribute - // set population attribute divided by number of receiver to each receiver - sql.execute("DROP TABLE IF EXISTS tmp_receivers") - sql.execute("create table tmp_receivers(pk integer not null AUTO_INCREMENT, the_geom geometry,build_pk integer not null)") - - sql.execute("insert into tmp_receivers(the_geom, build_pk) select ST_SetSRID(the_geom," + srid.toInteger() + "), pk building_pk from TMP_SCREENS;") - logger.info('Add primary key') - sql.execute("ALTER TABLE tmp_receivers add primary key(pk)") - // Remove recipients left inside buildings BEFORE distributing POP - sql.execute("delete from tmp_receivers g " + - "where exists (" + - " select 1 from " + building_table_name + " b " + - " where b.the_geom && g.the_geom " + - " and ST_Contains(b.the_geom, g.the_geom) " + - " limit 1)") - - - if (input['sourcesTableName']) { - // Delete receivers near sources - logger.info('Delete receivers near sources...') - sql.execute("delete from tmp_receivers g where exists (select 1 from " + sources_table_name + " r where st_expand(g.the_geom, 1) && r.the_geom and st_distance(g.the_geom, r.the_geom) < 1 limit 1);") - } - - if (fence != null) { - // delete receiver not in fence filter - sql.execute("delete from tmp_receivers g where not ST_INTERSECTS(g.the_geom , :fenceGeom);", [fenceGeom : fence]) - } - - sql.execute("CREATE INDEX ON tmp_receivers(build_pk)") - logger.info('Distribute population over receivers') - sql.execute("create table " + receivers_table_name + "(pk integer not null AUTO_INCREMENT, the_geom geometry,build_pk integer, pop real)"); - sql.execute("insert into "+receivers_table_name+"(the_geom, build_pk, pop) select a.the_geom, a.build_pk, b.pop/COUNT(DISTINCT aa.pk)::float from tmp_receivers a, " + building_table_name + " b,tmp_receivers aa where b." + buildingPk + " = a.build_pk and a.build_pk = aa.build_pk GROUP BY a.the_geom, a.build_pk, b.pop;") - logger.info('Add primary key') - sql.execute("ALTER TABLE "+receivers_table_name+" add primary key(pk)") - - sql.execute("drop table if exists tmp_receivers") - } - // cleaning - sql.execute("drop table TMP_SCREENS") - sql.execute("drop table tmp_screen_truncated") - sql.execute("drop table tmp_relation_screen_building") - sql.execute("drop table tmp_receivers_lines") - sql.execute("drop table if exists tmp_buildings;") - // Process Done - resultString = "Process done. Table of receivers " + receivers_table_name + " created !" - - // print to command window - logger.info('Result : ' + resultString) - logger.info('End : Receivers grid around buildings') - - // print to WPS Builder - return resultString - -} - - -/** - * - * @param geom Geometry - * @param segmentSizeConstraint Maximal distance between points - * @param [out]pts computed points - * @return Fixed distance between points - */ -double splitLineStringIntoPoints(LineString geom, double segmentSizeConstraint, - List pts) { - // If the linear sound source length is inferior than half the distance between the nearest point of the sound - // source and the receiver then it can be modelled as a single point source - double geomLength = geom.getLength(); - if (geomLength < segmentSizeConstraint) { - // Return mid point - Coordinate[] points = geom.getCoordinates(); - double segmentLength = 0; - final double targetSegmentSize = geomLength / 2.0; - for (int i = 0; i < points.length - 1; i++) { - Coordinate a = points[i]; - final Coordinate b = points[i + 1]; - double length = a.distance3D(b); - if (length + segmentLength > targetSegmentSize) { - double segmentLengthFraction = (targetSegmentSize - segmentLength) / length; - Coordinate midPoint = new Coordinate(a.x + segmentLengthFraction * (b.x - a.x), - a.y + segmentLengthFraction * (b.y - a.y), - a.z + segmentLengthFraction * (b.z - a.z)); - pts.add(midPoint); - break; - } - segmentLength += length; - } - return geom.getLength(); - } else { - double targetSegmentSize = geomLength / Math.ceil(geomLength / segmentSizeConstraint); - Coordinate[] points = geom.getCoordinates(); - double segmentLength = 0.0; - - // Mid point of segmented line source - def midPoint = null; - for (int i = 0; i < points.length - 1; i++) { - Coordinate a = points[i]; - final Coordinate b = points[i + 1]; - double length = a.distance3D(b); - if (Double.isNaN(length)) { - length = a.distance(b); - } - while (length + segmentLength > targetSegmentSize) { - //LineSegment segment = new LineSegment(a, b); - double segmentLengthFraction = (targetSegmentSize - segmentLength) / length; - Coordinate splitPoint = new Coordinate(); - splitPoint.x = a.x + segmentLengthFraction * (b.x - a.x); - splitPoint.y = a.y + segmentLengthFraction * (b.y - a.y); - splitPoint.z = a.z + segmentLengthFraction * (b.z - a.z); - if (midPoint == null && length + segmentLength > targetSegmentSize / 2) { - segmentLengthFraction = (targetSegmentSize / 2.0 - segmentLength) / length; - midPoint = new Coordinate(a.x + segmentLengthFraction * (b.x - a.x), - a.y + segmentLengthFraction * (b.y - a.y), - a.z + segmentLengthFraction * (b.z - a.z)); - } - pts.add(midPoint); - a = splitPoint; - length = a.distance3D(b); - if (Double.isNaN(length)) { - length = a.distance(b); - } - segmentLength = 0; - midPoint = null; - } - if (midPoint == null && length + segmentLength > targetSegmentSize / 2) { - double segmentLengthFraction = (targetSegmentSize / 2.0 - segmentLength) / length; - midPoint = new Coordinate(a.x + segmentLengthFraction * (b.x - a.x), - a.y + segmentLengthFraction * (b.y - a.y), - a.z + segmentLengthFraction * (b.z - a.z)); - } - segmentLength += length; - } - if (midPoint != null) { - pts.add(midPoint); - } - return targetSegmentSize; - } -} - +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + +/** + * @Author Nicolas Fortin, Université Gustave Eiffel + * @Contributor Ignacio Soto Molina, Ministry for Ecological Transition (MITECO), Spain - Delete Receivers Inside Buildings + */ + +package org.noise_planet.noisemodelling.scripts.Receivers + +import groovy.sql.Sql +import groovy.time.TimeCategory +import org.h2.util.geometry.EWKTUtils +import org.h2.util.geometry.JTSUtils +import org.h2gis.functions.spatial.crs.ST_SetSRID +import org.h2gis.functions.spatial.crs.ST_Transform +import org.h2gis.utilities.JDBCUtilities +import org.h2gis.utilities.GeometryTableUtilities +import org.h2gis.utilities.TableLocation +import org.h2gis.utilities.dbtypes.DBUtils +import org.locationtech.jts.geom.* +import org.locationtech.jts.io.WKTReader +import org.noise_planet.noisemodelling.jdbc.DelaunayReceiversMaker +import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.sql.Connection + +title = 'Buildings Grid' +description = '➡️ Generates receivers, 2m around the building facades, at a given height.
    ' + + '
    ' + + '✅ The output table is called RECEIVERS and contain a field build_pk corresponding to the primary key of the buildings table

    '+ + 'Building grid output' + +inputs = [ + tableBuilding : [ + name : 'Buildings table name', + title : 'Buildings table name', + description: 'Name of the Buildings table.

    ' + + 'The table must contain:
      ' + + '
    • THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON)
    • ' + + '
    • HEIGHT : the height of the building (in meter) (FLOAT)
    • ' + + '
    • POP : (optional field) building population to add in the receiver attribute (FLOAT)
    ', + type : String.class + ], + fence : [ + name : 'Fence geometry', + title : 'Extent filter', + description: 'Create receivers only in the provided polygon (fence)', + min : 0, + max : 1, + type : Geometry.class + ], + fenceTableName : [ + name : 'Fence geometry from table', + title : 'Filter using table bounding box', + description: 'Filter receivers, using the bounding box of the given table name:
      ' + + '
    1. Extract the bounding box of the specified table,
    2. ' + + '
    3. then create only receivers on the table bounding box.
    ' + + 'The given table must contain:
      ' + + '
    • THE_GEOM : any geometry type.
    ', + min : 0, + max : 1, + type : String.class + ], + sourcesTableName : [ + name : 'Sources table name', + title : 'Sources table name', + description: 'Keep only receivers that are at least 1 meter from the provided source geometries.

    ' + + 'The source geometries table must contain:
      ' + + '
    • THE_GEOM : any geometry type.
    ', + min : 0, + max : 1, + type : String.class + ], + delta : [ + name : 'Receivers minimal distance', + title : 'Distance between receivers', + description: 'Distance between receivers (in the Cartesian plane - in meter) (FLOAT)', + default : 10, + type : Double.class + ], + height : [ + name : 'Height', + title : 'Height', + description: 'Height of receivers (in meter) (FLOAT)', + default : 4, + type : Double.class + ], + distance : [ + name : 'Distance', + title : 'Distance from wall', + description: 'Distance between the receivers and the wall, in metres (FLOAT)', + default : 2, + type : Double.class + ] +] + +outputs = [ + result: [ + name : 'Created table', + title : 'Created table', + description: 'Name of the table containing the results of the computation. Can be used as input for another process.', + type : String.class + ] +] + + +def exec(Connection connection, Map input) { + + // output string, the information given back to the user + String resultString = null + + // Create a logger to display messages in the geoserver logs and in the command prompt. + Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") + + // print to command window + logger.info('Start : Receivers grid around buildings') + logger.info("inputs {}", input) // log inputs of the run + + + String receivers_table_name = "RECEIVERS" + + double delta = input.getOrDefault("delta",10) as Double + + double h = input.getOrDefault("height",4.0d) as Double + + double distance = input.getOrDefault("distance",2.0d) as Double + + String sources_table_name = "SOURCES" + if (input['sourcesTableName']) { + sources_table_name = input['sourcesTableName'] + } + sources_table_name = sources_table_name.toUpperCase() + + + String building_table_name = input['tableBuilding'] + building_table_name = building_table_name.toUpperCase() + + Boolean hasPop = JDBCUtilities.hasField(connection, building_table_name, "POP") + if (hasPop) logger.info("The building table has a column named POP.") + if (!hasPop) logger.info("The building table has not a column named POP.") + + if (!JDBCUtilities.hasField(connection, building_table_name, "HEIGHT")) { + resultString = "Buildings table must have HEIGHT field" + return resultString + } + + //Statement sql = connection.createStatement() + Sql sql = new Sql(connection) + sql.execute(String.format("DROP TABLE IF EXISTS %s", receivers_table_name)) + + // Reproject fence + int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(building_table_name)) + if (srid == 0 && input['sourcesTableName']) { + srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(sources_table_name)) + } + + Geometry fence = null + if (input['fence']) { + if(input['fence'] instanceof Geometry) { + fence = input['fence'] + } else { + fence = JTSUtils.ewkb2geometry(EWKTUtils.ewkt2ewkb(input['fence'] as String)) + } + } + + // Fence handling (two options): + // 1) Direct geometry passed as 'fence' (handled above) + // 2) Bounding box extracted from another table via 'fenceTableName' + // Implemented by IsotoCedex (adapted from Building_Grid.groovy) + if (input['fenceTableName']) { + fence = GeometryTableUtilities.getEnvelope(connection, TableLocation.parse(input['fenceTableName'] as String), 'THE_GEOM') + } + + if (fence != null && srid != 0 && fence.getSRID() != srid) { + if (fence.getSRID() == 0) { + // If the provided srid is not known, it is considered being in the WGS84 projection system + fence = ST_SetSRID.setSRID(fence, 4326) + } + // Transform fence to the same coordinate system than the buildings & sources + fence = ST_Transform.ST_Transform(connection, fence, srid) + } + + + def buildingPk = JDBCUtilities.getColumnName(connection, building_table_name, + JDBCUtilities.getIntegerPrimaryKey(connection, + TableLocation.parse(building_table_name, DBUtils.getDBType(connection)))) + if (!buildingPk || buildingPk == "") { + throw new IllegalArgumentException(building_table_name + " table must have a primary key") + } + + //--------------------------------------------------------------------- + logger.info('Create line of receivers') + + sql.execute("DROP TABLE IF EXISTS tmp_receivers_lines") + + if (fence != null) { + sql.execute("CREATE TABLE tmp_receivers_lines(pk int not null primary key, the_geom geometry) as select " + buildingPk + " as pk, st_simplifypreservetopology(ST_ToMultiLine(ST_Buffer(the_geom, :distance_wall, 'join=bevel')), 0.05) the_geom from " + building_table_name + " WHERE the_geom && :fenceGeom AND ST_INTERSECTS(the_geom, :fenceGeom)", [fenceGeom : fence, distance_wall : distance]) + } else { + sql.execute("CREATE TABLE tmp_receivers_lines(pk int not null primary key, the_geom geometry) as select " + buildingPk + " as pk, st_simplifypreservetopology(ST_ToMultiLine(ST_Buffer(the_geom, :distance_wall, 'join=bevel')), 0.05) the_geom from " + building_table_name, [distance_wall : distance]) + } + sql.execute("CREATE SPATIAL INDEX ON tmp_receivers_lines(the_geom)") + + //--------------------------------------------------------------------- + logger.info('List buildings that will remove receivers (if height is superior than receiver height)') + + sql.execute("DROP TABLE IF EXISTS tmp_relation_screen_building;") + sql.execute("CREATE SPATIAL INDEX ON tmp_receivers_lines(the_geom)") + sql.execute("CREATE TABLE tmp_relation_screen_building as select b." + buildingPk + " as PK_building, s.pk as pk_screen from " + building_table_name + " b, tmp_receivers_lines s where b.the_geom && s.the_geom and s.pk != b." + buildingPk + " and ST_Intersects(b.the_geom, s.the_geom) and b.height > " + h) + sql.execute("CREATE INDEX ON tmp_relation_screen_building(PK_building);") + sql.execute("CREATE INDEX ON tmp_relation_screen_building(pk_screen);") + + //--------------------------------------------------------------------- + logger.info('Truncate receiver lines') + + // First, for each screen, the aggregate geometry of the associated buildings is calculated. + sql.execute("DROP TABLE IF EXISTS tmp_screen_buildings_geom;") + sql.execute("CREATE TABLE tmp_screen_buildings_geom (pk_screen integer not null, the_geom geometry) as select r.pk_screen, ST_ACCUM(b.the_geom) as the_geom FROM tmp_relation_screen_building r JOIN " + building_table_name + " b ON r.PK_building = b." + buildingPk + " GROUP BY r.pk_screen;") + sql.execute("ALTER TABLE tmp_screen_buildings_geom add primary key(pk_screen)") + sql.execute("CREATE INDEX ON tmp_screen_buildings_geom (pk_screen);") + sql.execute("CREATE SPATIAL INDEX ON tmp_screen_buildings_geom (the_geom)") + + // We now apply the buffer and the difference with the geometry of the screens. + sql.execute("DROP TABLE IF EXISTS tmp_screen_truncated;") + sql.execute("CREATE TABLE tmp_screen_truncated (pk_screen integer not null, the_geom geometry) AS SELECT s.pk as pk_screen, ST_DIFFERENCE(s.the_geom, ST_BUFFER(b.the_geom, :distance_wall)) as the_geom FROM tmp_receivers_lines s JOIN tmp_screen_buildings_geom b ON s.pk = b.pk_screen;", [distance_wall : distance]) + + logger.info('Add primary key on tmp_screen_truncated') + sql.execute("ALTER TABLE tmp_screen_truncated add primary key(pk_screen)") + + //--------------------------------------------------------------------- + logger.info('Union of truncated and non truncated receivers') + + sql.execute("DROP TABLE IF EXISTS TMP_SCREENS_MERGE;") + sql.execute("CREATE TABLE TMP_SCREENS_MERGE (pk integer not null, the_geom geometry) as select s.pk, s.the_geom the_geom from tmp_receivers_lines s where not st_isempty(s.the_geom) and pk not in (select pk_screen from tmp_screen_truncated) UNION ALL select pk_screen, the_geom from tmp_screen_truncated where not st_isempty(the_geom);") + + logger.info('Add primary key on TMP_SCREENS_MERGE') + sql.execute("ALTER TABLE TMP_SCREENS_MERGE add primary key(pk)") + + //--------------------------------------------------------------------- + logger.info('Collect all lines and convert into points using custom method') + + sql.execute("DROP TABLE IF EXISTS TMP_SCREENS;") + sql.execute("CREATE TABLE TMP_SCREENS(pk integer, the_geom geometry)") + def qry = 'INSERT INTO TMP_SCREENS(pk , the_geom) VALUES (?,?);' + GeometryFactory factory = new GeometryFactory(new PrecisionModel(), srid); + logger.info('Split line to points') + int nrows = sql.firstRow('SELECT COUNT(*) FROM TMP_SCREENS_MERGE')[0] as Integer + RootProgressVisitor progressLogger = new RootProgressVisitor(nrows, true, 1) + sql.withBatch(100, qry) { ps -> + sql.eachRow("SELECT pk, the_geom from TMP_SCREENS_MERGE") { row -> + List pts = new ArrayList() + def geom = row[1] as Geometry + if (geom instanceof LineString) { + splitLineStringIntoPoints(geom as LineString, delta, pts) + } else if (geom instanceof MultiLineString) { + for (int idgeom = 0; idgeom < geom.numGeometries; idgeom++) { + splitLineStringIntoPoints(geom.getGeometryN(idgeom) as LineString, delta, pts) + } + } + for (int idp = 0; idp < pts.size(); idp++) { + Coordinate pt = pts.get(idp); + if (!Double.isNaN(pt.x) && !Double.isNaN(pt.y)) { + // define coordinates of receivers + Coordinate newCoord = new Coordinate(pt.x, pt.y, h) + ps.addBatch(row[0] as Integer, factory.createPoint(newCoord)) + } + } + progressLogger.endStep() + } + } + sql.execute("DROP TABLE IF EXISTS TMP_SCREENS_MERGE") + sql.execute("DROP TABLE IF EXISTS " + receivers_table_name) + + if (!hasPop) { + logger.info('Create RECEIVERS table...') + + + sql.execute("CREATE TABLE " + receivers_table_name + "(pk integer not null AUTO_INCREMENT, the_geom geometry,build_pk integer)") + sql.execute("INSERT INTO " + receivers_table_name + "(the_geom, build_pk) select ST_SetSRID(the_geom," + srid.toInteger() + ") , pk building_pk from TMP_SCREENS;") + logger.info('Add primary key') + sql.execute("ALTER TABLE "+receivers_table_name+" add primary key(pk)") + + if (input['sourcesTableName']) { + // Delete receivers near sources + logger.info('Delete receivers near sources...') + sql.execute("delete from " + receivers_table_name + " g where exists (select 1 from " + sources_table_name + " r where st_expand(g.the_geom, 1, 1) && r.the_geom and st_distance(g.the_geom, r.the_geom) < 1 limit 1);") + } + + if (fence != null) { + // Delete receiver not in fence filter + sql.execute("delete from " + receivers_table_name + " g where not ST_INTERSECTS(g.the_geom , :fenceGeom);", [fenceGeom : fence]) + } + } else { + logger.info('Create RECEIVERS table...') + // Building have population attribute + // Set population attribute divided by number of receiver to each receiver + sql.execute("DROP TABLE IF EXISTS tmp_receivers") + sql.execute("CREATE TABLE tmp_receivers(pk integer not null AUTO_INCREMENT, the_geom geometry,build_pk integer not null)") + + sql.execute("INSERT INTO tmp_receivers(the_geom, build_pk) select ST_SetSRID(the_geom," + srid.toInteger() + "), pk building_pk from TMP_SCREENS;") + logger.info('Add primary key') + sql.execute("ALTER TABLE tmp_receivers add primary key(pk)") + + if (input['sourcesTableName']) { + // Delete receivers near sources + logger.info('Delete receivers near sources...') + sql.execute("delete from tmp_receivers g where exists (select 1 from " + sources_table_name + " r where st_expand(g.the_geom, 1) && r.the_geom and st_distance(g.the_geom, r.the_geom) < 1 limit 1);") + } + + if (fence != null) { + // delete receiver not in fence filter + sql.execute("delete from tmp_receivers g where not ST_INTERSECTS(g.the_geom , :fenceGeom);", [fenceGeom : fence]) + } + logger.info('Create index on build_pk') + sql.execute("CREATE INDEX ON tmp_receivers(build_pk)") + + //--------------------------------------------------------------------- + logger.info('Distribute population over receivers') + + sql.execute("DROP TABLE IF EXISTS BUILDINGS_RECEIVERS_POP") + sql.execute("CREATE TABLE BUILDINGS_RECEIVERS_POP(" + buildingPk + " integer primary key, pop float) AS SELECT b." + buildingPk + ", b.pop / COUNT(a.PK)::float FROM tmp_receivers a, " + building_table_name + " b where b." + buildingPk + " = a.build_pk GROUP BY b." + buildingPk) + sql.execute("CREATE TABLE " + receivers_table_name + "(pk integer not null AUTO_INCREMENT, the_geom geometry,build_pk integer, pop float)"); + sql.execute("INSERT INTO "+receivers_table_name+"(the_geom, build_pk, pop) select a.the_geom, a.build_pk, b.pop from tmp_receivers a, BUILDINGS_RECEIVERS_POP b where b." + buildingPk + " = a.build_pk;"); + + logger.info('Add primary key on ' +receivers_table_name) + sql.execute("ALTER TABLE "+receivers_table_name+" add primary key(pk)") + + sql.execute("DROP TABLE IF EXISTS tmp_receivers") + sql.execute("DROP TABLE BUILDINGS_RECEIVERS_POP;") + } + + //--------------------------------------------------------------------- + // Cleaning + sql.execute("DROP TABLE TMP_SCREENS") + sql.execute("DROP TABLE tmp_screen_truncated") + sql.execute("DROP TABLE tmp_relation_screen_building") + sql.execute("DROP TABLE tmp_receivers_lines") + sql.execute("DROP TABLE TMP_SCREEN_BUILDINGS_GEOM;") + + //--------------------------------------------------------------------- + // Process Done + resultString = "Process done. The table of receivers " + receivers_table_name + " has been created !" + + // print to command window + logger.info('Result : ' + resultString) + logger.info('End : Receivers grid around buildings') + + return [result: receivers_table_name] + +} + + +/** + * + * @param geom Geometry + * @param segmentSizeConstraint Maximal distance between points + * @param [out]pts computed points + * @return Fixed distance between points + */ +double splitLineStringIntoPoints(LineString geom, double segmentSizeConstraint, + List pts) { + // If the linear sound source length is inferior than half the distance between the nearest point of the sound + // source and the receiver then it can be modelled as a single point source + double geomLength = geom.getLength(); + if (geomLength < segmentSizeConstraint) { + // Return mid point + Coordinate[] points = geom.getCoordinates(); + double segmentLength = 0; + final double targetSegmentSize = geomLength / 2.0; + for (int i = 0; i < points.length - 1; i++) { + Coordinate a = points[i]; + final Coordinate b = points[i + 1]; + double length = a.distance3D(b) + if(Double.isNaN(length)) { + length = a.distance(b) + } + if (length + segmentLength > targetSegmentSize) { + double segmentLengthFraction = (targetSegmentSize - segmentLength) / length; + Coordinate midPoint = new Coordinate(a.x + segmentLengthFraction * (b.x - a.x), + a.y + segmentLengthFraction * (b.y - a.y), + Double.isNaN(a.z) || Double.isNaN(b.z) ? Double.NaN : a.z + segmentLengthFraction * (b.z - a.z)); + pts.add(midPoint); + break; + } + segmentLength += length; + } + return geom.getLength(); + } else { + double targetSegmentSize = geomLength / Math.ceil(geomLength / segmentSizeConstraint as double); + Coordinate[] points = geom.getCoordinates(); + double segmentLength = 0.0; + + // Mid point of segmented line source + def midPoint = null; + for (int i = 0; i < points.length - 1; i++) { + Coordinate a = points[i]; + final Coordinate b = points[i + 1]; + double length = a.distance3D(b); + if (Double.isNaN(length)) { + length = a.distance(b); + } + while (length + segmentLength > targetSegmentSize) { + //LineSegment segment = new LineSegment(a, b); + double segmentLengthFraction = (targetSegmentSize - segmentLength) / length; + Coordinate splitPoint = new Coordinate(); + splitPoint.x = a.x + segmentLengthFraction * (b.x - a.x); + splitPoint.y = a.y + segmentLengthFraction * (b.y - a.y); + splitPoint.z = a.z + segmentLengthFraction * (b.z - a.z); + if (midPoint == null && length + segmentLength > targetSegmentSize / 2) { + segmentLengthFraction = (targetSegmentSize / 2.0 - segmentLength) / length; + midPoint = new Coordinate(a.x + segmentLengthFraction * (b.x - a.x), + a.y + segmentLengthFraction * (b.y - a.y), + a.z + segmentLengthFraction * (b.z - a.z)); + } + pts.add(midPoint); + a = splitPoint; + length = a.distance3D(b); + if (Double.isNaN(length)) { + length = a.distance(b); + } + segmentLength = 0; + midPoint = null; + } + if (midPoint == null && length + segmentLength > targetSegmentSize / 2) { + double segmentLengthFraction = (targetSegmentSize / 2.0 - segmentLength) / length; + midPoint = new Coordinate(a.x + segmentLengthFraction * (b.x - a.x), + a.y + segmentLengthFraction * (b.y - a.y), + a.z + segmentLengthFraction * (b.z - a.z)); + } + segmentLength += length; + } + if (midPoint != null) { + pts.add(midPoint); + } + return targetSegmentSize; + } +} diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Building_Grid3D.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Building_Grid3D.groovy similarity index 69% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Building_Grid3D.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Building_Grid3D.groovy index 9360da594..417636916 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Building_Grid3D.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Building_Grid3D.groovy @@ -1,7 +1,7 @@ /** * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. * - * This version is developed by the DECIDE team FROM the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). * * * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. @@ -15,13 +15,10 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ +package org.noise_planet.noisemodelling.scripts.Receivers -package org.noise_planet.noisemodelling.wps.Receivers - -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore +import groovy.transform.CompileStatic import org.h2gis.functions.spatial.crs.ST_SetSRID import org.h2gis.functions.spatial.crs.ST_Transform import org.h2gis.utilities.JDBCUtilities @@ -30,9 +27,9 @@ import org.h2gis.utilities.TableLocation import org.h2gis.utilities.dbtypes.DBUtils import org.locationtech.jts.geom.* import org.locationtech.jts.io.WKTReader +import org.noise_planet.noisemodelling.pathfinder.PathFinder import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection title = 'Buildings Grid' @@ -43,7 +40,7 @@ description = '➡️ Generates 3D receivers around the buildings and '
  • "Distance from wall": set the distance between the receivers and the building facades,
  • '+ '
  • "Distance between receivers": set the number of receivers around the buildings.

  • ' + '✅ The output table is called RECEIVERS

    '+ - 'Building grid output' + 'Building grid output' inputs = [ tableBuilding : [ @@ -53,7 +50,7 @@ inputs = [ 'The table must contain:
      ' + '
    • THE_GEOM : the 2D geometry of the building (POLYGON or MULTIPOLYGON)
    • ' + '
    • HEIGHT : the height of the building (in meter) (FLOAT)
    • ' + - '
    • POP : building population to add in the receiver attribute (FLOAT) (Optionnal)
    ', + '
  • POP : building population to add in the receiver attribute (FLOAT) (Optional)
  • ', type : String.class ], fence : [ @@ -79,70 +76,44 @@ inputs = [ title : 'Sources table name', description: 'Keep only receivers that are at least 1 meter from the provided source geometries.

    ' + 'The source geometries table must contain:
      ' + - '
    • THE_GEOM : any geometry type.
    ', + '
  • THE_GEOM : any geometry type
  • ', min : 0, max: 1, type : String.class ], delta : [ name : 'Receivers minimal distance', title : 'Distance between receivers', - description: 'Distance between receivers (in the Cartesian plane - in meters) (FLOAT)

    '+ - '🛠 Default value: 10 ', + description: 'Distance between receivers (in the Cartesian plane - in meters) (FLOAT)', + default : 10, type : Double.class ], heightLevels : [ name : 'Height between levels', title : 'Height between levels', - description: 'Height between each level of receivers (in meters) (FLOAT)

    ' + - '🛠 Default value: 2.5 ', - min : 0, max: 1, + description: 'Height between each level of receivers, in meters (FLOAT)', + default : 2.5, type : Double.class ], distance : [ name : 'Distance', title : 'Distance from wall', - description: 'Distance of receivers from the wall (in meters) (FLOAT)

    ' + - '🛠 Default value: 2 ', - min : 0, max: 1, + description: 'Distance between the receivers and the wall, in metres (FLOAT)', + default : 2, type : Double.class ] ] outputs = [ result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', + name : 'Created table', + title : 'Created table', + description: 'Name of the table containing the results of the computation. Can be used as input for another process.', type : String.class ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - - -def exec(Connection connection, input) { +def exec(Connection connection, Map input) { // output string, the information given back to the user String resultString = null @@ -157,21 +128,12 @@ def exec(Connection connection, input) { String receivers_table_name = "RECEIVERS" - Double delta = 10 - if (input['delta']) { - delta = input['delta'] as Double - } + double delta = input.getOrDefault("delta",10) as Double - Double h = 2.5d - if (input['heightLevels']) { - h = input['heightLevels'] as Double - } - Double distance = 2.0d - if (input['distance']) { - distance = input['distance'] as Double - } + double h = input.getOrDefault("heightLevels",2.5d) as Double + double distance = input.getOrDefault("distance",2.0d) as Double String sources_table_name = "SOURCES" if (input['sourcesTableName']) { @@ -216,7 +178,6 @@ def exec(Connection connection, input) { fenceGeom = GeometryTableUtilities.getEnvelope(connection, TableLocation.parse(input['fenceTableName'] as String), "THE_GEOM") } - def buildingPk = JDBCUtilities.getColumnName(connection, building_table_name, JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(building_table_name, DBUtils.getDBType(connection)))) @@ -251,22 +212,22 @@ def exec(Connection connection, input) { List pts = new ArrayList() def geom = row[1] as Geometry def hBuilding = row[2] as Double - def pk_building = row[3] as Integer + int pk_building = row[3] as Integer if (geom instanceof LineString) { - splitLineStringIntoPoints(geom as LineString, delta, pts) + PathFinder.splitLineStringIntoPoints(geom as LineString, delta, pts) } else if (geom instanceof MultiLineString) { for (int idgeom = 0; idgeom < geom.numGeometries; idgeom++) { - splitLineStringIntoPoints(geom.getGeometryN(idgeom) as LineString, delta, pts) + PathFinder.splitLineStringIntoPoints(geom.getGeometryN(idgeom) as LineString, delta, pts) } } - int nLevels = Math.ceil((hBuilding-1.5)/h) - if (hBuilding>1.5){ - for (int i=0;i 1.5) { + for (int i = 0; i < nLevels; i++) { for (int idp = 0; idp < pts.size(); idp++) { Coordinate pt = pts.get(idp); if (!Double.isNaN(pt.x) && !Double.isNaN(pt.y)) { // define coordinates of receivers - Coordinate newCoord = new Coordinate(pt.x, pt.y, 1.5+i*h) + Coordinate newCoord = new Coordinate(pt.x, pt.y, 1.5 + i * h) ps.addBatch(row[0] as Integer, factory.createPoint(newCoord), i, pk_building) } } @@ -358,91 +319,6 @@ def exec(Connection connection, input) { logger.info('Result : ' + resultString) logger.info('End : 3D Receivers grid around buildings') - // print to WPS Builder - return resultString + return [result: receivers_table_name] } - - -/** - * - * @param geom Geometry - * @param segmentSizeConstraint Maximal distance between points - * @param [out]pts computed points - * @return Fixed distance between points - */ -double splitLineStringIntoPoints(LineString geom, double segmentSizeConstraint, - List pts) { - // If the linear sound source length is inferior than half the distance between the nearest point of the sound - // source and the receiver then it can be modelled as a single point source - double geomLength = geom.getLength(); - if (geomLength < segmentSizeConstraint) { - // Return mid point - Coordinate[] points = geom.getCoordinates(); - double segmentLength = 0; - final double targetSegmentSize = geomLength / 2.0; - for (int i = 0; i < points.length - 1; i++) { - Coordinate a = points[i]; - final Coordinate b = points[i + 1]; - double length = a.distance3D(b); - if (length + segmentLength > targetSegmentSize) { - double segmentLengthFraction = (targetSegmentSize - segmentLength) / length; - Coordinate midPoint = new Coordinate(a.x + segmentLengthFraction * (b.x - a.x), - a.y + segmentLengthFraction * (b.y - a.y), - a.z + segmentLengthFraction * (b.z - a.z)); - pts.add(midPoint); - break; - } - segmentLength += length; - } - return geom.getLength(); - } else { - double targetSegmentSize = geomLength / Math.ceil(geomLength / segmentSizeConstraint); - Coordinate[] points = geom.getCoordinates(); - double segmentLength = 0.0; - - // Mid point of segmented line source - def midPoint = null; - for (int i = 0; i < points.length - 1; i++) { - Coordinate a = points[i]; - final Coordinate b = points[i + 1]; - double length = a.distance3D(b); - if (Double.isNaN(length)) { - length = a.distance(b); - } - while (length + segmentLength > targetSegmentSize) { - //LineSegment segment = new LineSegment(a, b); - double segmentLengthFraction = (targetSegmentSize - segmentLength) / length; - Coordinate splitPoint = new Coordinate(); - splitPoint.x = a.x + segmentLengthFraction * (b.x - a.x); - splitPoint.y = a.y + segmentLengthFraction * (b.y - a.y); - splitPoint.z = a.z + segmentLengthFraction * (b.z - a.z); - if (midPoint == null && length + segmentLength > targetSegmentSize / 2) { - segmentLengthFraction = (targetSegmentSize / 2.0 - segmentLength) / length; - midPoint = new Coordinate(a.x + segmentLengthFraction * (b.x - a.x), - a.y + segmentLengthFraction * (b.y - a.y), - a.z + segmentLengthFraction * (b.z - a.z)); - } - pts.add(midPoint); - a = splitPoint; - length = a.distance3D(b); - if (Double.isNaN(length)) { - length = a.distance(b); - } - segmentLength = 0; - midPoint = null; - } - if (midPoint == null && length + segmentLength > targetSegmentSize / 2) { - double segmentLengthFraction = (targetSegmentSize / 2.0 - segmentLength) / length; - midPoint = new Coordinate(a.x + segmentLengthFraction * (b.x - a.x), - a.y + segmentLengthFraction * (b.y - a.y), - a.z + segmentLengthFraction * (b.z - a.z)); - } - segmentLength += length; - } - if (midPoint != null) { - pts.add(midPoint); - } - return targetSegmentSize; - } -} diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Delaunay_Grid.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Delaunay_Grid.groovy similarity index 73% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Delaunay_Grid.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Delaunay_Grid.groovy index 2d9741d96..f80f7f112 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Delaunay_Grid.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Delaunay_Grid.groovy @@ -16,13 +16,9 @@ * @Contributor Ignacio Soto, Ministry for the Ecological Transition, Spain */ +package org.noise_planet.noisemodelling.scripts.Receivers -package org.noise_planet.noisemodelling.wps.Receivers - -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2.util.geometry.EWKTUtils import org.h2.util.geometry.JTSUtils import org.h2gis.api.EmptyProgressVisitor @@ -38,11 +34,11 @@ import org.h2gis.utilities.wrapper.ConnectionWrapper import org.locationtech.jts.geom.Envelope import org.locationtech.jts.geom.Geometry import org.noise_planet.noisemodelling.jdbc.DelaunayReceiversMaker +import org.noise_planet.noisemodelling.jdbc.utils.DataBaseUtilities import org.noise_planet.noisemodelling.pathfinder.delaunay.LayerDelaunayError import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection import java.util.concurrent.atomic.AtomicInteger @@ -55,7 +51,7 @@ description = '➡️ Computes a ' + 'Delaunay grid output' inputs = [ fenceTableName: [ @@ -65,7 +61,6 @@ inputs = [ min : 0, max: 1, type : String.class ], - tableBuilding : [ name : 'Buildings table name', title : 'Buildings table name', @@ -92,8 +87,14 @@ inputs = [ name : 'Maximum cell size', title : 'Maximum cell size', description: 'Maximum distance used to split the domain into sub-domains (in meters) (FLOAT).

    ' + - 'In a logic of optimization of processing times, it allows to limit the number of objects (buildings, roads, …) stored in memory during the Delaunay triangulation.

    ' + - '🛠 Default value: 600 ', + 'In a logic of optimization of processing times, it allows to limit the number of objects (buildings, roads, …) stored in memory during the Delaunay triangulation', + default : 600, + type : Double.class + ], + skipCellNoSourcesMinimalDistance : [ + name : 'Skip cell no sources minimal distance', + title : 'Skip cell no sources minimal distance', + description: 'If provided, a sub-domain will not be computed if no sources geometries are near x meters from the sub-domain area', min : 0, max: 1, type : Double.class ], @@ -101,102 +102,77 @@ inputs = [ name : 'Road width', title : 'Road width', description: 'Set Road Width (in meters) (FLOAT).

    ' + - 'No receivers closer than road width distance will be created.

    ' + - '🛠 Default value: 2 ', - min : 0, max: 1, + 'No receivers closer than road width distance will be created.
    ' + + '
    You can set 0 m if you don\'t want to insert roads in the output but still want' + + ' to skip cells without sources using the \'Skip cell no sources minimal distance\' parameter', + default : 2, type : Double.class ], - buildingBuffer : [ name : 'Building buffer', title : 'Minimum distance to buildings (m)', - description: 'Do not add receivers closer than this distance to buildings (in meters). ' + - 'Default value: 2', - min : 0, max: 1, + description: 'Do not add receivers closer than this distance to buildings (in meters)', + default : 2, type : Double.class ], - maxArea : [ name : 'Maximum Area', title : 'Maximum Area', description: 'Set Maximum Area (in m2) (FLOAT).

    ' + 'No triangles larger than provided area will be created.
    ' + - 'Smaller area will create more receivers.

    ' + - '🛠 Default value: 2500 ', - min : 0, max: 1, + 'Smaller area will create more receivers', + default : 2500, type : Double.class ], height : [ name : 'Height', title : 'Height', - description: 'Receiver height relative to the ground (in meters) (FLOAT).

    ' + - '🛠 Default value: 4 ', - min : 0, max: 1, + description: 'Receiver height relative to the ground (in meters) (FLOAT)', + default : 4, type : Double.class ], outputTableName : [ name : 'outputTableName', title : 'Name of output table', description: 'Name of the output table.

    ' + - 'Do not write the name of a table that contains a space.

    ' + - '🛠 Default value: RECEIVERS ', - min : 0, max: 1, + 'Do not write the name of a table that contains a space', + default : 'RECEIVERS', type : String.class ], isoSurfaceInBuildings: [ name : 'Create IsoSurfaces over buildings', title : 'Create IsoSurfaces over buildings', - description : 'If enabled, isosurfaces will be visible at the location of buildings

    ' + - '🛠 Default value: false ', - min : 0, max: 1, + description : 'If enabled, isosurfaces will be visible at the location of buildings', + default : false, type : Boolean.class ], fenceNegativeBuffer : [ name : 'Negative buffer', title : 'Negative buffer', description: 'Reduce the fence(parameter, or sound sources and buildings extent)' + - ' used to generate receivers positions. You should set here the maximum propagation distance (in meters) (FLOAT).

    ' + - '🛠 Default value: 0 ', - min : 0, max: 1, + ' used to generate receivers positions. You should set here the maximum propagation distance (in meters) (FLOAT)', + default : 0, type : Double.class - ] + ], + exportTrianglesGeometries: [ + name : 'In the triangles table, export triangles geometries', + title : 'In the triangles table, export triangles geometries', + description : 'If enabled, the TRIANGLES table will contain the geometry of each triangle', + default : false, + type : Boolean.class + ], ] outputs = [ result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', + name : 'Created table', + title : 'Created table', + description: 'Name of the table containing the results of the computation. Can be used as input for another process.', type : String.class ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - - // Create a spatial index if it does not exist yet on table(geomCol) def ensureSpatialIndex(Connection connection, String table) { def geomCol = GeometryTableUtilities.getFirstGeometryColumnNameAndIndex(connection, table).first() @@ -205,12 +181,7 @@ def ensureSpatialIndex(Connection connection, String table) { } } -def exec(Connection connection, input) { - - DBTypes dbType = DBUtils.getDBType(connection) - - // output string, the information given back to the user - String resultString = null +def exec(Connection connection, Map input) { // Create a logger to display messages in the geoserver logs and in the command prompt. Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") @@ -250,34 +221,45 @@ def exec(Connection connection, input) { maxCellDist = input['maxCellDist'] as Double } - Double height = 4.0 - if (input['height']) { - height = input['height'] as Double - } + double height = input.getOrDefault("height",4.0) as Double - Double roadWidth = 2.0 - if (input['roadWidth']) { - roadWidth = input['roadWidth'] as Double - } + + double roadWidth = input.getOrDefault("roadWidth",2.0) as Double // Receiver-to-building minimum distance (meters). // New parameter: prevents adding receivers too close to building footprints. // Default: 2.0 m. - Double buildingBuffer = 2.0 - if (input['buildingBuffer']) { - buildingBuffer = input['buildingBuffer'] as Double - } + double buildingBuffer = input.getOrDefault("buildingBuffer",2.0) as Double + Double maxArea = 2500 if (input.containsKey('maxArea')) { maxArea = input['maxArea'] as Double } + boolean exportTriangles = false + if(input.containsKey('exportTrianglesGeometries')) { + exportTriangles = input['exportTrianglesGeometries'] as Boolean + } + + boolean skipCellNoSources = false + double skipCellNoSourcesMinimalDistance = input.getOrDefault("skipCellNoSourcesMinimalDistance",0.0) as Double + if(skipCellNoSourcesMinimalDistance > 0.0) { + skipCellNoSources = true + } + int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(building_table_name)) if (srid == 0) { srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(sources_table_name)) } + if (!DataBaseUtilities.isSridMetric(connection, srid)) { + throw new IllegalArgumentException("Error : Please use a metric projection for your tables. (SRID " + srid + " is not metric)") + } + if (srid == 0) { + throw new IllegalArgumentException("Error : The table does not have an associated SRID.") + } + Geometry fence = null if (input['fence']) { if(input['fence'] instanceof Geometry) { @@ -313,6 +295,12 @@ def exec(Connection connection, input) { // Generate receivers grid for noise map rendering DelaunayReceiversMaker delaunayReceiversMaker = new DelaunayReceiversMaker(building_table_name, sources_table_name) + if(skipCellNoSources) { + delaunayReceiversMaker.setMinimalSourceGeometriesDistanceToComputeCell(skipCellNoSourcesMinimalDistance) + } + + delaunayReceiversMaker.setExportTrianglesGeometries(exportTriangles) + if (fence != null) { // If the fence must be reprojected into the input srid if (srid != 0 && fence.getSRID() != srid) { @@ -341,59 +329,59 @@ def exec(Connection connection, input) { // Allow isosurfaces to be present over buildings if requested. delaunayReceiversMaker.setIsoSurfaceInBuildings(isoSurfaceInBuildings) - logger.info("Delaunay initialize") - delaunayReceiversMaker.initialize(connection, new EmptyProgressVisitor()) - // Apply negative envelope parameter - if (input.containsKey('fenceNegativeBuffer')) { - double negativeBuffer = input['fenceNegativeBuffer'] as Double - if(negativeBuffer > 0) { - Envelope envelope = delaunayReceiversMaker.getMainEnvelope() - envelope.expandBy(-negativeBuffer) - delaunayReceiversMaker.setMainEnvelope(envelope) + double negativeBuffer = input.getOrDefault("fenceNegativeBuffer",0.0) as Double + if(negativeBuffer > 0) { + Envelope envelope; + if(fence != null) { + envelope = fence.getEnvelopeInternal() + } else { + envelope = delaunayReceiversMaker.getComputationEnvelope(connection); } + envelope.expandBy(-negativeBuffer) + delaunayReceiversMaker.setMainEnvelope(envelope) } + if(input['errorDumpFolder']) { // Will write the input mesh in this folder in order to // help debugging delaunay triangulation delaunayReceiversMaker.setExceptionDumpFolder(input['errorDumpFolder'] as String) } - AtomicInteger pk = new AtomicInteger(0) - ProgressVisitor progressVisitorNM = progressLogger.subProcess(delaunayReceiversMaker.getGridDim() * delaunayReceiversMaker.getGridDim()) - + long startTime = System.currentTimeMillis() try { - for (int i = 0; i < delaunayReceiversMaker.getGridDim(); i++) { - for (int j = 0; j < delaunayReceiversMaker.getGridDim(); j++) { - logger.info("Compute cell " + (i * delaunayReceiversMaker.getGridDim() + j + 1) + " of " + delaunayReceiversMaker.getGridDim() * delaunayReceiversMaker.getGridDim()) - delaunayReceiversMaker.generateReceivers(connection, i, j, receivers_table_name, "TRIANGLES", pk) - progressVisitorNM.endStep() - } - } + delaunayReceiversMaker.run(connection, receivers_table_name, "TRIANGLES", progressLogger) } catch (LayerDelaunayError ex) { logger.error("Got an error use the errorDumpFolder parameter with a folder path in order to save the " + "input geometries for debugging purpose") throw ex } + logger.info("Generating spatial index on " + receivers_table_name) // Ensure spatial indexes on output tables (if missing) ensureSpatialIndex(connection, receivers_table_name) - ensureSpatialIndex(connection, 'TRIANGLES') + + if(exportTriangles) { + logger.info("Generating spatial index on TRIANGLES") + ensureSpatialIndex(connection, 'TRIANGLES') + } - int nbReceivers = sql.firstRow("SELECT COUNT(*) FROM " + receivers_table_name)[0] as Integer + long processTime = System.currentTimeMillis() - startTime + logger.info("Delaunay grid computed in " + (processTime / 1000) + " seconds.") + + long nbReceivers = delaunayReceiversMaker.getReceiversCount() // Process Done - resultString = "Process done. " + receivers_table_name + " (" + nbReceivers + " receivers) and TRIANGLES tables created." + def resultString = "Delaunay grid created with " + nbReceivers + " receivers in table " + receivers_table_name + + (exportTriangles ? " and triangles in table TRIANGLES" : "" )+ "." + resultString += " Process time: " + (processTime / 1000) + " seconds." // print to command window logger.info('Result : ' + resultString) logger.info('End : Delaunay grid') - // print to WPS Builder - return resultString - + return [result: receivers_table_name] } - diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Random_Grid.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Random_Grid.groovy similarity index 82% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Random_Grid.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Random_Grid.groovy index df4653004..839223e5b 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Random_Grid.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Random_Grid.groovy @@ -15,13 +15,9 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ +package org.noise_planet.noisemodelling.scripts.Receivers -package org.noise_planet.noisemodelling.wps.Receivers - -import geoserver.GeoServer -import geoserver.catalog.Store import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore import org.h2gis.functions.spatial.crs.ST_SetSRID import org.h2gis.functions.spatial.crs.ST_Transform import org.h2gis.utilities.GeometryTableUtilities @@ -32,14 +28,13 @@ import org.locationtech.jts.geom.GeometryFactory import org.locationtech.jts.io.WKTReader import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.Connection title = 'Random Grid' description = '➡️ Computes a random grid of receivers.
    ' + '
    ' + '✅ The output table is called RECEIVERS

    '+ - 'Random grid output' + 'Random grid output' inputs = [ buildingTableName: [ @@ -63,16 +58,15 @@ inputs = [ name : 'Number of receivers', title : 'Number of receivers', description: 'Number of receivers to return

    ' + - '🛠 Default value: 100

    '+ - 'Number of receivers', + 'Number of receivers', + default : 100, type : Integer.class ], height : [ name : 'Height', title: 'Height', - description: 'Height of receivers (in meters) (FLOAT)

    ' + - '🛠 Default value: 4 ', - min : 0, max: 1, + description: 'Height of receivers (in meters) (FLOAT)', + default : 4, type : Double.class ], fence : [ @@ -96,40 +90,15 @@ inputs = [ outputs = [ result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', + name : 'Created table', + title : 'Created table', + description: 'Name of the table containing the results of the computation. Can be used as input for another process.', type : String.class ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - - -def exec(Connection connection, input) { +def exec(Connection connection,Map input) { // output string, the information given back to the user String resultString = null @@ -150,10 +119,7 @@ def exec(Connection connection, input) { nReceivers = input['nReceivers'] as Integer } - Double h = 4.0d - if (input['height']) { - h = input['height'] as Double - } + double h = input.getOrDefault("height",4.0d) as Double String sources_table_name = "SOURCES" if (input['sourcesTableName']) { @@ -235,8 +201,6 @@ def exec(Connection connection, input) { logger.info('Result : ' + resultString) logger.info('End : Random grid') - - // print to WPS Builder - return resultString + return [result: receivers_table_name] } diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Regular_Grid.groovy b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Regular_Grid.groovy similarity index 83% rename from wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Regular_Grid.groovy rename to noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Regular_Grid.groovy index 7dc51f0cc..8b3cc1e7a 100644 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Receivers/Regular_Grid.groovy +++ b/noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts/Receivers/Regular_Grid.groovy @@ -15,12 +15,8 @@ * @Author Nicolas Fortin, Université Gustave Eiffel */ +package org.noise_planet.noisemodelling.scripts.Receivers -package org.noise_planet.noisemodelling.wps.Receivers - -import geoserver.GeoServer -import geoserver.catalog.Store -import org.geotools.jdbc.JDBCDataStore import org.h2gis.functions.spatial.crs.ST_SetSRID import org.h2gis.functions.spatial.crs.ST_Transform import org.h2gis.utilities.GeometryTableUtilities @@ -30,7 +26,6 @@ import org.locationtech.jts.geom.GeometryFactory import org.locationtech.jts.io.WKTReader import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.* import groovy.sql.Sql @@ -42,7 +37,7 @@ description = '➡️ Computes a regular grid of receivers.
    ' + '
  • the BUILDINGS table extent (option by default)
  • ' + '
  • OR a single Geometry "fence" (see "Extent filter" parameter).

  • ' + '✅ The output table is called RECEIVERS

    '+ - 'Regular grid output' + 'Regular grid output' inputs = [ buildingTableName : [ @@ -83,27 +78,23 @@ inputs = [ delta : [ name : 'Offset', title : 'Offset', - description: 'Offset in the Cartesian plane (in meters)

    ' + - '🛠 Default value: 10 ', - min : 0, max : 1, + description: 'Offset in the Cartesian plane (in meters)', + default : 10, type : Double.class ], receiverstablename: [ name : 'receiverstablename', title : 'Name of receivers table', description: 'Name of the output table.

    ' + - 'Do not write the name of a table that contains a space.

    ' + - '🛠 Default value: RECEIVERS ', - min : 0, max: 1, + 'Do not write the name of a table that contains a space', + default : 'RECEIVERS', type : String.class ], height : [ name : 'Height', title : 'Height', - description: 'Height of receivers (in meter) (FLOAT)

    ' + - '🛠 Default value: 4', - min : 0, - max : 1, + description: 'Height of receivers (in meter) (FLOAT)', + default : 4, type : Double.class ], outputTriangleTable : [ @@ -117,38 +108,13 @@ inputs = [ outputs = [ result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', + name : 'Created table', + title : 'Created table', + description: 'Name of the table containing the results of the computation. Can be used as input for another process.', type : String.class ] ] -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - - def exec(connection, Map input) { @@ -166,7 +132,7 @@ def exec(connection, Map input) { Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") // print to command window - logger.info('Start : Random grid') + logger.info('Start : Regular grid') logger.info("inputs {}", input) // log inputs of the run @@ -176,15 +142,9 @@ def exec(connection, Map input) { } receivers_table_name = receivers_table_name.toUpperCase() - Double delta = 10 - if (input['delta']) { - delta = input['delta'] as Double - } + double delta = input.getOrDefault("delta",10.0) as Double - Double h = 4 - if (input['height']) { - h = input['height'] as Double - } + double h = input.getOrDefault("height",4.0) as Double boolean createTriangles = false if(input['outputTriangleTable']) { @@ -269,5 +229,5 @@ def exec(connection, Map input) { " AND A.ID_ROW = C.ID_ROW AND A.ID_COL = C.ID_COL + 1;") } - return [tableNameCreated: "Process done. Table of receivers " + receivers_table_name + " created !"] + return [result: receivers_table_name] } \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/VersionUtils.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/VersionUtils.java new file mode 100644 index 000000000..0db44f7a6 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/VersionUtils.java @@ -0,0 +1,36 @@ +/* + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and + * education, as well as by experts in a professional use. + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE + * provided with this software. + * + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + * + */ +package org.noise_planet.noisemodelling; + +import org.slf4j.LoggerFactory; + +import java.io.InputStream; +import java.util.Properties; + +/** + * Utility class to read version.properties + */ +public class VersionUtils { + public static String getVersion() { + try (InputStream input = VersionUtils.class.getResourceAsStream("version.properties")) { + Properties prop = new Properties(); + if (input == null) { + return "Unknown"; + } + prop.load(input); + return prop.getProperty("project.version"); + } catch (Exception ex) { + LoggerFactory.getLogger(VersionUtils.class).error("Error while reading version.properties", ex); + return "Unknown"; + } + } +} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/autodoc/GenerateFunctionsDocs.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/autodoc/GenerateFunctionsDocs.java new file mode 100644 index 000000000..3326a313a --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/autodoc/GenerateFunctionsDocs.java @@ -0,0 +1,507 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, + * as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE + * provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + +package org.noise_planet.noisemodelling.autodoc; + +import org.noise_planet.noisemodelling.webserver.script.ScriptInput; +import org.noise_planet.noisemodelling.webserver.script.ScriptMetadata; +import org.noise_planet.noisemodelling.webserver.script.ScriptOutput; +import org.noise_planet.noisemodelling.webserver.script.WpsScriptWrapper; +import org.noise_planet.noisemodelling.webserver.utilities.Logging; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static org.locationtech.jts.io.WKBWriter.toHex; + +/** + * Parses Groovy WPS scripts and generates RST documentation files for each script, + * as well as the main Functions.rst index. + *

    + * Bound to the Maven {@code package} phase via the exec-maven-plugin in + * noisemodelling-scripts/pom.xml. + */ +public class GenerateFunctionsDocs { + + private static final Logger LOGGER = LoggerFactory.getLogger(GenerateFunctionsDocs.class); + + private static final String AUTO_GENERATED_HEADER = + ".. DO NOT UPDATE THIS FILE!!\n" + + ".. This document has been automatically generated with " + + "noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/GenerateFunctionsDocs.java\n\n"; + + // Compiled patterns — reused across all calls + private static final Pattern IMG_TAG_PATTERN = Pattern.compile("]*)>", Pattern.CASE_INSENSITIVE); + private static final Pattern WPS_IMAGE_SRC_PATTERN = Pattern.compile("src=\"wps_images/([^\"]+)\"", Pattern.CASE_INSENSITIVE); + private static final Pattern IMG_ALT_PATTERN = Pattern.compile("alt=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE); + private static final Pattern HEX_ENTITY_PATTERN = Pattern.compile("&#x([0-9a-fA-F]+);"); + private static final Pattern DEC_ENTITY_PATTERN = Pattern.compile("&#([0-9]+);"); + private static final Pattern DEFAULT_VALUE_PATTERN = Pattern.compile("(?i)Default value\\s*:[^\n<]*"); + + // ------------------------------------------------------------------------- + // Entry point + // ------------------------------------------------------------------------- + + /** + * @param args args[0] = path to Docs directory (default: "../Docs"), + * args[1] = path to groovy scripts root directory + * (default: "src/main/groovy/org/noise_planet/noisemodelling/scripts") + */ + public static void main(String[] args) throws IOException, NoSuchAlgorithmException { + + Logging.initConsoleLogging(); + + String docsDir = "../Docs"; + String scriptsDir = "src/main/groovy/org/noise_planet/noisemodelling/scripts"; + if (args.length > 0) { + docsDir = args[0]; + } + if (args.length > 1) { + scriptsDir = args[1]; + } + + File docsDirFile = new File(docsDir).getCanonicalFile(); + File scriptsDirFile = new File(scriptsDir).getAbsoluteFile(); + + if (!docsDirFile.exists()) { + LOGGER.error("Docs directory does not exist: {}", docsDirFile); + return; + } + if (!scriptsDirFile.exists()) { + LOGGER.error("Scripts directory does not exist: {}", scriptsDirFile); + return; + } + + // Derive wps_images source directory (resources sibling of the groovy source tree) + File wpsImagesDir = new File("src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images"); + if (!wpsImagesDir.exists()) { + LOGGER.warn("wps_images directory not found at {}, images will not be copied", wpsImagesDir); + wpsImagesDir = null; + } + + // Discover and parse all scripts using GroovyShell-based ScriptMetadata + + Map metadataMap = new HashMap<>(); + WpsScriptWrapper.walkUri(metadataMap, LOGGER, scriptsDirFile.toURI(), scriptsDir); + + // Ordered map: category name -> list of script base names (sorted) + Map> categories = new LinkedHashMap<>(); + + File functionsDocDir = new File(docsDirFile, "functions"); + functionsDocDir.mkdirs(); + + for (ScriptMetadata scriptMetadata : metadataMap.values()) { + String categoryName = scriptMetadata.group; + + File categoryDocDir = new File(functionsDocDir, categoryName); + categoryDocDir.mkdirs(); + + // Copy referenced wps_images to the category doc directory so + // RST .. figure:: directives resolve correctly + if (wpsImagesDir != null) { + copyReferencedImages(scriptMetadata, wpsImagesDir, categoryDocDir); + } + String scriptFileName = new File(scriptMetadata.path).getName(); + String scriptBaseName = scriptFileName.substring(0, scriptFileName.length() - ".groovy".length()); + String rstContent = generateFunctionRst(scriptBaseName, scriptMetadata); + File rstFile = new File(categoryDocDir, scriptBaseName + ".rst"); + + categories.merge(categoryName, new ArrayList<>(List.of(scriptBaseName)), (existing, newOnes) -> { + existing.addAll(newOnes); + existing.sort(String::compareTo); + return existing; + }); + + // Check if content is different before writing to avoid unnecessary file updates (which would trigger Sphinx rebuilds) + if (rstFile.exists()) { + String existingContent = Files.readString(rstFile.toPath(), StandardCharsets.UTF_8); + if (existingContent.equals(rstContent)) { + LOGGER.trace("No changes for {}, skipping write", docsDirFile.toPath().relativize(rstFile.toPath())); + continue; + } + } + try (FileWriter fw = new FileWriter(rstFile, StandardCharsets.UTF_8)) { + fw.write(rstContent); + } + LOGGER.info("Written: {}", rstFile.getAbsolutePath()); + + } + + // Write main Functions.rst + File functionsRst = new File(docsDirFile, "Functions.rst"); + try (FileWriter fw = new FileWriter(functionsRst, StandardCharsets.UTF_8)) { + fw.write(generateFunctionsIndex(categories)); + } + LOGGER.info("Functions index written to {}", functionsRst.getCanonicalPath()); + } + + /** + * Scan all description fields of the given metadata for {@code src="wps_images/..."} references + * and copy the matching images from {@code wpsImagesDir} to {@code targetDir}. + */ + private static void copyReferencedImages(ScriptMetadata metadata, File wpsImagesDir, File targetDir) throws IOException, NoSuchAlgorithmException { + List allDescriptions = new ArrayList<>(); + allDescriptions.add(metadata.description); + for (ScriptInput input : metadata.inputs.values()) { + if (input.description != null) { + allDescriptions.add(input.description); + } + } + for (ScriptOutput output : metadata.outputs.values()) { + if (output.description != null) { + allDescriptions.add(output.description); + } + } + + for (String desc : allDescriptions) { + if (desc == null || desc.isEmpty()) { + continue; + } + Matcher m = WPS_IMAGE_SRC_PATTERN.matcher(desc); + while (m.find()) { + String imgName = m.group(1); + File imgSrc = new File(wpsImagesDir, imgName); + File imgDst = new File(targetDir, imgName); + if (imgSrc.exists()) { + // Check if destination file already exists with the same content to avoid unnecessary writes + if (imgDst.exists()) { + // Using sha256 hash comparison to avoid loading entire files into memory for large images + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + String srcHash = toHex(digest.digest(Files.readAllBytes(imgSrc.toPath()))); + String dstHash = toHex(digest.digest(Files.readAllBytes(imgDst.toPath()))); + boolean sameContent = srcHash.equals(dstHash); + if (sameContent) { + LOGGER.trace("Image {} already exists in {}, skipping copy", imgName, targetDir); + continue; + } + } + Files.copy(imgSrc.toPath(), imgDst.toPath(), StandardCopyOption.REPLACE_EXISTING); + } else { + LOGGER.warn("Image not found in wps_images: {}", imgName); + } + } + } + } + + // ------------------------------------------------------------------------- + // HTML cleaner + // ------------------------------------------------------------------------- + + /** + * Strip HTML tags and decode HTML entities to produce plain RST text. + *

      + *
    • {@code name} tags are stripped; text content is kept as plain text
    • + *
    • {@code } → RST {@code .. figure::} directive
    • + *
    • {@code
      } / {@code
      } / list tags → newlines and {@code *} bullets
    • + *
    + */ + static String cleanHtml(String html) { + if (html == null || html.isEmpty()) return ""; + + String s = html; + + // Step 1: Strip / tags (keep their text content as plain text) + s = s.replaceAll("(?i)", ""); + + // Step 2: Replace block-level tags with newlines / bullets + s = s.replaceAll("(?i)]*>", "\n"); + s = s.replaceAll("(?i)]*/?>", "\n"); + s = s.replaceAll("(?i)", "\n"); + s = s.replaceAll("(?i)]*>", "\n* "); + s = s.replaceAll("(?i)]*>", "\n"); + s = s.replaceAll("(?i)", "\n"); + s = s.replaceAll("(?i)]*>", "\n"); + s = s.replaceAll("(?i)", "\n"); + s = s.replaceAll("(?i)]*>", "\n"); + s = s.replaceAll("(?i)

    ", "\n"); + + // Step 2.5: Convert ALT to RST figure directive. + // The image file must be copied alongside the RST (handled in main()). + Matcher imgM = IMG_TAG_PATTERN.matcher(s); + StringBuilder sbImg = new StringBuilder(); + while (imgM.find()) { + String attrs = imgM.group(1); + Matcher srcM = WPS_IMAGE_SRC_PATTERN.matcher(attrs); + if (srcM.find()) { + String filename = srcM.group(1); + Matcher altM = IMG_ALT_PATTERN.matcher(attrs); + String alt = altM.find() ? altM.group(1) : filename; + String figure = "\n\n.. figure:: " + filename + "\n :align: center\n :alt: " + alt + "\n\n"; + imgM.appendReplacement(sbImg, Matcher.quoteReplacement(figure)); + } else { + imgM.appendReplacement(sbImg, ""); + } + } + imgM.appendTail(sbImg); + s = sbImg.toString(); + + // Step 3: Strip remaining tags + s = s.replaceAll("<[^>]+>", ""); + + // Step 4: Decode named entities + // Use concatenation to prevent editor formatters from corrupting HTML entity strings + String _amp = "&" + "amp;"; + String _lt = "&" + "lt;"; + String _gt = "&" + "gt;"; + String _quot = "&" + "quot;"; + String _apos = "&" + "apos;"; + String _nbsp = "&" + "nbsp;"; + String _le = "&" + "le;"; + String _ge = "&" + "ge;"; + String _deg = "&" + "deg;"; + s = s.replace(_amp, "&"); + s = s.replace(_lt, "<"); + s = s.replace(_gt, ">"); + s = s.replace(_quot, "\""); + s = s.replace(_apos, "'"); + s = s.replace(_nbsp, " "); + s = s.replace(_le, "≤"); + s = s.replace(_ge, "≥"); + s = s.replace(_deg, "°"); + s = decodeNumericEntities(s); + + // Step 5: Remove "Default value: ..." sentences from the description body. + // They will be displayed separately as "Default: ``...``" by appendParameterRst. + s = DEFAULT_VALUE_PATTERN.matcher(s).replaceAll(""); + + // Step 6: Normalize whitespace. + // Strip leading+trailing spaces per line, EXCEPT for RST directive option lines + // (indented lines starting with ':') which must keep their leading spaces. + String[] lines = s.split("\n", -1); + StringBuilder sb = new StringBuilder(); + int consecutiveBlanks = 0; + for (String line : lines) { + String stripped = line.strip(); + if (stripped.isEmpty()) { + consecutiveBlanks++; + if (consecutiveBlanks <= 1) { + sb.append("\n"); + } + } else { + consecutiveBlanks = 0; + // Preserve indentation for RST directive option lines (e.g. " :align: center") + String lineToAppend = (stripped.startsWith(":") && line.startsWith(" ")) + ? line.stripTrailing() + : stripped; + sb.append(lineToAppend).append("\n"); + } + } + return sb.toString().trim(); + } + + /** Decode &#NNNN; (decimal) and &#xHHHH; (hex) numeric HTML entities to Unicode. */ + private static String decodeNumericEntities(String s) { + // Hex entities + Matcher mh = HEX_ENTITY_PATTERN.matcher(s); + StringBuilder sbHex = new StringBuilder(); + while (mh.find()) { + int cp = Integer.parseInt(mh.group(1), 16); + mh.appendReplacement(sbHex, new String(Character.toChars(cp))); + } + mh.appendTail(sbHex); + s = sbHex.toString(); + + // Decimal entities + Matcher md = DEC_ENTITY_PATTERN.matcher(s); + StringBuilder sbDec = new StringBuilder(); + while (md.find()) { + int cp = Integer.parseInt(md.group(1)); + md.appendReplacement(sbDec, new String(Character.toChars(cp))); + } + md.appendTail(sbDec); + return sbDec.toString(); + } + + // ------------------------------------------------------------------------- + // RST generation + // ------------------------------------------------------------------------- + + /** Generate per-function RST content from a {@link ScriptMetadata} instance. */ + static String generateFunctionRst(String scriptName, ScriptMetadata metadata) { + StringBuilder sb = new StringBuilder(); + + sb.append(AUTO_GENERATED_HEADER); + + // Title + String heading = scriptName.replace("_", " "); + sb.append(heading).append("\n"); + sb.append("=".repeat(heading.length())).append("\n\n"); + + // Compute cleaned title once for reuse + String cleanTitle = metadata.title.isEmpty() ? "" : cleanHtml(metadata.title); + + // Script title as subtitle if different + if (!cleanTitle.isEmpty() && !cleanTitle.equalsIgnoreCase(heading)) { + sb.append(cleanTitle).append("\n\n"); + } + + // Overview + if (!metadata.description.isEmpty()) { + String desc = cleanHtml(metadata.description); + // Avoid duplication: if the description starts with the (cleaned) title, remove the prefix + if (!cleanTitle.isEmpty() && desc.startsWith(cleanTitle)) { + desc = desc.substring(cleanTitle.length()).stripLeading(); + // Also strip leading punctuation like ". " + if (desc.startsWith(".")) { + desc = desc.substring(1).stripLeading(); + } + } + sb.append("Overview\n"); + sb.append("--------\n\n"); + sb.append(desc).append("\n\n"); + } + + // Split inputs into mandatory (minOccurs > 0) and optional (minOccurs == 0) + List mandatoryInputs = new ArrayList<>(); + List optionalInputs = new ArrayList<>(); + for (ScriptInput input : metadata.inputs.values()) { + if (input.minOccurs == 0) { + optionalInputs.add(input); + } else { + mandatoryInputs.add(input); + } + } + // Sort each group by parameter id for a stable, predictable output + Comparator byId = Comparator.comparing(i -> i.id); + mandatoryInputs.sort(byId); + optionalInputs.sort(byId); + + // Arguments section — only if there are inputs + if (!mandatoryInputs.isEmpty() || !optionalInputs.isEmpty()) { + sb.append("Arguments\n"); + sb.append("---------\n\n"); + + if (!mandatoryInputs.isEmpty()) { + sb.append("Mandatory inputs\n"); + sb.append("~~~~~~~~~~~~~~~~\n\n"); + for (ScriptInput p : mandatoryInputs) { + appendInputRst(sb, p); + } + } + + if (!optionalInputs.isEmpty()) { + sb.append("Optional inputs\n"); + sb.append("~~~~~~~~~~~~~~~\n\n"); + for (ScriptInput p : optionalInputs) { + appendInputRst(sb, p); + } + } + } + + // Output + if (!metadata.outputs.isEmpty()) { + List outputs = new ArrayList<>(metadata.outputs.values()); + outputs.sort(Comparator.comparing(o -> o.id)); + sb.append("Output\n"); + sb.append("------\n\n"); + for (ScriptOutput p : outputs) { + appendOutputRst(sb, p); + } + } + + return sb.toString(); + } + + private static void appendInputRst(StringBuilder sb, ScriptInput p) { + sb.append("``").append(p.id).append("``"); + if (p.title != null && !p.title.isEmpty() && !p.title.equals(p.id)) { + sb.append(" — *").append(p.title).append("*"); + } + sb.append("\n"); + + String desc = cleanHtml(p.description); + if (!desc.isEmpty()) { + for (String line : desc.split("\n", -1)) { + sb.append(" ").append(line).append("\n"); + } + } + + if (p.type != null) { + sb.append("\n Type: ``").append(p.type.getSimpleName()).append("``\n"); + } + if (p.defaultValue != null) { + sb.append("\n Default: ``").append(p.defaultValue).append("``\n"); + } + if (!p.allowedValues.isEmpty()) { + sb.append("\n Allowed values: ``"); + boolean first = true; + for (String v : p.allowedValues) { + if (!first) sb.append("``, ``"); + sb.append(v); + first = false; + } + sb.append("``\n"); + } + sb.append("\n"); + } + + private static void appendOutputRst(StringBuilder sb, ScriptOutput p) { + sb.append("``").append(p.id).append("``"); + if (p.title != null && !p.title.isEmpty() && !p.title.equals(p.id)) { + sb.append(" — *").append(p.title).append("*"); + } + sb.append("\n"); + + String desc = cleanHtml(p.description); + if (!desc.isEmpty()) { + for (String line : desc.split("\n", -1)) { + sb.append(" ").append(line).append("\n"); + } + } + + if (p.type != null) { + sb.append("\n Type: ``").append(p.type.getSimpleName()).append("``\n"); + } + sb.append("\n"); + } + + /** Generate the main Functions.rst index. */ + static String generateFunctionsIndex(Map> categories) { + StringBuilder sb = new StringBuilder(); + + sb.append(AUTO_GENERATED_HEADER); + + sb.append("List of functions\n"); + sb.append("^^^^^^^^^^^^^^^^^\n\n"); + sb.append("Below is a list of all the functions that can be run in NoiseModelling.\n"); + sb.append("These functions, written as ``.groovy`` scripts, are available in the ``/scripts/`` folder.\n\n"); + + for (String category : categories.keySet().stream().sorted().collect(Collectors.toCollection(ArrayList::new))) { + List scripts = categories.get(category); + + // Category header — replace underscores with spaces for readability + String categoryTitle = category.replace("_", " "); + sb.append(categoryTitle).append("\n"); + sb.append("~".repeat(Math.max(categoryTitle.length(), 5))).append("\n\n"); + + sb.append(".. toctree::\n"); + sb.append(" :maxdepth: 1\n\n"); + for (String scriptName : scripts) { + sb.append(" functions/").append(category).append("/").append(scriptName).append("\n"); + } + sb.append("\n"); + } + + return sb.toString(); + } +} \ No newline at end of file diff --git a/noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/GenerateReferenceDeviation.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/autodoc/GenerateReferenceDeviation.java similarity index 90% rename from noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/GenerateReferenceDeviation.java rename to noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/autodoc/GenerateReferenceDeviation.java index d15256267..15955905a 100644 --- a/noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/GenerateReferenceDeviation.java +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/autodoc/GenerateReferenceDeviation.java @@ -7,7 +7,7 @@ * Contact: contact@noise-planet.org */ -package org.noise_planet.nmtutorial01; +package org.noise_planet.noisemodelling.autodoc; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -23,6 +23,7 @@ import org.noise_planet.noisemodelling.propagation.SceneWithAttenuation; import org.noise_planet.noisemodelling.propagation.cnossos.CnossosPath; +import org.noise_planet.noisemodelling.webserver.utilities.Logging; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,24 +46,21 @@ public class GenerateReferenceDeviation { private static final double TEMPERATURE = 10; private static final String CHECKED = "☑"; private static final String UNCHECKED = "□"; - private static final String REPORT_HEADER = "Conformity to ISO 17534-1:2015\n" + - "==============================\n" + - ".. DO NOT UPDATE THIS FILE!!\n" + - ".. This document has been automatically generated with noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/GenerateReferenceDeviation.java\n" + - "\n" + - "\n" + - "Clarifications on the ISO Standard and Identified Issues\n" + - "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + - "\n" + - "It is important to note that the ISO standard provides recommendations rather than regulatory obligations. While it serves as a reference framework, its application is not mandatory from a legal standpoint.\n" + - "\n" + - "During our analysis, we identified several issues within the standard that hinder a complete and reliable comparison. Notably, we observed inconsistencies between 2D and 3D visualizations, preventing us from achieving a coherent assessment. Additionally, discrepancies exist between the geometric description of the scene and the corresponding acoustic response, raising concerns about the accuracy and reliability of the standard’s methodology.\n" + - "\n" + - "Furthermore, with respect to favourable rays, our findings indicate a different implementation of CNOSSOS compared to the approach suggested by the standard. This divergence may have implications for the interpretation and reproducibility of results, necessitating further clarification and alignment.\n" + - "\n" + - "\n" + - "Conformity table\n" + - "^^^^^^^^^^^^^^^^\n"; + private static final String REPORT_HEADER = + "Conformity to ISO 17534-1:2015\n" + + "==============================\n" + + ".. DO NOT UPDATE THIS FILE!!\n" + + ".. This document has been automatically generated with noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/GenerateReferenceDeviation.java\n" + + "\n" + + "Clarifications on the ISO Standard\n" + + "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "\n" + + "It is important to note that the ISO standard provides recommendations\n" + + "rather than regulatory obligations. While it serves as a reference framework,\n" + + "its application is not mandatory from a legal standpoint.\n" + + "\n" + + "Conformity table\n" + + "^^^^^^^^^^^^^^^^\n"; private static final String TABLE_HEADER = ".. list-table::\n" + " :widths: 10 20 20 25 30\n" + @@ -257,8 +255,10 @@ private static void addUTDeviationDetails(CutProfile.PROFILE_TYPE profileType, S * @throws IOException exception */ public static void main(String[] args) throws IOException { + Logging.initConsoleLogging(); + // Read working directory argument - String workingDir = "Docs"; + String workingDir = "../Docs"; if (args.length > 0) { workingDir = args[0]; } diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/autodoc/package-info.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/autodoc/package-info.java new file mode 100644 index 000000000..d581533cc --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/autodoc/package-info.java @@ -0,0 +1,4 @@ +/** + * Provides the classes necessary to generate documentation for the NoiseModelling scripts. + */ +package org.noise_planet.noisemodelling.autodoc; diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/runner/Main.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/runner/Main.java new file mode 100644 index 000000000..b5eb5b053 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/runner/Main.java @@ -0,0 +1,274 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and + * education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE + * provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + +package org.noise_planet.noisemodelling.runner; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.h2gis.utilities.dbtypes.DBTypes; +import org.h2gis.utilities.dbtypes.DBUtils; +import org.noise_planet.noisemodelling.webserver.NoiseModellingServer; +import org.noise_planet.noisemodelling.webserver.database.DatabaseManagement; +import org.noise_planet.noisemodelling.webserver.script.ExecutionPlan; +import org.noise_planet.noisemodelling.webserver.script.Job; +import org.noise_planet.noisemodelling.webserver.script.ScriptMetadata; +import org.noise_planet.noisemodelling.webserver.utilities.FileUtilities; +import org.noise_planet.noisemodelling.webserver.utilities.LibraryInfo; +import org.noise_planet.noisemodelling.webserver.utilities.Logging; +import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; +import org.noise_planet.noisemodelling.webserver.utilities.PgPassUtilities; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.net.URI; +import java.sql.Connection; +import java.sql.SQLException; +import java.text.NumberFormat; +import java.sql.Statement; +import java.util.*; + + +public class Main { + public static final int SECONDS_BETWEEN_PROGRESSION_PRINT = 5; + public static final int DEFAULT_TERMINAL_WIDTH = 240; + + /** + * Logs the collected libraries in a tabular format. + */ + public static void printBuildIdentifiers(Logger logger, List libraries) { + if (libraries.isEmpty()) { + logger.info("No library identifiers found."); + return; + } + + String columnFormat = "%-35.35s %-35.35s %-20.20s %-30.30s"; + StringBuilder sb = new StringBuilder(); + sb.append("Loaded libraries:\n"); + sb.append(String.format(Locale.ROOT, columnFormat, "Name", "Last-Modified", "Version", "Commit")); + sb.append("\n"); + + for (LibraryInfo lib : libraries) { + sb.append(String.format(Locale.ROOT, columnFormat, + lib.getName(), lib.getLastModified(), lib.getVersion(), lib.getCommit())); + sb.append("\n"); + } + + logger.info(sb.toString()); + } + + public static void main(String... args) throws Exception { + // Use internal logging settings + Logging.initConsoleLogging(); + + try { + parseArgsAndRun(args); + } finally { + Logging.clearAppenders(); + } + } + + public static void parseArgsAndRun(String... args) { + // Arguments parser + Options options = new Options(); + Option workingDirOption = new Option("w", "working-dir", true, "Path where the database and output logs will be written. It must be an existing folder with write permissions"); + workingDirOption.setRequired(true); + workingDirOption.setArgName("WORKING_DIR"); + options.addOption(workingDirOption); + Option scriptPathOption = new Option("s", "script", true, "Path and file name of the script"); + scriptPathOption.setRequired(true); + scriptPathOption.setArgName("SCRIPT_PATH"); + options.addOption(scriptPathOption); + Option databaseNameOption = new Option("d", "database-name", true, "Database name (default: h2gisdb)"); + databaseNameOption.setArgName("DATABASE_NAME"); + options.addOption(databaseNameOption); + Option usernameOption = new Option("u", "username", true, "Database username (default: sa)"); + usernameOption.setArgName("USERNAME"); + options.addOption(usernameOption); + Option passwordOption = new Option("p", "password", true, "Database password. If a PostGIS host is specified without a password, the password will be fetched from the .pgpass file if it exists (see https://www.postgresql.org/docs/current/libpq-pgpass.html). (default: sa for H2GIS)"); + passwordOption.setArgName("PASSWORD"); + Option portOption = new Option(null, "port", true, "Database port when connecting to PostGIS database (default: 5432)"); + portOption.setArgName("PORT"); + options.addOption(portOption); + Option databaseHostNameOption = new Option(null, "host", true, "Database host name when connecting to PostGIS database, localhost if it is on your PC. The database and host name can be used to fetch the credential access from the file .pgpass on your system if it exists (see https://www.postgresql.org/docs/current/libpq-pgpass.html).(default: empty to use embedded H2GIS)"); + databaseHostNameOption.setArgName("HOST"); + options.addOption(databaseHostNameOption); + options.addOption(passwordOption); + Option printVersionOption = new Option("v", false, "Print version of all libraries"); + options.addOption(printVersionOption); + Option shutdownOption = new Option("c", "shutdown", false, "Do not shutdown compact the database at the end " + + "of the execution"); + options.addOption(shutdownOption); + Logger logger = LoggerFactory.getLogger("org.noise_planet"); + + // Read parameters + String workingDir = ""; + String scriptPath = ""; + Map customParameters = new HashMap<>(); + // Check if -v option is invoked before parsing using commandLineParser + for (String arg : args) { + if (arg.equals("-v") || arg.equals("--version")) { + List libraryInfoList = FileUtilities.collectLibraryIdentifiers(); + printBuildIdentifiers(logger, libraryInfoList); + return; + } + } + + CommandLineParser commandLineParser = new DefaultParser(); + HelpFormatter helpFormatter = new HelpFormatter(); + helpFormatter.setWidth(DEFAULT_TERMINAL_WIDTH); + helpFormatter.setLeftPadding(2); + helpFormatter.setDescPadding(4); + CommandLine commandLine; + try { + commandLine = commandLineParser.parse(options, args, true); + } catch (ParseException ex) { + logger.info(ex.getMessage()); + helpFormatter.printHelp("ScriptRunner", options, true); + System.exit(1); + return; + } + workingDir = commandLine.getOptionValue(workingDirOption.getOpt()); + scriptPath = commandLine.getOptionValue(scriptPathOption.getOpt()); + boolean shutdown = !commandLine.hasOption(shutdownOption.getOpt()); + + Logging.configureLoggerFromWorkingDirectory(workingDir, NoiseModellingServer.LOGGING_FILE_NAME, false); + try (HikariDataSource ds = createDataSource(commandLine)) { + // Initialize additional loggers + RootProgressVisitor progressVisitor = new RootProgressVisitor(1, true, SECONDS_BETWEEN_PROGRESSION_PRINT); + try { + File parentFolder = new File(scriptPath).getParentFile(); + String group = ""; + if(parentFolder != null) { + group = parentFolder.getName(); + } + ScriptMetadata scriptMetadata = new ScriptMetadata(group, new File(scriptPath).toURI(), + parentFolder == null ? new URI("") : parentFolder.toURI()); + // Create Command line arguments specification using the Input specification of the WPS process + scriptMetadata.inputs.forEach((key, scriptInput) -> { + StringBuilder description = new StringBuilder(scriptInput.description.replaceAll("<[^>]*>", "")); + if(scriptInput.defaultValue != null) { + description.append("\nDefault: ").append(scriptInput.defaultValue).append("\n"); + } + if(!scriptInput.allowedValues.isEmpty()) { + description.append("\nPossible values:\n"); + for(Object allowedValue : scriptInput.allowedValues) { + description.append(" - ").append(allowedValue.toString()).append("\n"); + } + } + Option customOption = new Option(null, key, true, description.toString()); + customOption.setType(scriptInput.type); + if(Boolean.class == scriptInput.type) { + customOption.setArgName("true/false"); + } else { + customOption.setArgName(scriptInput.title); + } + customOption.setRequired(scriptInput.minOccurs > 0); + options.addOption(customOption); + }); + try { + commandLine = commandLineParser.parse(options, args); + // Read the command lines values to feed an input hash map for the groovy WPS + for (Iterator

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE + * provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.runner; + +import net.postgis.jdbc.PGbox2d; +import net.postgis.jdbc.PGbox3d; +import org.h2gis.postgis_jts.ConnectionWrapper; +import org.h2gis.postgis_jts.JtsGeometry; +import org.postgresql.PGConnection; +import org.postgresql.ds.PGSimpleDataSource; + +import java.sql.Connection; +import java.sql.SQLException; + +/** + * Handles JTS objects from PosGIS connection + */ +public class PostGISJTSDataSource extends PGSimpleDataSource { + public PostGISJTSDataSource() { + } + + @Override + public Connection getConnection() throws SQLException { + Connection connection = super.getConnection(); + return configureConnection(connection); + } + + private Connection configureConnection(Connection connection) throws SQLException { + if(connection instanceof PGConnection) { + ((PGConnection) connection).addDataType("geometry", JtsGeometry.class); + ((PGConnection) connection).addDataType("box3d", PGbox3d.class); + ((PGConnection) connection).addDataType("box2d", PGbox2d.class); + } + return new ConnectionWrapper(connection); + } + + @Override + public Connection getConnection(String user, String password) throws SQLException { + Connection connection = super.getConnection(user, password); + return configureConnection(connection); + } +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/Configuration.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/Configuration.java new file mode 100644 index 000000000..f770da488 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/Configuration.java @@ -0,0 +1,379 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + + +package org.noise_planet.noisemodelling.webserver; + +import org.apache.commons.cli.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * Manage webserver configuration + */ +public class Configuration { + public static final int DEFAULT_PORT = 8000; + public static final String DEFAULT_APPLICATION_URL = "noisemodelling"; + public static final String DEFAULT_APPLICATION_PROXY_URL = "http://localhost"; + public static final String NOISE_MODELLING_WEB_SERVER = "NoiseModelling Web Server"; + /** Application context url */ + String applicationRootUrl = DEFAULT_APPLICATION_URL; + /** Proxy url of the application */ + String applicationProxyBaseUrl = DEFAULT_APPLICATION_PROXY_URL; + String scriptPath = "scripts"; + final boolean unsecure; + boolean skipOpenBrowser = false; + String workingDirectory = Path.of(System.getProperty("user.home"), ".noisemodelling").toString(); + // secureBase is the h2 database that store web application critical data + // it is not associated with any noisemodelling data + String secureBaseEncryptionSecret = ""; + String secureBaseAdminUser = "sa"; + String secureBaseAdminPassword = "sa"; + int port = DEFAULT_PORT; + Map customConfiguration = new HashMap(); + + + public Configuration(boolean unsecure) { + this.unsecure = unsecure; + } + + /** + * Creates a Configuration object from command-line arguments (backward compatible entry point). + * Delegates to {@link #createConfigurationFromCommandLine(String[], Options)} using default options. + * + * @param args command-line arguments + * @return Configuration with properties set according to command-line arguments + * @throws IllegalArgumentException if required options are missing or invalid + */ + public static Configuration createConfigurationFromArguments(String[] args) throws IllegalArgumentException { + return createConfigurationFromCommandLine(args, buildOptions()); + } + + /** + * Build the CLI Options definition used for both CLI and JSON parsing. + * Required flags defined here are also enforced when parsing from JSON. + */ + public static Options buildOptions() { + Options options = new Options(); + + Option workingDirOption = new Option("w", "working-dir", true, + "Path were the application have writing rights to store sessions data"); + workingDirOption.setArgName("folder path"); + options.addOption(workingDirOption); + + Option helpOption = new Option("h", "help", false, "Show this help message"); + options.addOption(helpOption); + + Option scriptPathOption = new Option("s", "script", true, "Path and file name of the script"); + scriptPathOption.setArgName("script path"); + options.addOption(scriptPathOption); + + Option unsecureOption = new Option("u", "unsecure", false, "Disable TOTP, visitors can run any process"); + options.addOption(unsecureOption); + + Option secureBaseEncryptionSecret = new Option("e", "encryption-secret", true, + "If provided will encrypt the webserver h2 database with this secret"); + options.addOption(secureBaseEncryptionSecret); + + Option applicationRootUrlOption = new Option("r", "root-url", true, "Custom root URL for the web application (default " + DEFAULT_APPLICATION_URL+ " )"); + options.addOption(applicationRootUrlOption); + + Option portOption = new Option("p", "port", true, "Server http serve port (default " + DEFAULT_PORT+ " )"); + portOption.setType(Integer.class); + options.addOption(portOption); + + Option browserNotOpenOption = new Option("b", "browser-skip", false, "Disable open the browser page on startup"); + options.addOption(browserNotOpenOption); + + Option applicationProxyBaseUrlOption = new Option("l", "proxy-base-url", true, "Custom root URL for the web application (ex: http://myservice.org)"); + options.addOption(applicationProxyBaseUrlOption); + + return options; + } + + /** + * Creates a Configuration object from command-line arguments using the provided Options definition. + * + * @param args command-line arguments + * @param options Apache Commons CLI options definition + * @return Configuration configured from CLI + * @throws IllegalArgumentException if parsing fails + */ + public static Configuration createConfigurationFromCommandLine(String[] args, Options options) + throws IllegalArgumentException { + Logger logger = LoggerFactory.getLogger(Configuration.class.getName()); + + CommandLineParser commandLineParser = new DefaultParser(); + HelpFormatter helpFormatter = HelpFormatter.builder() + .setPrintWriter(new PrintWriter(new LoggerWriter(logger))).get(); + // Check if -h or --help argument is present + if (args.length > 0 && (args[0].equals("-h") || args[0].equals("--help"))) { + helpFormatter.printHelp(NOISE_MODELLING_WEB_SERVER, options); + return null; + } + try { + CommandLine commandLine = commandLineParser.parse(options, args, true); + Configuration config = new Configuration(commandLine.hasOption("u")); + // Map options to fields + if (commandLine.hasOption("s")) { + config.scriptPath = commandLine.getOptionValue("s"); + } + if (commandLine.hasOption("w")) { + config.workingDirectory = commandLine.getOptionValue("w"); + } + if (commandLine.hasOption("e")) { + config.secureBaseEncryptionSecret = commandLine.getOptionValue("e"); + } + if (commandLine.hasOption("r")) { + config.applicationRootUrl = commandLine.getOptionValue("r"); + } + if (commandLine.hasOption("p")) { + config.port = Integer.parseInt(commandLine.getOptionValue("p")); + } + if (commandLine.hasOption("b")) { + config.skipOpenBrowser = true; + } + if(commandLine.hasOption("l")) { + config.applicationProxyBaseUrl = commandLine.getOptionValue("l"); + } + return config; + } catch (ParseException ex) { + helpFormatter.printHelp(NOISE_MODELLING_WEB_SERVER, options); + throw new IllegalArgumentException(ex.getMessage()); + } + } + + /** + * A Writer implementation that redirects output to an SLF4J Logger instance. + * + * This class is useful for redirecting output from a Writer to a logging framework. + * It buffers the output and logs it when the buffer is flushed or closed. + */ + public static class LoggerWriter extends Writer { + + /** + * The SLF4J Logger instance to which output will be redirected. + */ + private final Logger logger; + + /** + * A buffer to store the output before it is logged. + */ + private StringBuilder buffer = new StringBuilder(); + + /** + * Constructs a new LoggerWriter instance that redirects output to the specified Logger. + * + * @param logger the SLF4J Logger instance to which output will be redirected + */ + public LoggerWriter(Logger logger) { + this.logger = logger; + } + + /** + * Writes a portion of an array of characters to the buffer. + * + * @param cbuf the array of characters to write + * @param off the offset from which to start writing + * @param len the number of characters to write + * @throws IOException if an I/O error occurs + */ + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + buffer.append(cbuf, off, len); + } + + /** + * Flushes the buffer and logs its contents to the Logger. + * + * @throws IOException if an I/O error occurs + */ + @Override + public void flush() throws IOException { + if (buffer.length() > 0) { + logger.info(buffer.toString()); + buffer = new StringBuilder(); + } + } + + /** + * Closes the Writer, but does not perform any actual closing operation. + * + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + // do nothing + } + } + + /** + * Returns the application root URL. + * + * @return the application root URL + */ + public String getApplicationRootUrl() { + return applicationRootUrl; + } + + /** + * Sets the application root URL. + * + * @param applicationRootUrl the application root URL to set + */ + public void setApplicationRootUrl(String applicationRootUrl) { + this.applicationRootUrl = applicationRootUrl; + } + + /** + * Returns the script path. + * + * @return the script path + */ + public String getScriptPath() { + return scriptPath; + } + + /** + * Sets the script path. + * + * @param scriptPath the script path to set + */ + public void setScriptPath(String scriptPath) { + this.scriptPath = scriptPath; + } + + /** + * Returns whether the server is in unsecure mode. + * + * @return true if unsecure mode is enabled, false otherwise + */ + public boolean isUnsecure() { + return unsecure; + } + + /** + * Returns the working directory path. + * + * @return the working directory + */ + public String getWorkingDirectory() { + return workingDirectory; + } + + /** + * Sets the working directory path. + * + * @param workingDirectory the working directory to set + */ + public void setWorkingDirectory(String workingDirectory) { + this.workingDirectory = workingDirectory; + } + + /** + * Returns the encryption secret for the secure base. + * + * @return the secure base encryption secret + */ + public String getSecureBaseEncryptionSecret() { + return secureBaseEncryptionSecret; + } + + /** + * Sets the encryption secret for the secure base. + * + * @param secureBaseEncryptionSecret the encryption secret to set + */ + public void setSecureBaseEncryptionSecret(String secureBaseEncryptionSecret) { + this.secureBaseEncryptionSecret = secureBaseEncryptionSecret; + } + + /** + * Returns the secure base admin user. + * + * @return the secure base admin user + */ + public String getSecureBaseAdminUser() { + return secureBaseAdminUser; + } + + /** + * Sets the secure base admin user. + * + * @param secureBaseAdminUser the admin user to set + */ + public void setSecureBaseAdminUser(String secureBaseAdminUser) { + this.secureBaseAdminUser = secureBaseAdminUser; + } + + /** + * Returns the secure base admin password. + * + * @return the secure base admin password + */ + public String getSecureBaseAdminPassword() { + return secureBaseAdminPassword; + } + + /** + * Sets the secure base admin password. + * + * @param secureBaseAdminPassword the admin password to set + */ + public void setSecureBaseAdminPassword(String secureBaseAdminPassword) { + this.secureBaseAdminPassword = secureBaseAdminPassword; + } + + /** + * Returns the custom configuration map. + * + * @return the custom configuration + */ + public Map getCustomConfiguration() { + return customConfiguration; + } + + /** + * Sets the custom configuration map. + * + * @param customConfiguration the custom configuration to set + */ + public void setCustomConfiguration(Map customConfiguration) { + this.customConfiguration = customConfiguration; + } + + /** + * @return Server port + */ + public int getPort() { + return port; + } + + /** + * @return Return the full website url to type in the browser window + */ + public String getWebSiteFullUrl() { + return (Objects.equals(applicationProxyBaseUrl, Configuration.DEFAULT_APPLICATION_PROXY_URL) + ? Configuration.DEFAULT_APPLICATION_PROXY_URL + ":" + port : applicationProxyBaseUrl) + + (applicationRootUrl.isEmpty() ? "" : "/" + applicationRootUrl); + } + + /** + * @param port Server port + */ + public void setPort(int port) { + this.port = port; + } +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/NoiseModellingServer.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/NoiseModellingServer.java new file mode 100644 index 000000000..6f174fbab --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/NoiseModellingServer.java @@ -0,0 +1,367 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + + +package org.noise_planet.noisemodelling.webserver; + +import io.javalin.Javalin; +import io.javalin.http.Context; +import io.javalin.http.Handler; +import io.javalin.http.HttpStatus; +import io.javalin.http.staticfiles.Location; +import io.javalin.rendering.template.JavalinThymeleaf; +import io.javalin.util.JavalinLogger; +import io.javalin.websocket.WsConfig; +import org.apache.log4j.Appender; +import org.noise_planet.noisemodelling.VersionUtils; +import org.noise_planet.noisemodelling.webserver.database.DatabaseManagement; +import org.noise_planet.noisemodelling.webserver.script.ScriptFileWatchedProcess; +import org.noise_planet.noisemodelling.webserver.secure.*; +import org.noise_planet.noisemodelling.webserver.utilities.Logging; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sql.DataSource; +import java.awt.*; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.nio.file.*; +import java.sql.SQLException; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +/** + * {@link NoiseModellingServer} is the main class responsible for initializing and running the NoiseModelling web server. + * It leverages {@link Javalin}(psi_element://io.javalin.Javalin) to serve static content, manage OGC-compliant Web Processing Service (WPS) operations + * through {@link OwsController}(psi_element://org.noise_planet.noisemodelling.webserver.OwsController), and handle user authentication and management + * via {@link UserController}(psi_element://org.noise_planet.noisemodelling.webserver.secure.UserController). + *

    + * The server provides functionalities such as: + *

      + *
    • Serving static web resources for the application interface.
    • + *
    • Exposing OGC WPS endpoints for NoiseModelling computations.
    • + *
    • User registration, login, and access control using JWT.
    • + *
    • Job management, including logging and cancellation.
    • + *
    • Dynamic script reloading by watching for changes in a specified script directory.
    • + *
    + * This class also handles server shutdown procedures and integrates with a database for persistent storage + * and user management. + */ +public class NoiseModellingServer { + public static final String LOGGING_FILE_NAME = "webserver.log"; + protected final Logger logger = LoggerFactory.getLogger(NoiseModellingServer.class); + protected Javalin app; + protected Future scriptWatch; + protected final OwsController owsController; + protected final Configuration configuration; + protected final DataSource serverDataSource; + protected final JWTProvider provider; + protected final UserController userController; + + public NoiseModellingServer(Configuration configuration) throws IOException, SQLException { + this.configuration = configuration; + serverDataSource = DatabaseManagement.createH2DataSource(configuration.workingDirectory, "server", + configuration.secureBaseAdminUser, configuration.secureBaseAdminPassword, + configuration.getSecureBaseEncryptionSecret(), false); + // Initialize server database + DatabaseManagement.initializeServerDatabaseStructure(serverDataSource, configuration); + // Initialize an access right system + provider = JWTProviderFactory.createHMAC512(DatabaseManagement.getJWTSigningKey(serverDataSource)); + userController = new UserController(serverDataSource, provider, configuration); + owsController = new OwsController(serverDataSource, provider, configuration); + } + + public Configuration getConfiguration() { + return configuration; + } + + public DataSource getServerDataSource() { + return serverDataSource; + } + + /** + * Retrieves a user-specific {@link DataSource} instance for database operations. + * The {@code DataSource} is maintained with a connection pool for reuse between transactions. + * + * @param userId the unique identifier of the user for whom the {@code DataSource} is being retrieved. + * @return the {@code DataSource} instance associated with the specified user. + * @throws SQLException if an SQL error occurs while retrieving or creating the {@code DataSource}. + */ + public DataSource getUserDataSource(int userId) throws SQLException { + return owsController.fetchUserDataSource(userId); + } + + /** + * The entry point of the application. This method initializes and starts the server. + * + * @param args command-line arguments passed to the application. Not utilized currently. + */ + public static void main(String[] args) { + // Use internal logging settings + Logging.initConsoleLogging(); + + try { + // Read configuration from command line + Configuration configuration = Configuration.createConfigurationFromArguments(args); + if(configuration == null) { + // Use called with --help or -h argument, just exit after displaying help + System.exit(0); + } + // Initialize additional loggers + Logging.configureLoggerFromWorkingDirectory(configuration.workingDirectory, LOGGING_FILE_NAME, true); + // Create WebServer instance + NoiseModellingServer noiseModellingServer = new NoiseModellingServer(configuration); + noiseModellingServer.startServer(!configuration.skipOpenBrowser); + } catch (Exception e) { + Logger logger = LoggerFactory.getLogger("Main"); + logger.error("Can't start NoiseModelling", e); + } + } + + /** + * @return Returns the Javalin application instance. + */ + public Javalin getJavalinInstance() { + return app; + } + + /** + * Initializes and starts the NoiseModelling server with the specified configuration. + * The server serves static files, provides endpoints for OGC-compliant operations, + * and optionally opens a browser pointing to the server's base URL. + * + * @param openBrowser indicates whether the default web browser should be opened + * pointing to the server's base URL. + * @throws IOException if an I/O error occurs during server initialization or script directory resolution. + */ + public void startServer(boolean openBrowser) throws IOException { + String rootPath = "/" + configuration.applicationRootUrl; + + configureApp(rootPath); + + scriptWatch = startWatcher(Path.of(configuration.scriptPath), owsController); + + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + // Stop watching for script changes + scriptWatch.cancel(true); + app.stop(); + // Close all datasource connections + owsController.closeDataBaseDataSources(); + owsController.shutdown(); + if (serverDataSource instanceof AutoCloseable) { + ((AutoCloseable) serverDataSource).close(); + } + // stop file logger + Logging.clearAppenders(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + })); + + app.start(configuration.port); + + if (openBrowser) { + openBrowser(configuration.getWebSiteFullUrl()); + } + } + + /** + * Configure Javalin routes + * @param rootPath Base url + */ + protected void configureApp(String rootPath) { + JavalinLogger.startupInfo = false; // disable startup info + app = Javalin.create(config -> { + config.router.contextPath = rootPath; + config.router.ignoreTrailingSlashes = false; + config.staticFiles.add(staticFileConfig -> { + staticFileConfig.location = Location.CLASSPATH; + staticFileConfig.hostedPath = "/builder"; + staticFileConfig.directory = "org/noise_planet/noisemodelling/webserver/static/wpsbuilder/"; + staticFileConfig.roles = Set.of(Role.ANYONE); + }); + config.staticFiles.add(staticFileConfig -> { + staticFileConfig.location = Location.CLASSPATH; + staticFileConfig.hostedPath = "/"; + staticFileConfig.directory = "org/noise_planet/noisemodelling/webserver/static/root/"; + staticFileConfig.roles = Set.of(Role.ANYONE); + }); + // Serve documentation if the folder exists + File helpDir = getHelpDirectory(); + if(helpDir != null) { + config.staticFiles.add(staticFileConfig -> { + staticFileConfig.location = Location.EXTERNAL; + staticFileConfig.hostedPath = "/builder/help"; + staticFileConfig.directory = helpDir.getAbsolutePath(); + staticFileConfig.roles = Set.of(Role.ANYONE); + }); + } else { + logger.warn("Documentation folder 'help/' not found, documentation won't be served on the web interface."); + } + config.fileRenderer(new JavalinThymeleaf(ThymeleafConfig.buildTemplateConfiguration())); + }); + + app.get("/builder/", this::handleBuilderIndex, configuration.unsecure ? Role.ANYONE : Role.RUNNER); + app.get("/builder", ctx -> ctx.redirect(ctx.contextPath() + "/builder/"), configuration.unsecure ? Role.ANYONE : Role.RUNNER); + + /* + * A decode handler which captures the value of a JWT from an + * authorization header in the form of "Bearer {jwt}". The handler + * decodes and verifies the JWT then puts the decoded object as + * a context attribute for future handlers to access directly. + */ + Handler decodeHandler = JavalinJWT.createCookieDecodeHandler(provider); + Handler headerDecodeHandler = JavalinJWT.createHeaderDecodeHandler(provider); + + app.before(headerDecodeHandler); + app.before(decodeHandler); + app.beforeMatched(new Auth(provider, serverDataSource, configuration)::handleAccess); + + installWpsRoutes(); + + + installJobsRoutes(); + installUserManagementRoutes(); + installExceptionHandlers(); + } + + /** + * Determines the location of the "help" directory relative to the JAR file and returns it as a File object. + * "Working Directory" issue with macOS App Bundles. When you double-click a .app, + * the working directory is not the folder where the app is located; it's usually the system root (/). + * @return A File object representing the "help" directory if it exists, or null if it does not exist at the expected location. + */ + public File getHelpDirectory() { + // 1. Find where the JAR file is located, jar file is located into lib directory + File contentsDir; + try { + contentsDir = new File(NoiseModellingServer.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParentFile().getParentFile(); + } catch (Exception e) { + // Fallback to current directory if URI fails + contentsDir = new File("."); + } + + // 2. Define the help directory relative to the JAR + File helpDir = new File(contentsDir, "help"); + // 3. Check if the help directory exists + if (helpDir.exists() && helpDir.isDirectory()) { + return helpDir; + } else { + logger.warn("Help directory not found at expected location: {}", helpDir.getAbsolutePath()); + return null; + } + } + + protected void handleBuilderIndex(Context ctx) { + ctx.render("wpsbuilder_index", Map.of("version", "NoiseModelling " + VersionUtils.getVersion())); + } + + /** + * Web Processing Service (WPS) API + */ + protected void installWpsRoutes() { + app.get("/builder/ows", owsController::handleGet, Role.RUNNER); + app.post("/builder/ows", owsController::handleWPSPost, Role.RUNNER); + // Job status using web processing service ExecuteResponseDocument + app.get("/builder/jobs/{job_id}", owsController::handleJobExecuteStatus, Role.RUNNER); + } + + protected void installExceptionHandlers() { + // Exception rendering Handling + app.error(HttpStatus.UNAUTHORIZED, ctx -> { + String message = ctx.attributeMap().getOrDefault("messages", "").toString(); + // redirect the user to the login page + ctx.render("blank", Map.of( + "redirectUrl", ctx.contextPath()+"/login", + "message", message)); + }); + app.error(HttpStatus.NOT_FOUND, ctx -> { + logger.info("404 not found on {}", ctx.req().getRequestURI()); + // redirect the user to the login page + ctx.render("blank", Map.of( + "redirectUrl", ctx.contextPath().isEmpty() ? "/" : ctx.contextPath(), + "message", "This page does not exists, redirecting to home..")); + }); + } + + /** + * Routes for job management and custom WPS Builder operations + */ + protected void installJobsRoutes() { + app.get("/job_logs/{job_id}", owsController::jobLogs, Role.RUNNER); + app.ws("/job_logs_stream/{job_id}", this::manageLogsWebSocket, Role.RUNNER); + app.post("/jobs/delete/{job_id}", owsController::jobDelete, Role.RUNNER); + app.post("/jobs/delete_all", owsController::jobDeleteAll, Role.RUNNER); + app.post("/jobs/cancel/{job_id}", owsController::jobCancel, Role.RUNNER); + app.get("/jobs", owsController::jobList, Role.RUNNER); + app.get("/builder/database/export", owsController::handleDatabaseExport, Role.RUNNER); + app.post("/builder/database/import", owsController::handleDatabaseImport, Role.RUNNER); + } + + protected void installUserManagementRoutes() { + app.get("/", userController::index, Role.ANYONE); + app.get("/login", userController::login, Role.ANYONE); + app.post("/do_login", userController::doLogin, Role.ANYONE); + app.get("/register/{token}", userController::register, Role.ANYONE); + app.post("/do_register/{token}", userController::doRegister, Role.ANYONE); + app.get("/users", userController::users, Role.ADMINISTRATOR); + app.post("/users", userController::users, Role.ADMINISTRATOR); + app.get("/edit_user/{userId}", userController::userEdit, Role.ADMINISTRATOR); + app.post("/edit_user/{userId}", userController::userEdit, Role.ADMINISTRATOR); + app.get("/logout", userController::logout, Role.ANYONE); + app.get("/about", userController::about, Role.ADMINISTRATOR); + app.ws("/memory_stats_stream", this::manageMemoryWebSocket, Role.ADMINISTRATOR); + } + + /** + * Opens the default web browser and navigates to the specified URL. + * + * @param url the URL to be opened in the default web browser. It must be a properly formatted URI. + */ + public void openBrowser(String url) { + try { + if (Desktop.isDesktopSupported()) { + Desktop.getDesktop().browse(new URI(url)); + } + } catch (Exception e) { + logger.error("Unable to open the browser : {}", e.getMessage(), e); + } + } + + /** + * Monitors a specified directory and its subdirectories for changes in files. + * Specifically watches for creation, deletion, and modification events of files with the `.groovy` extension + * and triggers a script reload using the provided OwsController. + * + * @param scriptsDir the root directory to monitor for changes. All subdirectories under this will also be monitored. + * @param owsController the instance responsible for reloading scripts when a `.groovy` file is changed. + * @return a Future representing the asynchronous script reload operation. + */ + protected Future startWatcher(Path scriptsDir, OwsController owsController) { + ExecutorService executor = Executors.newSingleThreadExecutor(); + Callable task = new ScriptFileWatchedProcess(scriptsDir, owsController); + return executor.submit(task); + } + + protected void manageLogsWebSocket(WsConfig ws) { + ws.onConnect(owsController::jobLogsStreamOnConnect); + ws.onClose(owsController::jobLogsStreamOnClose); + } + + protected void manageMemoryWebSocket(WsConfig ws) { + ws.onConnect(userController::memoryStatsStreamOnConnect); + ws.onClose(userController::memoryStatsStreamOnClose); + } +} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/OwsController.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/OwsController.java new file mode 100644 index 000000000..3029c31cc --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/OwsController.java @@ -0,0 +1,1018 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + + +package org.noise_planet.noisemodelling.webserver; + +import io.javalin.http.Context; +import io.javalin.http.HttpStatus; +import io.javalin.http.InternalServerErrorResponse; +import io.javalin.websocket.WsCloseContext; +import io.javalin.websocket.WsConnectContext; +import io.javalin.websocket.WsContext; +import net.opengis.ows11.ExceptionReportType; +import net.opengis.wps10.*; +import org.apache.log4j.*; +import org.apache.log4j.spi.Filter; +import org.apache.log4j.spi.LoggingEvent; +import org.geotools.ows.v1_1.OWS; +import org.geotools.ows.v1_1.OWSConfiguration; +import org.geotools.wps.WPSConfiguration; +import org.geotools.xsd.Encoder; +import org.geotools.xsd.Parser; +import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NonNull; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.io.WKTWriter; +import org.noise_planet.noisemodelling.webserver.database.DatabaseManagement; +import org.noise_planet.noisemodelling.webserver.script.*; +import org.noise_planet.noisemodelling.webserver.secure.JWTProvider; +import org.noise_planet.noisemodelling.webserver.secure.JavalinJWT; +import org.noise_planet.noisemodelling.webserver.secure.User; +import org.noise_planet.noisemodelling.webserver.utilities.Logging; +import org.noise_planet.noisemodelling.webserver.utilities.StringUtilities; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; + +import javax.sql.DataSource; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.parsers.ParserConfigurationException; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Comparator; +import java.util.concurrent.*; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import com.zaxxer.hikari.HikariDataSource; +import java.text.MessageFormat; +import java.text.ParseException; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * The OwsController class handles requests for OGC Web Services (OWS), including + * WPS (Web Processing Service), WFS (Web Feature Service), and WCS (Web Coverage Service). + * It provides functionalities for GET and POST requests, depending on the OWS service and + * operation type. + */ +public class OwsController { + public static final int CORE_POOL_SIZE = 5; + public static final int MAXIMUM_POOL_SIZE = 5; + public static final long KEEP_ALIVE_TIME = 0L; + public static final int MAXIMUM_LINES_TO_FETCH = 1_000; + // After the user cancel the job, the WPS script should detect the progressLogger.isCancel() and terminate + // the computation. However, the script does not respond with this delay, + // NoiseModelling will force shutdown the database then kill the processing thread. + private static final int DEFAULT_ABORT_JOB_DELAY_SECONDS = 60; + private static final int COMPLETED_JOB_CLEANUP_DELAY_SECONDS = 3600; // 1 hour + private static final long MAX_UPLOAD_SIZE = 500L * 1024 * 1024; // 500 MB + private static final int MAX_UPLOAD_TIMEOUT = 10; + private final Logger logger = LoggerFactory.getLogger(OwsController.class); + private final JWTProvider provider; + private Map userDataSources = Collections.synchronizedMap(new HashMap()); + private Map websocketLoggers = Collections.synchronizedMap(new HashMap<>()); + Configuration configuration; + DataSource serverDataSource; + protected final ScheduledExecutorService scheduledExecutorService; + + /** + * Handle threads + */ + final JobExecutorService jobExecutorService = new JobExecutorService(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, + KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS); + + /** + * Collection of {@link ScriptMetadata} objects representing the + * scripts available for the Web Processing Service (WPS). Each script is wrapped + * in a {@link ScriptMetadata}, which encapsulates its metadata, inputs, outputs, + * and logic to facilitate execution. + *

    + * This list serves as a central repository of scripts that can be dynamically + * reloaded and used to process WPS requests. It plays a crucial role in + * handling WPS operations by mapping process identifiers to their corresponding + * Groovy script implementations. + */ + Map wpsScripts; + + /** + * An instance of WpsScriptWrapper used to manage the execution of WPS (Web Processing Service) scripts. + * This wrapper facilitates the interaction between the application and the underlying scripting engine + * to execute processes defined in scripts. It is responsible for script execution and handling inputs + * and outputs for WPS processes. + */ + WpsScriptWrapper wpsScriptWrapper; + + + /** + * Constructs an instance of the OwsController class. This constructor initializes the + * WPS scripts by loading and grouping them using the WpsScriptWrapper utility. The scripts + * are classified based on their directory structure and wrapped into appropriate script + * wrappers for further processing. + * + * @throws IOException if an error occurs while loading or processing the script files. + */ + public OwsController(DataSource serverDataSource, JWTProvider provider, Configuration configuration) throws IOException { + wpsScriptWrapper = new WpsScriptWrapper(Path.of(configuration.scriptPath)); + wpsScripts = WpsScriptWrapper.scanScriptsGrouped(getClass().getClassLoader(), configuration.scriptPath); + this.provider = provider; + this.configuration = configuration; + this.serverDataSource = serverDataSource; + this.scheduledExecutorService = Executors.newScheduledThreadPool(1); + } + + /** + * Reloads the WPS (Web Processing Service) scripts by reloading them from the file system + * and rebuilding the corresponding script wrappers. + * + * @throws IOException if an error occurs while loading or rebuilding the scripts. + */ + public void reloadScripts() throws IOException { + wpsScripts = WpsScriptWrapper.scanScriptsGrouped(getClass().getClassLoader(), configuration.scriptPath); + } + + /** + * Handles GET requests for the OWS (Web Services) endpoint. Based on the "service" query parameter, + * it routes the request to the appropriate WPS, WFS, or WCS service handler. If the service type is unknown, + * responds with HTTP 400 (Bad Request). Handles exceptions and responds with HTTP 500 (Internal Server Error) + * in case of server-side errors. + * + * @param ctx the context of the current HTTP request, providing access to request parameters, + * response handling, and the ability to set content type and status codes + */ + public void handleGet(Context ctx) { + ctx.contentType("text/xml; charset=UTF-8"); + String service = ctx.queryParam("service"); + + try { + if ("WPS".equalsIgnoreCase(service)) { + handleWPSGet(ctx); + } else if ("WFS".equalsIgnoreCase(service)) { + handleWFSGet(ctx); + } else if ("WCS".equalsIgnoreCase(service)) { + handleWCSGet(ctx); + } else { + ctx.status(400).result("Unknown service"); + } + } catch (Exception e) { + logger.error("Error handling OWS GET request", e); + try { + returnExceptionDocument(ctx, e); + } catch (IOException ex) { + logger.error("Error generating error document", ex); + } + } + } + + + public void returnExceptionDocument(Context ctx, Exception ex) throws IOException { + ExceptionReportType report = WpsXmlDocumentGenerator.generateExceptionDocument(ex); + + ProcessFailedType failedType = Wps10Factory.eINSTANCE.createProcessFailedType(); + failedType.setExceptionReport(report); + + Encoder encoder = new Encoder(new OWSConfiguration()); + encoder.setIndenting(true); + encoder.setIndentSize(2); + + // used to throw an exception here + ctx.status(500).result(encoder.encodeAsString(report, OWS.ExceptionReport)); + } + + + + /** + * Handles HTTP GET requests for the WPS (Web Processing Service) by managing + * the "GetCapabilities" and "DescribeProcess" operations. Based on the "request" + * query parameter, this method retrieves WPS capabilities or details of a specific + * process. Responds with appropriate XML content or error messages in case of invalid + * requests or missing parameters. + * + * @param ctx the context of the current HTTP request, providing access to + * query parameters, response handling, and the ability to set + * content type and status codes + */ + protected void handleWPSGet(Context ctx) throws IOException { + String request = ctx.queryParam("request"); + ctx.contentType("text/xml; charset=UTF-8"); + + if ("GetCapabilities".equalsIgnoreCase(request)) { + String xml = WpsXmlDocumentGenerator.generateCapabilitiesXML(wpsScripts); + ctx.result(xml); + } else if ("DescribeProcess".equalsIgnoreCase(request)) { + String identifier = ctx.queryParam("identifier"); + if (identifier == null || identifier.isEmpty()) { + ctx.status(400).result("Missing identifier parameter"); + return; + } + + ScriptMetadata target = wpsScripts.get(identifier); + + if (target != null) { + ctx.result(WpsXmlDocumentGenerator.generateDescribeProcessXML(target)); + } else { + ctx.status(404).result("Process not found: " + identifier + ""); + } + + } else { + ctx.status(400).result("Unknown WPS request: " + request + ""); + } + } + + /** + * Handles WFS (Web Feature Service) GET requests for the OWS (Web Services) endpoint. + * Depending on the value of the "request" query parameter, this method determines the desired operation. + * If the request is "GetCapabilities", the corresponding XML file is read and returned in the response. + * For unknown or unsupported requests, it returns an HTTP 400 (Bad Request) status. + * + * @param ctx the context of the current HTTP request, providing access to query parameters, + * request and response handling, and allowing for status and body configuration + * @throws Exception if an error occurs while reading or responding with the requested resource + */ + protected void handleWFSGet(Context ctx) throws Exception { + String request = ctx.queryParam("request"); + if ("GetCapabilities".equalsIgnoreCase(request)) { + try (InputStream xmlStream = getClass().getResourceAsStream("static/xmlFiles/wfs.xml")){ + if (xmlStream != null) { + ctx.result(xmlStream.readAllBytes()); + } + } + } else { + ctx.status(400).result("Unknown WFS request"); + } + } + + /** + * Handles a Get request for the Web Coverage Service (WCS). The method processes + * the incoming HTTP request by examining the "request" query parameter. If the + * query parameter is "GetCapabilities", it responds with the contents of a WCS + * capabilities XML file. If the request is not recognized, it responds with a + * 400 HTTP status and an error message. + * + * @param ctx the context of the HTTP request, providing access to query parameters, + * response handling, status codes, and other request-related information + * @throws Exception if an I/O error occurs while attempting to read the WCS capabilities + * XML file or while processing the request + */ + protected void handleWCSGet(Context ctx) throws Exception { + String request = ctx.queryParam("request"); + if ("GetCapabilities".equalsIgnoreCase(request)) { + try (InputStream xmlStream = getClass().getResourceAsStream("static/xmlFiles/wcs.xml")) { + if (xmlStream != null) { + ctx.result(xmlStream.readAllBytes()); + } + } + } else { + ctx.status(400).result("Unknown WCS request"); + } + } + + /** + * OGC compliant WPS, Build a ExecuteResponse according to the state of a Job + * @param ctx the context of the current HTTP request, providing access to query parameters, + * request and response handling, and allowing for status and body configuration + */ + public void handleJobExecuteStatus(Context ctx) { + try(Connection connection = serverDataSource.getConnection()) { + User user = ctx.attribute("user"); + int jobId = Integer.parseInt(ctx.pathParam("job_id")); + Map jobData = DatabaseManagement.getJob(connection, jobId); + if(hasUnauthorizedJobAccess(ctx, user, jobData)) { + return; + } + Job job = jobExecutorService.getJob(jobId); + ctx.contentType("text/xml; charset=UTF-8"); + ctx.result(WpsXmlDocumentGenerator.generateExecuteResponseDocument(job, jobData, configuration)); + } catch (SQLException | IOException | ParseException | DatatypeConfigurationException e) { + logger.error(e.getLocalizedMessage(), e); + throw new InternalServerErrorResponse(); + } + } + + /** + * Render job list HTML page + * @param ctx web context + */ + public void jobList(Context ctx) { + try(Connection connection = serverDataSource.getConnection()) { + int userIdFilter = -1; + User user = ctx.attribute("user"); + if(user != null && !user.isAdministrator()) { + userIdFilter = user.getIdentifier(); + } + ctx.render("job_list", Map.of("jobs", DatabaseManagement.getJobs(connection, userIdFilter))); + } catch (SQLException e) { + logger.error(e.getLocalizedMessage(), e); + throw new InternalServerErrorResponse(); + } + } + + + /** + * Parses an InputStream to extract and return an ExecuteType object. + * + * @param inputStream the input stream containing the request to be parsed + * @return an ExecuteType object if parsing is successful and the input corresponds to ExecuteType; + * otherwise, returns null + * @throws IOException if an I/O error occurs during parsing + * @throws ParserConfigurationException if a configuration error occurs while setting up the parser + * @throws SAXException if an error occurs during XML parsing + */ + public static ExecuteType parseExecuteRequest(InputStream inputStream) + throws IOException, ParserConfigurationException, SAXException { + Parser parser = new Parser(new WPSConfiguration()); + Object parsed = parser.parse(inputStream); + if (!(parsed instanceof ExecuteType)) { + return null; + } + return (ExecuteType) parsed; + } + + /** + * Parses the given input stream to extract an ExecuteResponseType object. + * + * @param inputStream the input stream containing the data to be parsed + * @return an ExecuteResponseType instance if parsing is successful and the parsed object + * is of the expected type, otherwise returns null + * @throws IOException if an I/O error occurs while reading the input stream + * @throws ParserConfigurationException if a parser configuration error occurs + * @throws SAXException if an XML parsing error occurs + */ + public static ExecuteResponseType parseExecuteResponse(InputStream inputStream) + throws IOException, ParserConfigurationException, SAXException { + Parser parser = new Parser(new WPSConfiguration()); + Object parsed = parser.parse(inputStream); + if (!(parsed instanceof ExecuteResponseType)) { + return null; + } + return (ExecuteResponseType) parsed; + } + + /** + * Parse the XML of the query to generate the execution plan + * @param wpsXmlBody XML of the query + * @return Execution plan + * @throws IOException if an I/O error occurs while reading the XML + * @throws ParserConfigurationException if a configuration error occurs while parsing the XML + * @throws SAXException if a SAX error occurs while parsing the XML + */ + public static ExecutionPlan generateExecutionPlanFromWPS(InputStream wpsXmlBody, Map wpsScripts) + throws IOException, ParserConfigurationException, SAXException { + ExecuteType execute = parseExecuteRequest(wpsXmlBody); + if(execute == null) { + throw new IOException("Invalid WPS request"); + } + return generateExecutionPlanFroExecuteType(execute, wpsScripts); + } + + public static ExecutionPlan generateExecutionPlanFroExecuteType(ExecuteType execute, Map wpsScripts) + throws IOException, ParserConfigurationException, SAXException { + return extractExecuteQuery(execute, wpsScripts); + } + + /** + * Extracts input data from the provided {@code ExecuteType} object and returns the execution plan. + * It processes the data inputs defined in the {@code ExecuteType} + * object to construct this mapping. + * + * @param execute the {@code ExecuteType} object that contains the data inputs to extract. + * @param wpsScripts the map of WPS scripts to their metadata. + * @return The execution plan requested by the query + */ + public static ExecutionPlan extractExecuteQuery(ExecuteType execute, Map wpsScripts) throws IOException { + String processId = execute.getIdentifier().getValue(); + + // Fetch the script name to execute + ScriptMetadata scriptMetadata = wpsScripts.get(processId); + + if (scriptMetadata == null) { + throw new IOException("Process name not found: " + processId); + } + + DataInputsType1 dataInputs = execute.getDataInputs(); + Map queryInputs = new HashMap<>(); + if (dataInputs != null && dataInputs.getInput() != null) { + // Check and cast provided inputs from the WPS Request + for (Object inputObj : dataInputs.getInput()) { + if (inputObj instanceof InputType) { + InputType input = (InputType) inputObj; + try { + String inputId = input.getIdentifier().getValue(); + if(input.getData() != null && input.getData().getLiteralData() != null) { + // Simple literal data type as input + if (scriptMetadata.inputs.containsKey(inputId)) { + ScriptInput scriptInput = scriptMetadata.inputs.get(inputId); + // found expected input, try to cast to expect type if not null + Class expectedInputType = scriptInput.type; + Object convertedInputValue = ScriptMetadata.castInputUsingExpectedInputType(expectedInputType, input.getData().getLiteralData().getValue()); + queryInputs.put(inputId, convertedInputValue); + } else { + Logger logger = LoggerFactory.getLogger(ExecutionPlan.class); + logger.warn("Input '{}' not found in metadata, ignore this argument", inputId); + } + } else if(input.getReference() != null) { + // Chained Process as input + InputReferenceType reference = input.getReference(); + if(reference.getBody() instanceof ExecuteType) { + ExecutionPlan childExecutionPlan = + extractExecuteQuery((ExecuteType) reference.getBody(), wpsScripts); + queryInputs.put(inputId, childExecutionPlan); + } + } + } catch (Exception ex) { + Logger logger = LoggerFactory.getLogger(ExecutionPlan.class); + logger.info("Warning, ignore input as there was an exception while converting input '{}'", input.getIdentifier().getValue(), ex); + } + } + } + } + // Expected output + return fetchChainedOutputIdentifier(execute, scriptMetadata, queryInputs); + } + + private static @NonNull ExecutionPlan fetchChainedOutputIdentifier(ExecuteType execute, ScriptMetadata scriptMetadata, Map queryInputs) { + String outputIdentifier = ""; + if(execute.getResponseForm() != null) { + OutputDefinitionType outputDefinitionType = execute.getResponseForm().getRawDataOutput(); + if (outputDefinitionType != null) { + String outputIdentifierValue = outputDefinitionType.getIdentifier().getValue(); + if (scriptMetadata.outputs.containsKey(outputIdentifierValue)) { + outputIdentifier = outputIdentifierValue; + } + } + } + ExecutionPlan executionPlan = new ExecutionPlan(queryInputs, scriptMetadata, outputIdentifier); + executionPlan.fillInputsWithDefaultValues(); + return executionPlan; + } + + /** + * Handles an HTTP POST request for a Web Processing Service (WPS) operation. + * This method parses the request body, validates the WPS Execute Request, identifies + * the target script to execute based on its process identifier, and executes the script. + * The result of the script execution is returned as a JSON response. + * Responds with appropriate HTTP status codes for invalid requests, missing scripts, + * and internal server errors. + * + * @param ctx the context of the HTTP request, providing access to the request body, + * response handling, and the ability to set status codes and send JSON responses + */ + public void handleWPSPost(Context ctx) { + try { + int userId = JavalinJWT.getUserIdentifierFromContext(ctx, provider); + + ExecuteType execute = parseExecuteRequest(new ByteArrayInputStream(ctx.bodyAsBytes())); + if(execute == null) { + throw new IOException("Invalid WPS request"); + } + ExecutionPlan executionPlan = generateExecutionPlanFroExecuteType(execute, wpsScripts); + int jobUserId = userId > 0 ? userId : 1; // user may not be logged in + DataSource userDataSource = fetchUserDataSource(jobUserId); + Job job = new Job<>(jobUserId, executionPlan, serverDataSource, + userDataSource , configuration); + Future result = jobExecutorService.submitJob(job); + // Prepare the task to clean up the job after it is completed or failed, + // we delay the cleanup to let the user fetch the job result if needed + // It will release some memory and avoid keeping too many results. The job state will still be saved in the database, + // but the result will be removed from memory. + scheduledExecutorService.schedule(new Runnable() { + @Override + public void run() { + if (result.isDone() || result.isCancelled()) { + jobExecutorService.removeJob(job.getId()); + logger.info("Job with ID {} has been clean-up from the memory after completion or cancellation.", job.getId()); + } else { + // Job is still running we will try again in the same delay + scheduledExecutorService.schedule(this, COMPLETED_JOB_CLEANUP_DELAY_SECONDS, TimeUnit.SECONDS); + } + } + }, COMPLETED_JOB_CLEANUP_DELAY_SECONDS, TimeUnit.SECONDS); + if(execute.getResponseForm() != null && execute.getResponseForm().getRawDataOutput() != null) { + // When a response form of RawDataOutput is requested + // Execute operation response will consist simply of that one complex output in its raw form + // returned directly to the client. + // Synchronous WPS Execution, wait for execution + try { + Object jobResult = result.get(executionPlan.getScriptMetadata().executionTimeoutSeconds, TimeUnit.SECONDS); + processResult(ctx, jobResult); + } catch (TimeoutException e) { + // Long process, timeout as been triggered, provide a response while the processing still run in the background + String url = ctx.contextPath() + "/job_logs/" + job.getId(); + String htmlMessage = String.format("

    The process is still running in the background. You can monitor its progress in the output logs.

    " + + "

    Click here to view the job (id: %d) output logs.

    ", url, job.getId()); + ctx.result(htmlMessage); + } + } else { + // Asynchronous WPS Execution + // We answer without delay + // Request want a standard OGC ExecuteResponse document + Map jobData; + try (Connection connection = serverDataSource.getConnection()) { + jobData = DatabaseManagement.getJob(connection, job.getId()); + } + ctx.contentType("text/xml; charset=UTF-8"); + ctx.result(WpsXmlDocumentGenerator.generateExecuteResponseDocument(job, jobData, configuration)); + } + } catch (Exception e) { + logger.error("Error executing WPS {}", ctx.body(), e); + // If error occurred inside the future, unwrap the ExecutionException + String stackTrace = Logging.formatThrowableAsHtml(e); + String html = MessageFormat.format("
    Error:" + + "
    {0}
    Inputs Data
    {1}
    ", stackTrace, StringUtilities.escapeHtml(ctx.body())); + + ctx.contentType("text/html; charset=UTF-8"); + ctx.result(html); + } + } + + /** + * Format the WPS output for the rendering of the WPS Builder website + * @param context + * @param result + */ + public static void processResult(Context context, Object result) { + if(result instanceof Map && ((Map) result).size() == 1) { + processResult(context, ((Map) result).values().iterator().next()); + } else { + if(result instanceof Geometry) { + // Convert Geometry to WKT then encode it in base64 + WKTWriter wktWriter = new WKTWriter(2); + String wkt = wktWriter.write((Geometry) result); + context.contentType("application/octet-stream"); + context.result(wkt.getBytes()); + } else { + context.result(result != null ? result.toString() : ""); + } + } + } + + /** + * The datasource instance contain the hikari connection pool so we must keep it between transactions + * @param userId User identifier + * @return + * @throws SQLException + */ + public DataSource fetchUserDataSource(int userId) throws SQLException { + DataSource dataSource = userDataSources.get(userId); + if (dataSource == null) { + dataSource = DatabaseManagement.createH2DataSource( + configuration.getWorkingDirectory(), getUserDatabaseName(userId), + "sa", + "sa", + "", + true); + userDataSources.put(userId, dataSource); + } + return dataSource; + } + + @NotNull + public static String getUserDatabaseName(int userId) { + return String.format("user_%03d", userId); + } + + + /** + * Checks if the given user has unauthorized access to the specified job data. + * If the user is not an administrator and the job data's user ID does not match + * the user's identifier, the method renders an "unauthorized access" message and + * redirects the user to the jobs page. + * + * @param ctx the context of the current HTTP request, providing access to request parameters, + * response handling, and other request-related features + * @param user the user requesting access to the job; may be null if no user is authenticated + * @param jobData a map containing job data, including the key "userId" which identifies the + * owner of the job + * @return true if the user has unauthorized access to the job and the method handles it by + * rendering a response; false if the access is authorized + */ + private boolean hasUnauthorizedJobAccess(@NotNull Context ctx, User user, + Map jobData) { + if (user != null && !user.isAdministrator() && Integer.valueOf(user.getIdentifier()) != jobData.get("userId")) { + ctx.render("blank", Map.of( + "redirectUrl", ctx.contextPath() + "/jobs", + "message", "Unauthorized access, this job does not belong to you")); + return true; + } + return false; + } + + /** + * Retrieves and displays the logs of a specific job based on the job ID. + * This method retrieves the job data from the database, checks access permissions, + * and fetches the corresponding log entries, rendering them in the response context. + * + * @param ctx the context of the current request, containing job-related parameters, + * request attributes, and response handling methods. + */ + public void jobLogs(@NotNull Context ctx) { + try (Connection connection = serverDataSource.getConnection()) { + User user = ctx.attribute("user"); + try { + int jobId = Integer.parseInt(ctx.pathParam("job_id")); + Map jobData = DatabaseManagement.getJob(connection, jobId); + if(hasUnauthorizedJobAccess(ctx, user, jobData)) { + return; + } + // Parse the current server logs + // we could store the logs into the database when the job complete or failed, maybe another time. + String lastLines = Logging.getLastLines(new File(configuration.workingDirectory, + NoiseModellingServer.LOGGING_FILE_NAME), MAXIMUM_LINES_TO_FETCH, Job.getThreadName(jobId), new AtomicInteger()); + ctx.render("job_logs", Map.of("jobId", jobId, "rows", lastLines)); + } catch (NumberFormatException ex) { + logger.error("Invalid job id {}", ctx.body(), ex); + ctx.render("blank", Map.of( + "redirectUrl", ctx.contextPath() + "/jobs", + "message", "Wrong job id parameter")); + } + } catch (SQLException | IOException e) { + logger.error(e.getLocalizedMessage(), e); + throw new InternalServerErrorResponse(); + } + } + + /** + * Deletes a job based on the job ID provided in the request context. + * Ensures user authorization before deleting the job and updates the job list + * upon successful deletion. Handles errors for invalid job IDs and database issues. + * + * @param ctx The context of the request containing user information and + * job ID path parameter. + */ + public void jobDelete(@NotNull Context ctx) { + try (Connection connection = serverDataSource.getConnection()) { + User user = ctx.attribute("user"); + try { + int jobId = Integer.parseInt(ctx.pathParam("job_id")); + Map jobData = DatabaseManagement.getJob(connection, jobId); + if(hasUnauthorizedJobAccess(ctx, user, jobData)) { + return; + } + DatabaseManagement.deleteJob(connection, jobId); + jobList(ctx); + } catch (NumberFormatException ex) { + logger.error("Invalid job id {}", ctx.body(), ex); + ctx.render("blank", Map.of( + "redirectUrl", ctx.contextPath() + "/jobs", + "message", "Wrong job id parameter")); + } + } catch (SQLException e) { + logger.error(e.getLocalizedMessage(), e); + throw new InternalServerErrorResponse(); + } + } + + /** + * Deletes a job based on the job ID provided in the request context. + * Ensures user authorization before deleting the job and updates the job list + * upon successful deletion. Handles errors for invalid job IDs and database issues. + * + * @param ctx The context of the request containing user information and + * job ID path parameter. + */ + public void jobDeleteAll(@NotNull Context ctx) { + try (Connection connection = serverDataSource.getConnection()) { + User user = ctx.attribute("user"); + if(user != null) { + try { + DatabaseManagement.deleteAllFinalizedJobs(connection, user.getIdentifier()); + jobList(ctx); + } catch (NumberFormatException ex) { + logger.error("Invalid job id {}", ctx.body(), ex); + ctx.render("blank", + Map.of("redirectUrl", ctx.contextPath() + "/jobs", "message", "Wrong job id parameter")); + } + } + } catch (SQLException e) { + logger.error(e.getLocalizedMessage(), e); + throw new InternalServerErrorResponse(); + } + } + + /** + * Cancels the job specified by the job ID in the request context. + * The method validates user access to the job, retrieves the job data, + * and triggers the cancellation of the job with a default delay. + * + * @param ctx the context of the HTTP request, containing information such as path parameters, + * user attributes, and other relevant data required for the operation + */ + public void jobCancel(@NotNull Context ctx) { + try (Connection connection = serverDataSource.getConnection()) { + User user = ctx.attribute("user"); + try { + int jobId = Integer.parseInt(ctx.pathParam("job_id")); + Map jobData = DatabaseManagement.getJob(connection, jobId); + if(hasUnauthorizedJobAccess(ctx, user, jobData)) { + return; + } + Job job = jobExecutorService.getJob(jobId); + if(!jobExecutorService.cancelJob(jobId)) { + // Can't find the job, set it in error to be able to remove it + DatabaseManagement.setJobState(connection, jobId, JobStates.FAILED.name()); + } + + // After a specified delay, abort the process if it can't handle the progress monitor cancel + scheduledExecutorService.schedule(() -> { + if (job.isRunning() && job.getFuture() != null) { + logger.warn("Aborting job {} after {} seconds.", jobId, DEFAULT_ABORT_JOB_DELAY_SECONDS); + // Release/Close the connections of this datasource + // to avoid corruption of the database + if(userDataSources.get(job.getUserId()) instanceof Closeable) { + try { + DataSource dataSource = userDataSources.get(job.getUserId()); + if (dataSource instanceof Closeable) { + // Execute SHUTDOWN command with timeout + try (Connection conn = dataSource.getConnection(); Statement stmt = + conn.createStatement()) { + stmt.setQueryTimeout(5); // 5 seconds timeout + stmt.execute("SHUTDOWN"); + } catch (SQLException e) { + logger.warn("SHUTDOWN command failed or timed out for user {}", + job.getUserId(), e); + } + } + // Close the datasource + if (userDataSources.get(job.getUserId()) instanceof Closeable) { + ((Closeable) userDataSources.get(job.getUserId())).close(); + } + // Remove the dead datasource from the cache + userDataSources.remove(job.getUserId()); + // Wait 1s + Thread.sleep(1_000); + } catch (IOException | InterruptedException e) { + // Ignore + } + } + job.getFuture().cancel(true); + } + }, DEFAULT_ABORT_JOB_DELAY_SECONDS, TimeUnit.SECONDS); + jobList(ctx); + } catch (NumberFormatException ex) { + logger.error("Invalid job id {}", ctx.body(), ex); + ctx.render("blank", Map.of( + "redirectUrl", ctx.contextPath() + "/jobs", + "message", "Wrong job id parameter")); + } + } catch (SQLException e) { + logger.error(e.getLocalizedMessage(), e); + throw new InternalServerErrorResponse(); + } + } + + /** + * Establishes a WebSocket stream to send logs associated with a specific job to the client upon connection. + * The method retrieves job details, validates user access, and creates a custom log appender that captures logs + * for the specified job thread. Logs are filtered and streamed through the WebSocket connection. + * + * @param ctx the WebSocket connection context that contains the connection details and user session data. + */ + public void jobLogsStreamOnConnect(WsConnectContext ctx) { + try (Connection connection = serverDataSource.getConnection()) { + User user = ctx.attribute("user"); + int jobId = Integer.parseInt(ctx.pathParam("job_id")); + Map jobData = DatabaseManagement.getJob(connection, jobId); + if(hasUnauthorizedJobAccess(ctx.getUpgradeCtx$javalin(), user, jobData)) { + return; + } + logger.info("WebSocket connection established for job {}", jobId); + String threadName = Job.getThreadName(jobId); + + // Create a custom appender that sends logs to WebSocket + WriterAppender wsAppender = getWriterAppender(ctx, jobId); + + websocketLoggers.put(ctx, wsAppender); + + // Filter to only capture logs from this job's thread + wsAppender.addFilter(new Filter() { + @Override + public int decide(LoggingEvent event) { + if (event.getThreadName().equals(threadName)) { + return Filter.ACCEPT; + } + return Filter.DENY; + } + }); + + wsAppender.activateOptions(); + org.apache.log4j.Logger rootLogger = org.apache.log4j.Logger.getRootLogger(); + rootLogger.addAppender(wsAppender); + + } catch (NumberFormatException ex) { + logger.error("Invalid job id in WebSocket connection", ex); + ctx.closeSession(); + } catch (SQLException e) { + logger.error(e.getLocalizedMessage(), e); + ctx.closeSession(); + throw new InternalServerErrorResponse(); + } + } + + /** + * Creates and configures a WriterAppender that sends log messages through a WebSocket connection. + * + * @param ctx the WebSocket context, which contains the session information and allows sending messages + * @param jobId the identifier for the job, used to assign a unique name to the appender + * @return a configured WriterAppender instance that writes log messages to the WebSocket session + */ + @NotNull + private static WriterAppender getWriterAppender(WsConnectContext ctx, int jobId) { + Layout layout = new PatternLayout(Logging.DEFAULT_LOG_FORMAT); + WriterAppender wsAppender = new WriterAppender(); + wsAppender.setLayout(layout); + wsAppender.setWriter(new java.io.Writer() { + @Override + public void write(char[] cbuf, int off, int len) { + String message = new String(cbuf, off, len); + if(ctx.session.isOpen()) { + ctx.send(message); + } + } + + @Override + public void flush() { + } + + @Override + public void close() { + } + }); + wsAppender.setName("WebSocketAppender-" + jobId); + wsAppender.setLayout(layout); + return wsAppender; + } + + /** + * Handles the closure of a job log stream associated with a WebSocket context. + * This method removes the corresponding appender from the logger and cleans up + * the association within the internal tracking map. + * + * @param wsCloseContext the WebSocket close context representing the closed connection + */ + public void jobLogsStreamOnClose(WsCloseContext wsCloseContext) { + WriterAppender appender = websocketLoggers.get(wsCloseContext); + if(appender != null) { + org.apache.log4j.Logger rootLogger = org.apache.log4j.Logger.getRootLogger(); + rootLogger.removeAppender(appender); + websocketLoggers.remove(wsCloseContext); + logger.info("Removed WebSocket appender {} for job logs", wsCloseContext); + } else { + logger.info("Could not find WebSocket appender for job logs"); + } + } + + public void closeDataBaseDataSources() { + userDataSources.forEach((userId, dataSource) -> { + if(dataSource instanceof AutoCloseable) { + try { + ((AutoCloseable) dataSource).close(); + } catch (Exception e) { + logger.error("Error closing database datasource for user {}", userId, e); + } + } + }); + } + + /** + * Handles the export of the user's H2 database as a zip file. + * Uses H2's BACKUP TO command to create a safe binary backup. + * The backup is streamed to the client as application/octet-stream. + * + * @param ctx the Javalin HTTP context + */ + public void handleDatabaseExport(Context ctx) { + Path tempDir = null; + try { + User user = ctx.attribute("user"); + int userId = user.getIdentifier(); + File targetDbFile = UserController.getDatabaseFile(userId, configuration.getWorkingDirectory()); + // Check if the database size is inferior than MAX_UPLOAD_SIZE + long dbSize = Files.size(targetDbFile.toPath()); + if(dbSize > MAX_UPLOAD_SIZE) { + String message = "Database size is too big, max size is " + MAX_UPLOAD_SIZE + " bytes"; + logger.error(message); + ctx.status(HttpStatus.CONTENT_TOO_LARGE).result(message); + return; + } + DataSource dataSource = fetchUserDataSource(userId); + tempDir = Files.createTempDirectory("nm_db_export_"); + File backupFile = tempDir.resolve("database.zip").toFile(); + // Add a timeout for the execution of the dump + try (Connection connection = dataSource.getConnection()) { + Statement st = connection.createStatement(); + st.setQueryTimeout(MAX_UPLOAD_TIMEOUT); + st.execute("BACKUP TO '" + backupFile.getAbsolutePath().replace("'", "''") + "'"); + st.setQueryTimeout(0); + } + byte[] data = Files.readAllBytes(backupFile.toPath()); + ctx.contentType("application/octet-stream"); + ctx.header("Content-Disposition", "attachment; filename=\"database.zip\""); + ctx.result(data); + } catch (Exception e) { + logger.error("Error exporting database", e); + ctx.status(500).result("Error exporting database: " + e.getMessage()); + } finally { + if (tempDir != null) { + try (Stream paths = Files.walk(tempDir)) { + paths.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); + } catch (IOException ignored) { + } + } + } + } + + /** + * Handles the import of an H2 database backup. + * Closes the existing user connection pool, replaces the database file + * with the uploaded backup, and lets the pool reconnect on next access. + * No SQL is executed from the uploaded file — only file replacement. + * + * @param ctx the Javalin HTTP context + */ + public void handleDatabaseImport(Context ctx) { + Path tempDir = null; + try { + User user = ctx.attribute("user"); + int userId = user.getIdentifier(); + var uploadedFile = ctx.uploadedFile("database"); + if (uploadedFile == null) { + ctx.status(400).result("No database file uploaded"); + return; + } + if (uploadedFile.size() > MAX_UPLOAD_SIZE) { + ctx.status(413).result("Upload too large (max 500 MB)"); + return; + } + // Close existing connection pool for this user + DataSource existingDS = userDataSources.remove(userId); + if (existingDS instanceof HikariDataSource) { + ((HikariDataSource) existingDS).close(); + } + // Extract the H2 backup zip to a temp directory and find the .mv.db file + File targetDbFile = UserController.getDatabaseFile(userId, configuration.getWorkingDirectory()); + tempDir = Files.createTempDirectory("nm_db_import_"); + File tempZip = tempDir.resolve("uploaded.zip").toFile(); + // Save uploaded file + try (InputStream is = uploadedFile.content(); + OutputStream os = new FileOutputStream(tempZip)) { + is.transferTo(os); + } + // Extract .mv.db from the H2 backup zip + boolean foundDb = false; + try (ZipInputStream zis = new ZipInputStream(new FileInputStream(tempZip))) { + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + // Zip Slip protection: use only the file name, ignore directory components + String entryName = Path.of(entry.getName()).getFileName().toString(); + if (entryName.endsWith(".mv.db")) { + try (OutputStream os = new FileOutputStream(targetDbFile)) { + zis.transferTo(os); + } + foundDb = true; + break; + } + } + } + if (!foundDb) { + ctx.status(400).result("Invalid database backup: no .mv.db file found in zip"); + return; + } + ctx.result("Database imported successfully"); + } catch (Exception e) { + logger.error("Error importing database", e); + ctx.status(500).result("Error importing database: " + e.getMessage()); + } finally { + if (tempDir != null) { + try (Stream paths = Files.walk(tempDir)) { + paths.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); + } catch (IOException ignored) { + } + } + } + } + + /** + * Shuts down the server by stopping the job executor service. + */ + public void shutdown() { + jobExecutorService.shutdown(); + scheduledExecutorService.shutdown(); + } +} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/ThymeleafConfig.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/ThymeleafConfig.java new file mode 100644 index 000000000..da18f201d --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/ThymeleafConfig.java @@ -0,0 +1,32 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + + +package org.noise_planet.noisemodelling.webserver; + +import org.thymeleaf.TemplateEngine; +import org.thymeleaf.templatemode.TemplateMode; +import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; + +public class ThymeleafConfig { + static TemplateEngine buildTemplateConfiguration() { + TemplateEngine templateEngine = new TemplateEngine(); + ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(ThymeleafConfig.class.getClassLoader()); + // HTML is the default mode + templateResolver.setTemplateMode(TemplateMode.HTML); + // context.serve("myresource.html") will look into this package + templateResolver.setPrefix("/org/noise_planet/noisemodelling/webserver/thymeleaf/"); + templateResolver.setSuffix(".html"); + // Set template cache TTL to 1 hour. If not set, entries would live in cache until expelled by LRU + templateResolver.setCacheTTLMs(3600000L); + templateResolver.setCharacterEncoding("UTF-8"); + templateEngine.addTemplateResolver(templateResolver); + return templateEngine; + } +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/UserController.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/UserController.java new file mode 100644 index 000000000..d0df01dc6 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/UserController.java @@ -0,0 +1,461 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + + +package org.noise_planet.noisemodelling.webserver; + +import com.atlassian.onetime.core.TOTP; +import com.atlassian.onetime.core.TOTPGenerator; +import com.atlassian.onetime.model.EmailAddress; +import com.atlassian.onetime.model.Issuer; +import com.atlassian.onetime.model.TOTPSecret; +import com.atlassian.onetime.service.*; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.WriterException; +import com.google.zxing.client.j2se.MatrixToImageWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; +import io.javalin.http.Context; +import io.javalin.http.InternalServerErrorResponse; +import io.javalin.http.util.NaiveRateLimit; +import io.javalin.websocket.WsCloseContext; +import io.javalin.websocket.WsConnectContext; +import io.javalin.websocket.WsContext; +import org.apache.commons.io.FileUtils; +import org.jetbrains.annotations.NotNull; +import org.noise_planet.noisemodelling.webserver.database.DatabaseManagement; +import org.noise_planet.noisemodelling.webserver.secure.*; +import org.noise_planet.noisemodelling.webserver.utilities.FileUtilities; +import org.noise_planet.noisemodelling.webserver.utilities.LibraryInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.imageio.ImageIO; +import javax.sql.DataSource; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryMXBean; +import java.lang.management.MemoryUsage; +import java.util.stream.Collectors; + +/** + * Handle users management + * Adapted from tutorial material from + * javalin-auth-example + * Do not add SQL queries in this class + */ +public class UserController { + public static final String ROLE_FIELD_PREPEND = "ROLE_"; + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final DataSource serverDataSource; + private final JWTProvider provider; + private final TOTPService totpService; + private final Configuration configuration; + + private final ScheduledExecutorService memoryStatsScheduler = Executors.newScheduledThreadPool(1); + private final Set memoryWebSocketContexts = Collections.synchronizedSet(new HashSet<>()); + + public UserController(DataSource serverDataSource, JWTProvider provider, Configuration configuration) { + this.serverDataSource = serverDataSource; + this.provider = provider; + this.configuration = configuration; + TOTPGenerator totpGenerator = new TOTPGenerator(); + TOTPConfiguration totpConfiguration = new TOTPConfiguration(); + totpService = new DefaultTOTPService(totpGenerator, totpConfiguration + ); + } + + public void login(Context ctx ) { + List messages = readMessagesArg(ctx); + ctx.render("login.html", Map.of("messages", messages)); + } + + public void index(Context ctx ) throws SQLException { + Map data = new HashMap<>(); + // not a restricted area so we do not have access to the user in the attributes + User user = Auth.getUserFromContext(ctx, serverDataSource, provider); + if(user != null) { + data.put("user", user); + } + ctx.render("index.html", data); + } + + public void logout(Context ctx ) { + JavalinJWT.addTokenToCookie(ctx, ""); + // redirect the user to the page + ctx.render("blank", Map.of( + "redirectUrl", ctx.contextPath().isEmpty() ? "/" : ctx.contextPath(), + "message", "Logout successful, you will be redirected to the application")); + } + + public void doLogin(Context ctx ) { + // brute force protection + NaiveRateLimit.requestPerTimeUnit(ctx, 5, TimeUnit.MINUTES); + String totpCode = Optional.ofNullable(ctx.formParam("TOTP_CODE")).orElse(""); + String email = Optional.ofNullable(ctx.formParam("EMAIL")).orElse(""); + + try(Connection connection = serverDataSource.getConnection()) { + String totpSecret = DatabaseManagement.getTotpSecretByUserEmail(connection, email); + if(totpSecret.isEmpty()) { + ctx.attribute("messages", "Invalid email or TOTP code"); + login(ctx); + } else { + TOTPVerificationResult result = totpService.verify(new TOTP(totpCode), + TOTPSecret.Companion.fromBase32EncodedString(totpSecret)); + if (result.isSuccess()) { + // Fetch user + int userId = DatabaseManagement.getUserIdByUserEmail(connection, email); + User user = DatabaseManagement.getUser(connection, userId); + String token = provider.generateToken(user); + // Register the JWT token in cookie + JavalinJWT.addTokenToCookie(ctx, token); + logger.info("User {} has logged into the system", email); + // redirect the user to the page + ctx.render("blank", Map.of( + "redirectUrl", ctx.contextPath().isEmpty() ? "/" : ctx.contextPath(), + "message", "Login successful, you will be redirected to the application")); + } else { + ctx.attribute("messages", "Invalid email or TOTP code"); + logger.info("Visitor with email {} failed to login {}", email, ctx.attribute("messages")); + login(ctx); + } + } + } catch (SQLException e) { + logger.error(e.getLocalizedMessage(), e); + throw new InternalServerErrorResponse(); + } + } + + + /** + * Post method of register page + * @param ctx Context + */ + public void doRegister(Context ctx ) { + String totpCode = ctx.formParam("TOTP_CODE"); + String totpSecret = ctx.formParam("TOTP_SECRET"); + String userToken = ctx.formParam("TOKEN"); + + try(Connection connection = serverDataSource.getConnection()) { + int userIdentifier = DatabaseManagement.getUserByRegisterToken(connection, userToken); + if (totpCode != null && totpSecret != null && userToken != null && userIdentifier >= 0) { + User user = DatabaseManagement.getUser(connection, userIdentifier); + TOTPVerificationResult result = totpService.verify(new TOTP(totpCode), + TOTPSecret.Companion.fromBase32EncodedString(totpSecret)); + if(result.isSuccess()) { + DatabaseManagement.updateUserTotpToken(connection, user.getIdentifier(), totpSecret); + String message = "Account successfully created ! You will be directed to the login page to enter your credentials"; + // redirect the user to the page + ctx.render("blank", Map.of( + "redirectUrl", ctx.contextPath() + "/login", + "message", message)); + } else { + ctx.attribute("messages", "Invalid TOTP code"); + logger.info("User {} failed to register {}", user.getEmail(), ctx.attribute("messages")); + register(ctx); + } + } else { + ctx.attribute("messages", "Invalid register page url, ask your administrator for a new link."); + logger.info("User with token {} failed to register {}", userToken, ctx.attribute("messages")); + register(ctx); + } + } catch (SQLException e) { + logger.error(e.getLocalizedMessage(), e); + throw new InternalServerErrorResponse(); + } + } + + + public static String createQRCodeImage(URI totpUri) throws IOException { + try { + BitMatrix bitMatrix = new QRCodeWriter().encode(totpUri.toString(), BarcodeFormat.QR_CODE, 200, 200); + BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageIO.write(image, "png", baos); + byte[] bytes = baos.toByteArray(); + return Base64.getEncoder().encodeToString(bytes); + } catch (WriterException e) { + throw new IOException(e.getLocalizedMessage(), e); + } + } + + /** + * Format totp secret using block 4 of chars to be more readable for the user + * @param totpSecret totpSecret string (multiple of 4 + * @return formated totpSecret + */ + public static String formatTotpSecret(String totpSecret) { + StringBuilder formatted = new StringBuilder(); + for (int i = 0; i < totpSecret.length(); i += 4) { + formatted.append(totpSecret, i, Math.min(i + 4, totpSecret.length())); + if (i + 4 < totpSecret.length()) { // Don't add space at the end of string + formatted.append(' '); + } + } + return formatted.toString(); + } + + public List readMessagesArg(Context ctx) { + String message = ctx.attributeMap().getOrDefault("messages", "").toString(); + if(message.isEmpty()) { + return Collections.emptyList(); + } else { + return Collections.singletonList(message); + } + } + + /** + * Display register page + * @param ctx Context + */ + public void register(Context ctx) { + // brute force protection + NaiveRateLimit.requestPerTimeUnit(ctx, 5, TimeUnit.MINUTES); + String token = ctx.pathParam("token"); + TOTPSecret totpSecret = RandomSecretProvider.Companion.generateSecret(); + try(Connection connection = serverDataSource.getConnection()) { + int userIdentifier = DatabaseManagement.getUserByRegisterToken(connection, token); + if(userIdentifier >= 0) { + User user = DatabaseManagement.getUser(connection, userIdentifier); + URI totpUri = totpService.generateTOTPUrl( + totpSecret, + new EmailAddress(user.getEmail()), + new Issuer("NoiseModelling")); + String qrCodeBytes = createQRCodeImage(totpUri); + ctx.render("register.html", Map.of( + "messages", readMessagesArg(ctx), + "token", token, + "totpUri", totpUri, + "totpSettings", totpUri, + "totpSecret", formatTotpSecret(totpSecret.getBase32Encoded()), + "qrCodeBytes", qrCodeBytes)); + } else { + ctx.render("login.html", Map.of( + "messages", List.of("Register/Reset token is no longer valid, ask your administrator for a new link."))); + } + } catch (SQLException | IOException e) { + logger.error(e.getLocalizedMessage(), e); + throw new InternalServerErrorResponse(); + } + } + + /** + * Render user list HTML page + * @param ctx web context + */ + public void about(Context ctx) { + List libraries = FileUtilities.collectLibraryIdentifiers(); + // Sort by last modified column + libraries.sort(Comparator.comparingLong(LibraryInfo::getLastModifiedTimeStamp).reversed()); + ctx.render("about", Map.of("libraries", libraries)); + } + + /** + * Render user list HTML page + * @param ctx web context + */ + public void users(Context ctx) { + try(Connection connection = serverDataSource.getConnection()) { + String message = ""; + String email = ctx.formParam("USER_EMAIL"); + if (email != null) { + // Administrator add a new user + Set roles = new HashSet<>(); + for (Role role : Role.values()) { + boolean selected = ctx.formParam(ROLE_FIELD_PREPEND + role.name()) != null; + if (selected) { + roles.add(role); + } + } + try { + DatabaseManagement.addUser(connection, email, roles.toArray(new Role[0])); + message = "User " + email + " successfully added"; + } catch (SQLException e) { + message = "User " + email + " already exists"; + } + } + List> table = new ArrayList<>(); + List users = DatabaseManagement.getUsers(connection); + for(User user : users) { + Map row = new HashMap<>(); + row.put("id", user.getIdentifier()); + row.put("email", user.getEmail()); + long size = 0; + File databaseFile = getDatabaseFile(user); + if(databaseFile.exists()) { + size = databaseFile.length(); + } + row.put("dbSize", FileUtils.byteCountToDisplaySize(size)); + row.put("registerUrl", user.getRegisterUrl(configuration.getWebSiteFullUrl())); + row.put("groups", user.getRoles().stream().map(Enum::name).collect(Collectors.joining(", "))); + table.add(row); + } + Map groups = Map.of(Role.RUNNER.name(), true, + Role.ADMINISTRATOR.name(), false); + ctx.render("users", Map.of("accounts", table, "groups", groups, "message", message)); + } catch (SQLException e) { + logger.error(e.getLocalizedMessage(), e); + throw new InternalServerErrorResponse(); + } + } + + + /** + * Render user edit HTML page + * @param ctx web context + */ + public void userEdit(Context ctx) { + try(Connection connection = serverDataSource.getConnection()) { + List messages = new ArrayList<>(); + int userId = Integer.parseInt(ctx.pathParam("userId")); + User user = DatabaseManagement.getUser(connection, userId); + if(user == null) { + String message = "This user does not exist"; + // redirect the user to the page + ctx.render("blank", Map.of( + "redirectUrl", ctx.contextPath() + "/user_list", + "message", message)); + return; + } + // Read post data + boolean delete = ctx.formParam("DELETE_USER") != null; + boolean deleteDatabase = ctx.formParam("DELETE_DATABASE") != null; + if(delete) { + DatabaseManagement.deleteUser(connection, user.getIdentifier()); + messages.add("User " + user.getEmail() + " successfully deleted"); + logger.info("User {} successfully deleted", user.getEmail()); + } else if(deleteDatabase) { + File databaseFile = getDatabaseFile(user); + FileUtils.deleteQuietly(databaseFile); + messages.add("Database for user " + user.getEmail() + " successfully deleted"); + logger.info("Database for user {} successfully deleted", user.getEmail()); + } else { + String email = ctx.formParam("USER_EMAIL"); + if (email != null) { + // Administrator update the user attributes + Set roles = new HashSet<>(); + for (Role role : Role.values()) { + boolean selected = ctx.formParam(ROLE_FIELD_PREPEND + role.name()) != null; + if (selected) { + roles.add(role); + } + } + if (user.getIdentifier() == 1 && user.isAdministrator()) { + // Avoid removing the administrator role of the first account + roles.add(Role.ADMINISTRATOR); + } + // read RESET_TOTP checkbox value + boolean resetTotp = ctx.formParam("RESET_TOTP") != null; + String token = user.getRegisterToken(); + if (resetTotp) { + token = JWTProviderFactory.generateServerSecretToken(); + } + User updatedUser = new User(user.getIdentifier(), email, roles, token); + DatabaseManagement.updateUserAttributes(connection, updatedUser); + messages.add("User " + email + " successfully updated"); + user = updatedUser; + } + } + // Rendering of the form + Map userFields = new HashMap<>(); + userFields.put("email", user.getEmail()); + Map groups = new HashMap<>(); + Set userRoles = user.getRoles(); + for (Role role : Role.values()) { + if(role.ordinal() > 0) { // skip anyone + groups.put(role.name(), userRoles.contains(role)); + } + } + userFields.put("groups", groups); + userFields.put("messages", messages); + userFields.put("deletable", user.getIdentifier() > 1); + ctx.render("user_edit", userFields); + } catch (SQLException e) { + logger.error(e.getLocalizedMessage(), e); + throw new InternalServerErrorResponse(); + } + } + + /** + * Handles WebSocket connection for memory stats streaming. + * @param ctx the WebSocket connect context + */ + public void memoryStatsStreamOnConnect(WsConnectContext ctx) { + logger.info("WebSocket connection established for memory stats"); + memoryWebSocketContexts.add(ctx); + // Start sending memory stats every second + memoryStatsScheduler.scheduleAtFixedRate(() -> sendMemoryStats(ctx), 0, 1, TimeUnit.SECONDS); + } + + /** + * Handles WebSocket disconnection for memory stats streaming. + * @param wsCloseContext the WebSocket close context + */ + public void memoryStatsStreamOnClose(WsCloseContext wsCloseContext) { + logger.info("WebSocket connection closed for memory stats"); + memoryWebSocketContexts.remove(wsCloseContext); + } + + /** + * Sends current JVM memory statistics to the connected WebSocket client. + * @param ctx the WebSocket context + */ + private void sendMemoryStats(WsContext ctx) { + try { + MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); + MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage(); + + long max = heapMemoryUsage.getMax(); + long used = heapMemoryUsage.getUsed(); + long free = max - used; + + // Create JSON-like string + String memoryStats = String.format("{\"max\": %d, \"used\": %d, \"free\": %d}", max, used, free); + + if (ctx.session.isOpen()) { + ctx.send(memoryStats); + } + } catch (Exception e) { + logger.error("Error sending memory stats", e); + } + } + + /** + * Retrieves the database file associated with the specified user. + * + * @param user The user for whom the database file is being retrieved. + * @return A File instance representing the user's database file. + */ + @NotNull + public File getDatabaseFile(User user) { + return getDatabaseFile(user.getIdentifier(), configuration.getWorkingDirectory()); + } + + + /** + * Retrieves the database file associated with the specified user. + * + * @param userId The identifier of the user for whom the database file is being retrieved. + * @param workingDirectory The working directory where the database file is located. + * @return A File instance representing the user's database file. + */ + public static File getDatabaseFile(int userId, String workingDirectory) { + return new File(workingDirectory, OwsController.getUserDatabaseName(userId) + ".mv.db"); + } +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/database/DatabaseManagement.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/database/DatabaseManagement.java new file mode 100644 index 000000000..a81929d67 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/database/DatabaseManagement.java @@ -0,0 +1,723 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + + +package org.noise_planet.noisemodelling.webserver.database; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.h2gis.functions.factory.H2GISDBFactory; +import org.h2gis.functions.factory.H2GISFunctions; +import org.h2gis.utilities.JDBCUtilities; +import org.jetbrains.annotations.NotNull; +import org.noise_planet.noisemodelling.webserver.Configuration; +import org.noise_planet.noisemodelling.webserver.script.JobStates; +import org.noise_planet.noisemodelling.webserver.secure.JWTProviderFactory; +import org.noise_planet.noisemodelling.webserver.secure.Role; +import org.noise_planet.noisemodelling.webserver.secure.User; +import org.noise_planet.noisemodelling.webserver.utilities.StringUtilities; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sql.DataSource; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; +import java.io.File; +import java.sql.*; +import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Duration; +import java.util.*; +import java.util.Date; + +/** + * Handle the creation of datasource according to application configuration + * The Model of the Web Server + */ +public class DatabaseManagement { + public static final int DATABASE_VERSION = 1; + public static final String ADMIN_EMAIL = "admin@localhost"; + public static DateFormat mediumDateFormatEN = + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); + + /** + * Create H2Database datasource + * @param databaseDirectory Where to store the database + * @param databaseName Name of the database + * @param userName Admin username + * @param userPassword Admin password + * @param secureBaseEncryptionSecret Encryption database password, optional (empty) + * @param initializeSpatial If true initialize H2GIS + * @return DataSource instance + * @throws SQLException If something wrong happened + */ + public static HikariDataSource createH2DataSource(String databaseDirectory, String databaseName, String userName, + String userPassword, String secureBaseEncryptionSecret, + boolean initializeSpatial) throws SQLException { + HikariConfig config = new HikariConfig(); + + StringBuilder connectionUrl = getConnectionUrl(databaseDirectory, databaseName, + !secureBaseEncryptionSecret.isEmpty()); + + Properties properties = new Properties(); + properties.setProperty(H2GISDBFactory.JDBC_URL, connectionUrl.toString()); + properties.setProperty(H2GISDBFactory.JDBC_USER, userName); + properties.setProperty(H2GISDBFactory.JDBC_PASSWORD, + secureBaseEncryptionSecret.isEmpty() ? userPassword : secureBaseEncryptionSecret + " " + userPassword); + + javax.sql.DataSource h2DataSource = H2GISDBFactory.createDataSource(properties); + config.setDataSource(h2DataSource); + config.setConnectionTestQuery("SELECT 1"); + config.setConnectionTimeout(30000); + config.setIdleTimeout(600000); + config.setMaxLifetime(1800000); + config.setMinimumIdle(1); + config.setMaximumPoolSize(10); + HikariDataSource dataSource = new HikariDataSource(config); + if (initializeSpatial) { + // Init spatial ext + try (Connection connection = dataSource.getConnection()) { + H2GISFunctions.load(connection); + } + } + return dataSource; + } + + /** + * Build H2 connection URL + * @param databaseDirectory Database directory + * @param databaseName Database name + * @param databaseEncryption True to enable encryption + * @return Connection URL + */ + @NotNull + public static StringBuilder getConnectionUrl(String databaseDirectory, String databaseName, + boolean databaseEncryption) { + StringBuilder connectionUrl = new StringBuilder(); + connectionUrl.append(H2GISDBFactory.START_URL); + try { + connectionUrl.append(new File(databaseDirectory, databaseName) + .getAbsolutePath().replace("\\", "/")); + } catch (Exception e) { + throw new RuntimeException("Error building H2GIS JDBC URL", e); + } + if (databaseEncryption) { + connectionUrl.append(";CIPHER=AES"); + } + return connectionUrl; + } + + + public static void initializeServerDatabaseStructure(DataSource dataSource, Configuration configuration) throws SQLException { + try(Connection connection = dataSource.getConnection()) { + if(!JDBCUtilities.tableExists(connection, "ATTRIBUTES")) { + // First database + createServerDataBaseStructure(connection); + } else { + // Existing database, may need to update it if old version + int databaseVersion = DATABASE_VERSION; + Statement st = connection.createStatement(); + ResultSet rs = st.executeQuery("SELECT * FROM ATTRIBUTES"); + if (rs.next()) { + databaseVersion = rs.getInt("DATABASE_VERSION"); + } + // In the future check databaseVersion for database upgrades + if (databaseVersion < DATABASE_VERSION) { + // do upgrade + st.executeUpdate("UPDATE ATTRIBUTES SET DATABASE_VERSION = " + databaseVersion); + } else if (databaseVersion > DATABASE_VERSION) { + throw new IllegalStateException( + String.format("Database more recent than application version %d > %d", + databaseVersion, DATABASE_VERSION)); + } + } + // Check if the user database is empty + // There should be at least the admin account in the database + // if not create one and print the register url into the console + if(JDBCUtilities.getRowCount(connection, "USERS") == 0) { + // Create an admin account + int pkUser = addUser(connection, ADMIN_EMAIL, Role.ADMINISTRATOR, Role.RUNNER); + User firstAdmin = DatabaseManagement.getUser(connection, pkUser); + Logger logger = LoggerFactory.getLogger(DatabaseManagement.class); + logger.info("First start of the server, register the Administrator account using this url (or run with -u option):\n {}", + firstAdmin.getRegisterUrl(configuration.getWebSiteFullUrl())); + } else { + // Check if Admin user(id:1) have not yet activating is account + User firstAdmin = DatabaseManagement.getUser(connection, 1); + if(firstAdmin.isAdministrator() && !firstAdmin.getRegisterToken().isEmpty()) { + Logger logger = LoggerFactory.getLogger(DatabaseManagement.class); + logger.warn("The Administrator account has not been registered yet," + + " please use this url to create the account (or run with -u option):\n {}", + firstAdmin.getRegisterUrl(configuration.getWebSiteFullUrl())); + } + } + } + + } + + public static void createServerDataBaseStructure(Connection connection) throws SQLException { + Statement st = connection.createStatement(); + final String serverSecretToken = JWTProviderFactory.generateServerSecretToken(); + st.executeUpdate( + "CREATE TABLE IF NOT EXISTS ATTRIBUTES(" + + "DATABASE_VERSION INTEGER," + + "SERVER_JWT_SIGNING_KEY VARCHAR" + + ")"); + PreparedStatement pst = connection.prepareStatement( + "INSERT INTO ATTRIBUTES(" + + "DATABASE_VERSION," + + "SERVER_JWT_SIGNING_KEY)" + + " VALUES(?, ?);"); + pst.setInt(1, DATABASE_VERSION); + pst.setString(2, serverSecretToken); + pst.execute(); + st.executeUpdate( + "CREATE TABLE USERS(" + + " PK_USER SERIAL PRIMARY KEY," + + " EMAIL VARCHAR UNIQUE," + + " TOTP_TOKEN VARCHAR," + + " REGISTER_TOKEN VARCHAR" + + ")" + ); + st.executeUpdate( + "CREATE TABLE ROLES(" + + " PK_USER INTEGER," + + " ROLE VARCHAR," + + " FOREIGN KEY (PK_USER) " + + " REFERENCES USERS(PK_USER) " + + " ON DELETE CASCADE" + + ")" + ); + st.executeUpdate( + "CREATE TABLE JOBS(" + + " PK_JOB INTEGER AUTO_INCREMENT PRIMARY KEY," + + " PK_USER INTEGER," + + " SCRIPT_ID VARCHAR," + + " PROGRESSION REAL," + + " STATUS VARCHAR DEFAULT '"+ JobStates.QUEUED.name() +"'," + + " BEGIN_DATE TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP," + + " END_DATE TIMESTAMP WITHOUT TIME ZONE," + + " FOREIGN KEY (PK_USER) " + + " REFERENCES USERS(PK_USER) " + + " ON DELETE CASCADE" + + ")" + ); + + } + + /** + * Retrieve the generated signing key of the server + * That key is used to sign the JWT tokens provided to the users + * If a malicious user tries to change the payload (ex. user identifier), then the token will not be valid + * @param serverDataSource data source + * @return JWTSigningKey + * @throws SQLException Something went wrong + */ + public static String getJWTSigningKey(DataSource serverDataSource) throws SQLException { + try(Connection connection = serverDataSource.getConnection()) { + Statement st = connection.createStatement(); + ResultSet rs = st.executeQuery("SELECT * FROM ATTRIBUTES"); + if (rs.next()) { + return rs.getString("SERVER_JWT_SIGNING_KEY"); + } else { + throw new IllegalStateException(); + } + } + } + + /** + * Get user roles + * @param connection Data source to the database + * @param userIdentifier User identifier in the database (e.g., primary key) + * @return List of roles associated with the user + * @throws SQLException If something wrong happened + */ + public static List getUserRoles(Connection connection, int userIdentifier) throws SQLException { + // Prepare statement to retrieve roles for a specific user + PreparedStatement pst = connection.prepareStatement("SELECT ROLE FROM ROLES WHERE PK_USER=?"); + + pst.setInt(1, userIdentifier); + + ResultSet rs = pst.executeQuery(); + + // Store the roles in a list and return it + List roles = new ArrayList<>(); + while (rs.next()) { + roles.add(rs.getString("ROLE")); + } + + return roles; + } + + /** + * Get user from database + * @param serverDataSource Data source to the database + * @param userIdentifier User identifier in the database (e.g., primary key) + * @return User object with associated roles and details + * @throws SQLException If something wrong happened + */ + public static User getUser(DataSource serverDataSource, int userIdentifier) throws SQLException { + try(Connection connection = serverDataSource.getConnection()) { + return getUser(connection, userIdentifier); + } + } + + /** + * Get user from database + * @param connection Data source to the database + * @param userIdentifier User identifier in the database (e.g., primary key) + * @return User object with associated roles and details + * @throws SQLException If something wrong happened + */ + public static User getUser(Connection connection, int userIdentifier) throws SQLException { + // Prepare statement to retrieve the specific user and his roles + String sql = "SELECT * FROM USERS WHERE PK_USER=?"; + PreparedStatement pstUser = connection.prepareStatement(sql); + + pstUser.setInt(1, userIdentifier); + + ResultSet rsUser = pstUser.executeQuery(); + + // If no user found with that identifier + if(!rsUser.next()) { + return null; + } + + return getUser(connection, rsUser); + } + + @NotNull + public static User getUser(Connection connection, ResultSet rsUser) throws SQLException { + String email = rsUser.getString("EMAIL"); + String registerToken = rsUser.getString("REGISTER_TOKEN"); + int userIdentifier = rsUser.getInt("PK_USER"); + List rolesList = getUserRoles(connection, userIdentifier); // Retrieve the user's roles + Set roles = new HashSet<>(); + + for (String roleName : rolesList) { + try { + Role role = Role.valueOf(roleName); + roles.add(role); + } catch (IllegalArgumentException ex ) { + Logger logger = LoggerFactory.getLogger(DatabaseManagement.class); + logger.error(ex.getLocalizedMessage(), ex); + } + } + + // Create a User object and return it + return new User(userIdentifier, email, roles, registerToken); + } + + /** + * This method adds a new user with the provided email. + *

    + * It generates an expected token that would be provided in the url when associating to a TOTP generator + * This token is provided to the user with the server url by mail or other communication method. + * + * @param connection The database Connection object used to execute the query. + * @param email The email of the user to be added. + * @return The token generated for this new user. + * @throws SQLException If the operation fails to add a user (i.e., no rows are affected in the "USERS" table). + */ + public static int addUser(Connection connection, String email, Role... roles) throws SQLException { + String sql = "INSERT INTO USERS (EMAIL, REGISTER_TOKEN) VALUES (?, ?)"; + PreparedStatement pstUser = connection.prepareStatement(sql, + Statement.RETURN_GENERATED_KEYS); + + // Set the parameters of the SQL statement + + String urlToken = JWTProviderFactory.generateServerSecretToken(); + + pstUser.setString(1, email); + pstUser.setString(2, urlToken); + + // Execute the statement and get the result + int rowsAffected = pstUser.executeUpdate(); + + if (rowsAffected == 0) { + throw new SQLException("Failed to add user."); + } + + ResultSet rs = pstUser.getGeneratedKeys(); + if (!rs.next()) { + throw new SQLException("Failed to get user primary key."); + } + + int userPk = rs.getInt(1); + + sql = "INSERT INTO ROLES (PK_USER, ROLE) VALUES (?, ?)"; + pstUser = connection.prepareStatement(sql); + for(Role role : roles) { + pstUser.setInt(1, userPk); + pstUser.setString(2, role.toString()); + rowsAffected = pstUser.executeUpdate(); + if (rowsAffected == 0) { + throw new SQLException("Failed to add roles."); + } + } + + return userPk; + } + + /** + * Get user by register token + * @param connection The database Connection object + * @param registerToken The registration token from URL + * @return User identifier or -1 if not found + * @throws SQLException If database error occurs + */ + public static int getUserByRegisterToken(Connection connection, String registerToken) throws SQLException { + String sql = "SELECT PK_USER FROM USERS WHERE REGISTER_TOKEN = ?"; + try (PreparedStatement pst = connection.prepareStatement(sql)) { + pst.setString(1, registerToken); + try (ResultSet rs = pst.executeQuery()) { + if (rs.next()) { + return rs.getInt("PK_USER"); + } + } + } + return -1; // Token not found + } + + /** + * Updates the TOTP token for a user and clears their registerToken field. + * + * @param connection The database connection object. + * @param userIdentifier The unique identifier of the user in the database. + * @param totpToken The new Time-Based One-Time Password (TOTP) token to be assigned to the user. + * @throws SQLException If there's an error executing the SQL update or if no rows were affected, + * indicating that no user with the given identifier was found in the database. + */ + public static void updateUserTotpToken(Connection connection, int userIdentifier, String totpToken) throws SQLException { + // Use an UPDATE query to set the new TOTP token and clear the registerToken field for the specified user. + String sql = "UPDATE USERS SET TOTP_TOKEN = ?, REGISTER_TOKEN = '' WHERE PK_USER = ?"; + PreparedStatement pstUser = connection.prepareStatement(sql); + + // Set the parameters of the SQL statement + pstUser.setString(1, totpToken); + pstUser.setInt(2, userIdentifier); + + // Execute the statement and get the result + int rowsAffected = pstUser.executeUpdate(); + + if (rowsAffected == 0) { + throw new SQLException("Failed to update TOTP token for user with PK_USER: " + userIdentifier); + } + } + + /** + * Get user by register token + * @param connection The database Connection object + * @param email User email + * @return User TOTP_TOKEN or empty if not found + * @throws SQLException If database error occurs + */ + public static String getTotpSecretByUserEmail(Connection connection, String email) throws SQLException { + if(email == null || email.isEmpty()) { + return ""; + } + String sql = "SELECT TOTP_TOKEN FROM USERS WHERE EMAIL = ?"; + try (PreparedStatement pst = connection.prepareStatement(sql)) { + pst.setString(1, email); + try (ResultSet rs = pst.executeQuery()) { + if (rs.next()) { + return rs.getString("TOTP_TOKEN"); + } + } + } + return ""; // email not found + } + + /** + * Get user id by using email + * @param connection The database Connection object + * @param email User email + * @return User identifier or -1 if not found + * @throws SQLException If database error occurs + */ + public static int getUserIdByUserEmail(Connection connection, String email) throws SQLException { + if(email == null || email.isEmpty()) { + return -1; + } + String sql = "SELECT PK_USER FROM USERS WHERE EMAIL = ?"; + try (PreparedStatement pst = connection.prepareStatement(sql)) { + pst.setString(1, email); + try (ResultSet rs = pst.executeQuery()) { + if (rs.next()) { + return rs.getInt("PK_USER"); + } + } + } + return -1; // email not found + } + + /** + * Create a new job with the specified user and return the job identifier + * @param connection SQL Connection + * @param userIdentifier User identifier + * @return Job identifier + * @throws SQLException Error + */ + public static int createJob(Connection connection, int userIdentifier, String jobScript) throws SQLException { + PreparedStatement st = connection.prepareStatement("INSERT INTO JOBS (PK_USER, SCRIPT_ID) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS); + st.setInt(1, userIdentifier); + st.setString(2, jobScript); + int affectedRows = st.executeUpdate(); + if (affectedRows == 0) { + throw new SQLException("Failed to create job."); + } + ResultSet rs = st.getGeneratedKeys(); + if (rs.next()) { + return rs.getInt(1); + } else { + throw new SQLException("Failed to create job."); + } + } + + /** + * Update the state of an existing Job record. + *

    + * Persists the given state in table {@code JOBS} for the row identified by {@code PK_JOB}. + * The {@code jobState} is expected to be the name of a value from + * {@link org.noise_planet.noisemodelling.webserver.script.JobStates} (e.g. {@code QUEUED}, {@code RUNNING}, etc.). + *

    + * + * @param connection The open JDBC {@link Connection} to use; must not be {@code null}. + * @param jobId The identifier of the job to update (value of column {@code PK_JOB}). + * @param jobState The new state to set for the job (typically {@code JobStates.name()}). + * @throws SQLException If a database access error occurs, or if no row was updated (job not found). + */ + public static void setJobState(Connection connection, int jobId, String jobState) throws SQLException { + PreparedStatement st = connection.prepareStatement("UPDATE JOBS SET STATUS = ? WHERE PK_JOB = ?"); + st.setString(1, jobState); + st.setInt(2, jobId); + int affectedRows = st.executeUpdate(); + if (affectedRows == 0) { + throw new SQLException("Failed to set job state."); + } + } + + public static void setJobProgression(Connection connection, int jobId, double progression) throws SQLException { + PreparedStatement st = connection.prepareStatement("UPDATE JOBS SET PROGRESSION = ? WHERE PK_JOB = ?"); + st.setDouble(1, progression); + st.setInt(2, jobId); + st.execute(); + } + + public static void setJobEndTime(Connection connection, int jobId) throws SQLException { + PreparedStatement st = connection.prepareStatement("UPDATE JOBS SET END_DATE = ? WHERE PK_JOB = ?"); + st.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + st.setInt(2, jobId); + st.execute(); + } + + /** + * Fetch the content of the JOB table + * @param connection + * @param filterByUserIdentifier if {@code > 0}, will filter the job for a specific user. Administrator see all jobs. + * @return Job list + * @throws SQLException + */ + public static List> getJobs(Connection connection, int filterByUserIdentifier) throws SQLException { + List> table = new ArrayList<>(); + StringBuilder sql = new StringBuilder("SELECT JOBS.*, USERS.EMAIL FROM JOBS INNER JOIN USERS ON JOBS.PK_USER = USERS.PK_USER "); + if(filterByUserIdentifier > 0) { + sql.append("WHERE PK_USER = ? "); + } + sql.append("ORDER BY BEGIN_DATE DESC"); + PreparedStatement statement = connection.prepareStatement(sql.toString()); + if(filterByUserIdentifier > 0) { + statement.setInt(1, filterByUserIdentifier); + } + DecimalFormat f = (DecimalFormat)(DecimalFormat.getInstance(Locale.ROOT)); + f.applyPattern("#.### '%'"); + try (ResultSet rs = statement.executeQuery()) { + while (rs.next()) { + table.add(parseJob(rs, mediumDateFormatEN, f)); + } + } + return table; + } + + /** + * + * @param stringDate + * @throws SQLException + * @throws ParseException + * @throws DatatypeConfigurationException + */ + public static XMLGregorianCalendar dateToXMLGregorianCalendar(String stringDate) + throws SQLException, ParseException, DatatypeConfigurationException { + Date date = mediumDateFormatEN.parse(stringDate); + GregorianCalendar gregorianCalendar = new GregorianCalendar(); + gregorianCalendar.setTime(date); + return DatatypeFactory.newInstance() + .newXMLGregorianCalendar(gregorianCalendar); + } + + + /** + * Fetch the content of the JOB table + * @param connection + * @param jobId if {@code > 0}, will filter the job for a specific user. Administrator see all jobs. + * @return Job list + * @throws SQLException + */ + public static Map getJob(Connection connection, int jobId) throws SQLException { + PreparedStatement statement = connection.prepareStatement("SELECT JOBS.*, USERS.EMAIL FROM JOBS INNER JOIN USERS ON JOBS.PK_USER = USERS.PK_USER WHERE PK_JOB = ?"); + statement.setInt(1, jobId); + DecimalFormat f = (DecimalFormat)(DecimalFormat.getInstance(Locale.ROOT)); + f.applyPattern("#.### '%'"); + DateFormat mediumDateFormatEN = + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); + try (ResultSet rs = statement.executeQuery()) { + if (rs.next()) { + return parseJob(rs, mediumDateFormatEN, f); + } + } + return Collections.emptyMap(); + } + + @NotNull + public static Map parseJob(ResultSet rs, DateFormat mediumDateFormatEN, DecimalFormat f) throws SQLException { + Map row = new HashMap<>(); + Integer pkJob = rs.getInt("pk_job"); + row.put("id", pkJob); + row.put("script", rs.getString("SCRIPT_ID")); + row.put("deletable", Objects.equals(rs.getString("STATUS"), JobStates.COMPLETED.name()) || + Objects.equals(rs.getString("STATUS"), JobStates.FAILED.name())); + row.put("cancelable", Objects.equals(rs.getString("STATUS"), JobStates.QUEUED.name()) || + Objects.equals(rs.getString("STATUS"), JobStates.RUNNING.name())); + row.put("email", rs.getString("email")); + Timestamp bDate = rs.getTimestamp("BEGIN_DATE"); + row.put("startDate", !rs.wasNull() ? mediumDateFormatEN.format(bDate) : "-"); + Timestamp eDate = rs.getTimestamp("END_DATE"); + String endDate = "-"; + String duration = "-"; + Duration computationTime = null; + if(!rs.wasNull()) { + endDate = mediumDateFormatEN.format(eDate); + computationTime = Duration.ofMillis( + eDate.getTime() - bDate.getTime()); + } else if(bDate != null){ + computationTime = Duration.ofMillis( + System.currentTimeMillis() - bDate.getTime()); + } + if(computationTime != null) { + duration = StringUtilities.durationToString(computationTime); + } + row.put("endDate", endDate); + row.put("duration", duration); + row.put("userId", rs.getInt("PK_USER")); + row.put("status", rs.getString("STATUS")); + row.put("progression", f.format(rs.getDouble("PROGRESSION"))); + return row; + } + + public static List getUsers(Connection connection) throws SQLException { + List table = new ArrayList<>(); + try(ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM USERS ORDER BY PK_USER")) { + while (rs.next()) { + table.add(getUser(connection, rs)); + } + } + return table; + } + + /** + * Updates the user attributes (email, totp token) in the database. + * + * @param connection The database connection object. + * @param user New attributes for the user. + * @throws SQLException If there's an error executing the SQL update or if no rows were affected, + * indicating that no user with the given identifier was found in the database. + */ + public static void updateUserAttributes(Connection connection, User user) throws SQLException { + // Use an UPDATE query to set the new TOTP token and clear the registerToken field for the specified user. + String sql = "UPDATE USERS SET EMAIL = ?, REGISTER_TOKEN = ? WHERE PK_USER = ?"; + + try(PreparedStatement pstUser = connection.prepareStatement(sql)) { + // Set the parameters of the SQL statement + pstUser.setString(1, user.getEmail()); + pstUser.setString(2, user.getRegisterToken()); + pstUser.setInt(3, user.getIdentifier()); + + // Execute the statement and get the result + int rowsAffected = pstUser.executeUpdate(); + + if (rowsAffected == 0) { + throw new SQLException("Failed to update user with PK_USER: " + user.getIdentifier()); + } + } + // Update groups + + sql = "DELETE FROM ROLES WHERE PK_USER = ?"; + try(PreparedStatement pstUser = connection.prepareStatement(sql)) { + pstUser.setInt(1, user.getIdentifier()); + pstUser.executeUpdate(); + } + + sql = "INSERT INTO ROLES (PK_USER, ROLE) VALUES (?, ?)"; + try(PreparedStatement pstUser = connection.prepareStatement(sql)) { + for (Role role : user.getRoles()) { + pstUser.setInt(1, user.getIdentifier()); + pstUser.setString(2, role.toString()); + pstUser.addBatch(); + } + if(!user.getRoles().isEmpty()) { + pstUser.executeBatch(); + } + } + + } + + public static void deleteUser(Connection connection, int userIdentifier) throws SQLException{ + if(userIdentifier > 1) { + // delete user by cascading to deletion + String sql = "DELETE FROM USERS WHERE PK_USER = ?"; + try(PreparedStatement pstUser = connection.prepareStatement(sql)) { + pstUser.setInt(1, userIdentifier); + pstUser.executeUpdate(); + } + } + } + + /** + * Deletes a job record from the JOBS table based on the specified job ID. + * + * @param connection The database connection to be used for executing the query. + * @param jobId The ID of the job to be deleted. + * @throws SQLException If a database access error occurs or the SQL statement fails to execute. + */ + public static void deleteJob(Connection connection, int jobId) throws SQLException { + String sql = "DELETE FROM JOBS WHERE PK_JOB = ?"; + try (PreparedStatement pstUser = connection.prepareStatement(sql)) { + pstUser.setInt(1, jobId); + pstUser.executeUpdate(); + } + } + + /** + * Deletes all jobs from the JOBS table that are not in the 'QUEUED' or 'RUNNING' status. + * + * @param connection the active database connection to use for executing the deletion query + * @param identifier User identifier + * @throws SQLException if a database access error occurs or the SQL statement fails + */ + public static void deleteAllFinalizedJobs(Connection connection, int identifier) throws SQLException { + String sql = "DELETE FROM JOBS WHERE STATUS NOT IN ('QUEUED', 'RUNNING') AND PK_USER = ?"; + try (PreparedStatement pstUser = connection.prepareStatement(sql)) { + pstUser.setInt(1, identifier); + pstUser.executeUpdate(); + } + } +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ExecutionPlan.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ExecutionPlan.java new file mode 100644 index 000000000..6223f0732 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ExecutionPlan.java @@ -0,0 +1,99 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.script; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; + + +/** + * Store the inputs and outputs of a job execution. + * Inputs values can be an instance of ExecutionPlan for a chained process and will be replaced by the outputs of the previous process. + */ +public class ExecutionPlan { + protected final Map inputs; + protected Object outputs; + protected final ScriptMetadata scriptMetadata; + // If this plan is referenced as an input of another plan, + // this is the key of one of these plan outputs that will be used as an input of the parent plan + protected final String chainedOutputKey; + + /** + * Create a new ExecutionPlan. + * @param inputs WPS Scripts inputs + * @param scriptMetadata Metadata of the script + */ + public ExecutionPlan(Map inputs, ScriptMetadata scriptMetadata) { + this.inputs = inputs; + this.outputs = null; + this.scriptMetadata = scriptMetadata; + this.chainedOutputKey = ""; + } + + /** + * Create a new ExecutionPlan for a chained process. + * @param inputs WPS Scripts inputs + * @param scriptMetadata Metadata of the script + * @param chainedOutputKey the name of the output of this plan used as an input of the parent plan + */ + public ExecutionPlan(Map inputs, ScriptMetadata scriptMetadata, String chainedOutputKey) { + this.chainedOutputKey = chainedOutputKey; + this.inputs = inputs; + this.outputs = null; + this.scriptMetadata = scriptMetadata; + } + + /** + * Fill missing optional inputs, from specified default values in the scripts metadata + */ + public void fillInputsWithDefaultValues() { + scriptMetadata.inputs.entrySet( ).stream().filter( + entry -> entry.getValue().defaultValue != null + && !inputs.containsKey(entry.getKey())) + .forEach(entry -> { + Object defaultValue = entry.getValue().defaultValue; + Class expectedType = entry.getValue().type; + // Groovy may generate BigDecimal instead of expected class + // So cast/convert to the expected type + if(expectedType != null && !expectedType.isAssignableFrom(defaultValue.getClass())) { + try { + defaultValue = ScriptMetadata.castInputUsingExpectedInputType(expectedType, defaultValue.toString()); + } catch (Exception ex) { + Logger logger = LoggerFactory.getLogger(ExecutionPlan.class); + logger.info("Warning, failed to cast default value for input '{}', use the original value. Exception: {}", + entry.getKey(), ex.getMessage()); + } + } + inputs.put(entry.getKey(), defaultValue); + }); + } + + public Map getInputs() { + return inputs; + } + public Object getOutputs() { + return outputs; + } + public ScriptMetadata getScriptMetadata() { + return scriptMetadata; + } + public void setOutputs(Object outputs) { + this.outputs = outputs; + } + + /** + * @return the name of the output of this plan used as an input of the parent plan + */ + public String getChainedOutputKey() { + return chainedOutputKey; + } + +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/Job.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/Job.java new file mode 100644 index 000000000..200fecde4 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/Job.java @@ -0,0 +1,301 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + +package org.noise_planet.noisemodelling.webserver.script; + +import groovy.lang.GroovyShell; +import groovy.lang.MetaMethod; +import groovy.lang.Script; +import org.h2gis.api.ProgressVisitor; +import org.jetbrains.annotations.NotNull; +import org.noise_planet.noisemodelling.webserver.Configuration; +import org.noise_planet.noisemodelling.webserver.database.DatabaseManagement; +import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sql.DataSource; +import java.io.IOException; +import java.math.BigInteger; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; + +/** + * Manage the execution of a Groovy Script + */ +public class Job implements Callable { + private static final Logger logger = LoggerFactory.getLogger(Job.class); + /** NoiseModelling DataBase for the user */ + public static final int WPS_RESPONSE_LOGGING_LENGTH_LIMIT = 2000; + protected DataSource userDataSource; + protected DataSource serverDataSource; + protected boolean isRunning = false; + protected int userId; + protected int jobId; + protected Configuration configuration; + protected Future future; + protected ProgressVisitor progressVisitor; + protected ExecutionPlan executionPlan; + protected Exception jobException = null; + + public Job(int userId, ExecutionPlan executionPlan, + DataSource serverDataSource, DataSource userDataSource, Configuration configuration) throws SQLException { + this.userId = userId; + this.executionPlan = executionPlan; + this.configuration = configuration; + this.userDataSource = userDataSource; + this.serverDataSource = serverDataSource; + progressVisitor = new RootProgressVisitor(1, false, 0); + try (Connection connection = serverDataSource.getConnection()) { + this.jobId = DatabaseManagement.createJob(connection, userId, executionPlan.scriptMetadata.id); + progressVisitor.addPropertyChangeListener("PROGRESS" , new ProgressionTracker(serverDataSource, jobId)); + } + } + + void setJobState(JobStates newState) { + try (Connection connection = serverDataSource.getConnection()) { + DatabaseManagement.setJobState(connection, jobId, newState.name()); + } catch (SQLException | SecurityException ex) { + logger.error(ex.getLocalizedMessage(), ex); + } + } + + + void setJobProgression(int progression) { + try (Connection connection = serverDataSource.getConnection()) { + DatabaseManagement.setJobProgression(connection, jobId, progression); + } catch (SQLException | SecurityException ex) { + logger.error(ex.getLocalizedMessage(), ex); + } + } + + /** + * Get the user id of the job + * @return User id + */ + public int getUserId() { + return userId; + } + + void onJobEnd() throws SQLException { + try (Connection connection = serverDataSource.getConnection()) { + DatabaseManagement.setJobEndTime(connection, jobId); + } catch (SQLException | SecurityException ex) { + logger.error(ex.getLocalizedMessage(), ex); + } + } + + public Future getFuture() { + return future; + } + + public void setFuture(Future future) { + this.future = future; + } + + @Override + public T call() throws Exception { + // Change the Thread name to match the logging filter to the logging messages of this job + Thread.currentThread().setName(getThreadName(jobId)); + isRunning = true; + setJobState(JobStates.RUNNING); + // Follow the execution plan by executing instances of ExecutionPlan on inputs + ExecutionPlan currentPlan = executionPlan; + // The currentPlan is executing because the output of the currentPlan + // is the input (parentPlanInputName) of the parent plan + Stack parentPlan = new Stack<>(); + Stack parentPlanInputName = new Stack<>(); + T returnData = null; + try { + while (currentPlan != null) { + // Check inputs of the current plan to find the next plan to execute + // If one of the input is an ExecutionPlan and not a literal value, it is the next plan to execute + boolean recheck = false; + for (Map.Entry input : currentPlan.inputs.entrySet()) { + if (input.getValue() instanceof ExecutionPlan) { + parentPlan.push(currentPlan); + parentPlanInputName.push(input.getKey()); + currentPlan = (ExecutionPlan) input.getValue(); + recheck = true; + break; + } + } + if (recheck) { + // The current plan has changed, we need to recheck the inputs + continue; + } + Object ret = runScript(currentPlan, progressVisitor, userDataSource); + @SuppressWarnings("unchecked") T castedReturn = (T) ret; + returnData = castedReturn; + if(!parentPlan.isEmpty()) { + // Update the value of the parent plan input + if(currentPlan.chainedOutputKey.isEmpty() || !(currentPlan.outputs instanceof Map + && ((Map) currentPlan.outputs).containsKey(currentPlan.chainedOutputKey))) { + parentPlan.peek().inputs.put(parentPlanInputName.pop(), currentPlan.outputs); + } else { + Map outputs = (Map) currentPlan.outputs; + parentPlan.peek().inputs.put(parentPlanInputName.pop(), outputs.get(currentPlan.chainedOutputKey)); + } + } + currentPlan = parentPlan.isEmpty() ? null : parentPlan.pop(); + } + setJobState(JobStates.COMPLETED); + setJobProgression(100); + } catch (Exception ex) { + setJobState(JobStates.FAILED); + logger.error("Job failed", ex); + jobException = ex; + throw new RuntimeException(ex); + } finally { + isRunning = false; + onJobEnd(); + } + return returnData; + } + + /** + * Retrieves the execution plan associated with the job. + * The execution plan encapsulates the metadata, inputs, outputs, + * and other details required for script execution within the job. + * + * @return The execution plan instance linked to this job. + */ + public ExecutionPlan getExecutionPlan() { + return executionPlan; + } + + /** + * Retrieves the exception associated with the job, if any. + * + * @return The exception that occurred during the job execution, or null if no exception was thrown. + */ + public Exception getJobException() { + return jobException; + } + + + /** + * Executes a Groovy script defined in the given execution plan. The script must have an `exec` method + * with one of the following signatures: + * - `exec(Connection connection, Map input)` + * - `exec(DataSource dataSource, Map input)` + * - `exec(Connection connection, Map input, ProgressVisitor progressVisitor)` + * - `exec(DataSource dataSource, Map input, ProgressVisitor progressVisitor)` + *

    + * This method handles script execution by dynamically invoking the appropriate `exec` method + * and passing in the required arguments, which may include a database connection, input parameters, + * and a progress visitor. The outputs of the script, if any, are stored in the execution plan. + * + * @param currentPlan The execution plan that contains the script metadata, input parameters, and stores outputs. + * @param progressVisitor An instance of `ProgressVisitor` used for reporting progress during script execution. + * @param userDataSource The data source to provide a database connection for the script + * + * @return The result produced by the executed script, or null if no result is returned. + * + * @throws IOException If an I/O error occurs during script execution. + * @throws SQLException If a database access error occurs. + * @throws RuntimeException If the `exec` method's argument types are invalid or other runtime exceptions occur. + */ + public static Object runScript(ExecutionPlan currentPlan, ProgressVisitor progressVisitor, DataSource userDataSource) throws IOException, SQLException { + Object returnData = null; + GroovyShell shell = new GroovyShell(); + Script script = shell.parse(currentPlan.scriptMetadata.path); + // Check expected arguments + List methods = script.getMetaClass().getMethods(); + MetaMethod execMetaMethod = null; + // Take the exec method with the most arguments, in case there are multiple exec methods, + // we want to use the one with the most arguments to provide more features to the script author + for (MetaMethod method : methods) { + if (method.getName().equals("exec")) { + if (execMetaMethod == null || method.getNativeParameterTypes().length > execMetaMethod.getNativeParameterTypes().length) { + execMetaMethod = method; + } + } + } + boolean useConnection = true; //first argument is a connection input + boolean useProgressVisitor = false; // third argument is a ProgressVisitor + if (execMetaMethod != null) { + // 2. Access the native parameter types + Class[] parameterTypes = execMetaMethod.getNativeParameterTypes(); + Class firstArgClass = parameterTypes[0]; + if (firstArgClass.equals(DataSource.class)) { + useConnection = false; + } else if (!firstArgClass.equals(Object.class) && !firstArgClass.equals(Connection.class)) { + throw new RuntimeException("Invalid first argument type for exec method in " + currentPlan.scriptMetadata.id); + } + if (parameterTypes.length >= 3 && parameterTypes[2].equals(ProgressVisitor.class)) { + useProgressVisitor = true; + } + // Exec method signature can be: + // def exec(Connection connection, Map input) + // def exec(DataSource dataSource, Map input) + // def exec(Connection connection, Map input, ProgressVisitor progressVisitor) + // def exec(DataSource dataSource, Map input, ProgressVisitor progressVisitor) + Object[] args = new Object[useProgressVisitor ? 3 : 2]; + args[1] = currentPlan.inputs; + if (useProgressVisitor) { + args[2] = progressVisitor; + } + Object ret; + logger.info("Executing script {}", currentPlan.scriptMetadata.id); + if (useConnection) { + // Open the connection to the database + try (Connection connection = userDataSource.getConnection()) { + args[0] = connection; + ret = execMetaMethod.invoke(script, args); + } + } else { + args[0] = userDataSource; + ret = execMetaMethod.invoke(script, args); + } + if (ret != null) { + // Unchecked cast is unavoidable due to type erasure with generics + // The script author is responsible for returning the correct type + currentPlan.outputs = ret; + returnData = ret; + } + } + String outputString = currentPlan.outputs != null ? currentPlan.outputs.toString() : "null"; + logger.info("Script {} executed with result {}", + currentPlan.scriptMetadata.id, + outputString.length() > WPS_RESPONSE_LOGGING_LENGTH_LIMIT ? + outputString.substring(0, WPS_RESPONSE_LOGGING_LENGTH_LIMIT) + + "... [TRUNCATED]" : outputString); + return returnData; + } + + public void cancel() { + progressVisitor.cancel(); + } + + public boolean isRunning() { + return isRunning; + } + + @NotNull + public static String getThreadName(int jobId) { + return String.format("JOB_%d", jobId); + } + + /** + * @return Job id + */ + public int getId() { + return jobId; + } + + public BigInteger getProgression() { + return BigInteger.valueOf(Math.round(progressVisitor.getProgression() * 100)); + } +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/JobExecutorService.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/JobExecutorService.java new file mode 100644 index 000000000..951d92c09 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/JobExecutorService.java @@ -0,0 +1,83 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.script; + +import org.jetbrains.annotations.NotNull; +import org.noise_planet.noisemodelling.webserver.database.DatabaseManagement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Closeable; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.*; + +/** + * Manage pool of Job Threads. + */ +public class JobExecutorService { + protected final Map> jobs = new ConcurrentHashMap<>(); + protected final ExecutorService executorService; + private final Logger logger = LoggerFactory.getLogger(JobExecutorService.class); + + public JobExecutorService(int corePoolSize, int maximumPoolSize, long keepAliveTime, @NotNull TimeUnit unit) { + this.executorService = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, + new SynchronousQueue<>(), Executors.defaultThreadFactory()); + } + + public Future submitJob(Job job) { + if (jobs.containsKey(job.getId())) { + throw new IllegalArgumentException(String.format("Job with ID %d already exists.", job.getId())); + } + jobs.put(job.getId(), job); + Future futureTask = executorService.submit(job); + job.setFuture(futureTask); + return futureTask; + } + + /** + * @param id Job identifier + * @return The job instance or null if it does not exist + */ + public Job getJob(int id) { + return jobs.get(id); + } + + /** + * Cancel a job + * @param jobId Job identifier + * @return true if the job was found and canceled, false otherwise + */ + public boolean cancelJob(int jobId) { + Job job = jobs.get(jobId); + if (job != null) { + job.cancel(); + jobs.remove(jobId); + return true; + } else { + logger.error("Job with ID {} not found.", jobId); + return false; + } + } + + /** + * Remove a job from the service. This does not cancel the job if it is still running, + * it just removes it from the tracking map. See cancelJob(int jobId) to cancel a job before removing it. + * @param jobId Job identifier + * @return The removed job instance or null if it did not exist + */ + public Job removeJob(int jobId) { + return jobs.remove(jobId); + } + + public void shutdown() { + executorService.shutdown(); + } + +} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/JobStates.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/JobStates.java new file mode 100644 index 000000000..c9429f6a6 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/JobStates.java @@ -0,0 +1,20 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.script; + +/** + * Job states enum {@link Job} + */ +public enum JobStates { + QUEUED, + RUNNING, + FAILED, + CANCELED, + COMPLETED +} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ProgressionTracker.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ProgressionTracker.java new file mode 100644 index 000000000..dd7454970 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ProgressionTracker.java @@ -0,0 +1,60 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.script; + + +import org.noise_planet.noisemodelling.webserver.database.DatabaseManagement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sql.DataSource; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.sql.Connection; +import java.sql.SQLException; +import java.text.MessageFormat; + +/** + * Send Job Progression state to the database + */ +public class ProgressionTracker implements PropertyChangeListener { + DataSource serverDataSource; + int jobIdentifier; + private final Logger logger; + private String lastProg = ""; + private long lastProgressionUpdate = 0; + private static final long TABLE_UPDATE_DELAY = 5000; + + public ProgressionTracker(DataSource serverDataSource, int jobIdentifier) { + this.serverDataSource = serverDataSource; + this.jobIdentifier = jobIdentifier; + this.logger = LoggerFactory.getLogger(Job.getThreadName(jobIdentifier)); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if(evt.getNewValue() instanceof Double) { + double progressValue = Math.round(((Double) evt.getNewValue()) * 10000.0) / 100.0; + String newLogProgress = MessageFormat.format("{0,number,0.00}", progressValue); + if(!lastProg.equals(newLogProgress)) { + lastProg = newLogProgress; + long t = System.currentTimeMillis(); + if(t - lastProgressionUpdate > TABLE_UPDATE_DELAY) { + lastProgressionUpdate = t; + try (Connection connection = serverDataSource.getConnection()) { + DatabaseManagement.setJobProgression(connection, jobIdentifier, progressValue); + } catch (SQLException ex) { + logger.error(ex.getLocalizedMessage(), ex); + } + logger.info("{} %", newLogProgress); + } + } + } + } +} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptFileWatchedProcess.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptFileWatchedProcess.java new file mode 100644 index 000000000..a9a3ab816 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptFileWatchedProcess.java @@ -0,0 +1,116 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + + +package org.noise_planet.noisemodelling.webserver.script; + +import org.noise_planet.noisemodelling.webserver.OwsController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.file.*; +import java.util.concurrent.*; +import java.util.stream.Stream; + +/** + * Monitors a specified directory and its subdirectories for changes in files. + * Specifically, watches for creation, deletion, and modification events of files with the `.groovy` extension. + * It triggers a script reload after a 5-second delay, which is reset if further changes are detected. + */ +public class ScriptFileWatchedProcess implements Callable { + + private final Path scriptsDir; + private final OwsController owsController; + private final Logger logger = LoggerFactory.getLogger(ScriptFileWatchedProcess.class); + + // Executor for handling the delayed reload task + private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + private ScheduledFuture pendingTask = null; + private final long delaySeconds = 5; + + public ScriptFileWatchedProcess(Path scriptsDir, OwsController owsController) { + this.scriptsDir = scriptsDir; + this.owsController = owsController; + } + + @Override + public Boolean call() throws Exception { + try (WatchService watchService = FileSystems.getDefault().newWatchService()) { + registerRecursive(watchService); + + while (!Thread.currentThread().isInterrupted()) { + try { + WatchKey key = watchService.take(); + boolean shouldReload = false; + + for (WatchEvent event : key.pollEvents()) { + Path fileName = (Path) event.context(); + if (fileName.toString().endsWith(".groovy")) { + shouldReload = true; + break; + } + } + + if (shouldReload) { + debounceReload(); + } + + boolean valid = key.reset(); + if (!valid) { + break; + } + } catch (InterruptedException interruptedException) { + Thread.currentThread().interrupt(); + break; + } catch (Exception e) { + logger.error("Error in file watch process: {}", e.getMessage(), e); + return false; + } + } + } finally { + scheduler.shutdownNow(); + } + return true; + } + + /** + * Schedules the reload task. If a task is already pending, it cancels it and starts a new 5-second timer. + */ + private synchronized void debounceReload() { + if (pendingTask != null && !pendingTask.isDone()) { + pendingTask.cancel(false); + } + + pendingTask = scheduler.schedule(() -> { + try { + logger.info("Change detected in scripts. Reloading after {}s quiet period...", delaySeconds); + owsController.reloadScripts(); + } catch (Exception e) { + logger.error("Failed to reload scripts: {}", e.getMessage(), e); + } + }, delaySeconds, TimeUnit.SECONDS); + } + + protected void registerRecursive(WatchService watchService) throws IOException { + try (Stream pathStream = Files.walk(scriptsDir)) { + pathStream.filter(Files::isDirectory) + .forEach(dir -> { + try { + dir.register(watchService, + StandardWatchEventKinds.ENTRY_CREATE, + StandardWatchEventKinds.ENTRY_DELETE, + StandardWatchEventKinds.ENTRY_MODIFY); + } catch (IOException e) { + logger.error("Could not register directory {}: {}", dir, e.getMessage()); + } + }); + } + } +} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptInput.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptInput.java new file mode 100644 index 000000000..396a2f0ba --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptInput.java @@ -0,0 +1,34 @@ +package org.noise_planet.noisemodelling.webserver.script; + +import java.util.HashSet; +import java.util.Set; + +/** + * Represents an input configuration for a script. + * This class is designed to encapsulate the metadata and properties that define + * an input to a script, such as its identifier, title, description, type, and + * whether it is optional. + */ +public class ScriptInput { + public String id; + public String title; + public String description; + public Class type; + /** + * Minimum occurrences of this input. A value of 0 indicates that the input is optional. + */ + public int minOccurs = 1; + /** + * Maximum occurrences of this input. + */ + public int maxOccurs = 1; + /** + * Default value for this input. + */ + public Object defaultValue; + + /** + * If at least one element, restrict allowed values, only for Strings + */ + public Set allowedValues = new HashSet<>(); +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptMetadata.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptMetadata.java new file mode 100644 index 000000000..63a91a313 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptMetadata.java @@ -0,0 +1,171 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + + +package org.noise_planet.noisemodelling.webserver.script; + + +import groovy.lang.GroovyShell; +import groovy.lang.Script; +import org.locationtech.jts.geom.Geometry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.URI; +import java.nio.file.Path; +import java.util.*; + +/** + * Represents the description for a script, with expected inputs and outputs + */ +public class ScriptMetadata { + // For the synchronous WPS call, release the http connection after this timeout (with a message "long running process..") + Logger logger = LoggerFactory.getLogger(ScriptMetadata.class); + public static final int DEFAULT_JOB_EXECUTION_TIMEOUT_SECONDS = 60; + final public String id; + final public String group; + final public String title; + final public String description; + final public URI path; + final public URI scriptDirectory; + final public int executionTimeoutSeconds; + + final public Map inputs = new HashMap<>(); + final public Map outputs = new HashMap<>(); + + /** + * Constructs a `ScriptMetadata` instance by parsing metadata from a specified Groovy script file. + * The constructor initializes the metadata fields such as `id`, `title`, `description`, `executionTimeoutSeconds`, + * and populates the `inputs` and `outputs` maps based on the content of the script. The `id` is generated + * using the provided group and the script file name, while the other fields are extracted from the script's + * metadata or assigned default values if not specified. + * + * @param group a string representing the group or category to which the script belongs, used in generating the script's unique identifier + * @param file a URI pointing to the Groovy script file from which to extract metadata + * @param scriptDirectory a URI representing the directory containing the script, used for mounting a special file system if the script is stored into a jar file + * @throws IOException if an error occurs while reading or parsing the script file for metadata extraction + */ + public ScriptMetadata(String group, URI file, URI scriptDirectory) throws IOException { + this.scriptDirectory = scriptDirectory; + this.group = group; + Map metadata = parseGroovyScriptMetadata(file); + if(metadata.isEmpty()) { + throw new IOException("Not a valid Function"); + } + id = group + ":" + Path.of(file).getFileName().toString().replace(".groovy", ""); + title = metadata.getOrDefault("title", id).toString(); + description = metadata.getOrDefault("description", "").toString(); + executionTimeoutSeconds = (Integer) metadata.getOrDefault("executionTimeout", DEFAULT_JOB_EXECUTION_TIMEOUT_SECONDS); + path = file; + + // Convert metadata inputs into ScriptInput instances + Object inputsValue = metadata.get("inputs"); + if(inputsValue instanceof Map) { + for (Map.Entry input : ((Map) inputsValue).entrySet()) { + ScriptInput si = new ScriptInput(); + si.id = input.getKey().toString(); + if(input.getValue() instanceof Map) { + Map inputAttributes = (Map)input.getValue(); + si.title = inputAttributes.getOrDefault("title", input.getKey()).toString(); + si.description = inputAttributes.getOrDefault("description", "").toString(); + Object attributeType = inputAttributes.get("type"); + if(attributeType instanceof Class) { + si.type = (Class)attributeType; + } + Object minValue = inputAttributes.getOrDefault("min", 1); + si.minOccurs = minValue instanceof Integer ? (Integer)minValue : 1; + Object maxValue = inputAttributes.getOrDefault("max", 1); + si.maxOccurs = maxValue instanceof Integer ? (Integer)maxValue : 1; + si.defaultValue = inputAttributes.getOrDefault("default", null); + // If minOccurs is 0 but no default value is provided + // it means that the input map will not have an entry for this input + if (inputAttributes.containsKey("default")) { + // We can consider that the input is optional as the default value will be used if no value is provided + si.minOccurs = 0; + } + Object allowedValues = inputAttributes.getOrDefault("allowedValues", new HashSet<>()); + if(allowedValues instanceof Collection) { + si.allowedValues = new HashSet<>((Collection)allowedValues); + } + } + inputs.put(si.id, si); + } + } + + Object outputsValue = metadata.get("outputs"); + if(outputsValue instanceof Map) { + for (Map.Entry output : ((Map) outputsValue).entrySet()) { + ScriptOutput scriptOutput = new ScriptOutput(); + scriptOutput.id = output.getKey().toString(); + if(output.getValue() instanceof Map) { + Map outputAttributes = (Map) output.getValue(); + scriptOutput.title = (String) outputAttributes.getOrDefault("title", "no titles"); + scriptOutput.description = outputAttributes.getOrDefault("description", "").toString(); + Object attributeType = outputAttributes.get("type"); + if(attributeType instanceof Class) { + scriptOutput.type = (Class)attributeType; + } + } + outputs.put(scriptOutput.id, scriptOutput); + } + } + } + + /** + * Cast the input content to the expected input type defined in the script metadata. + * + * @param expectedInputType the expected type of the input as defined in the script metadata + * @param inputValue the string input value containing the literal data to be cast + * @return the cast input content if successful, otherwise returns the original input content + * @throws org.locationtech.jts.io.ParseException if there is an error parsing a Geometry input + */ + public static Object castInputUsingExpectedInputType(Class expectedInputType, String inputValue) throws org.locationtech.jts.io.ParseException { + String typeName = expectedInputType.getName(); + if (typeName.equals(Long.class.getName())) { + return Long.parseLong(inputValue); + } else if (typeName.equals(Integer.class.getName())) { + return Integer.parseInt(inputValue); + } else if (typeName.equals(Float.class.getName())) { + return Float.parseFloat(inputValue); + } else if (typeName.equals(Double.class.getName())) { + return Double.parseDouble(inputValue); + } else if (typeName.equals(Boolean.class.getName())) { + return Boolean.parseBoolean(inputValue); + } else if (typeName.equals(Geometry.class.getName())) { + return new org.locationtech.jts.io.WKTReader().read(inputValue); + } + return inputValue; + } + + /** + * Parses metadata from a provided Groovy script file and extracts details such as title, + * description, inputs, and outputs defined within the script. The method analyzes the script + * content to populate a metadata map, which includes blocks of inputs and outputs if defined. + * + * @param scriptFile the Groovy script file to parse for metadata + * @return a map containing metadata fields such as "title", "description", "inputs", and "outputs", + * where "inputs" and "outputs" are themselves maps with their respective properties + * @throws IOException if an error occurs while reading the script file + */ + private static Map parseGroovyScriptMetadata(URI scriptFile) throws IOException { + GroovyShell shell = new GroovyShell(); + Script script = shell.parse(scriptFile); + // Expect at least an exec method + if(script.getMetaClass().getMethods().stream().anyMatch(m -> m.getName().equals("exec"))) { + script.run(); + return script.getBinding().getVariables(); + } else { + return Collections.EMPTY_MAP; + } + } + + +} + diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptOutput.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptOutput.java new file mode 100644 index 000000000..37f979aca --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/ScriptOutput.java @@ -0,0 +1,13 @@ +package org.noise_planet.noisemodelling.webserver.script; + +/** + * Represents an output configuration for a script. + * This class is designed to encapsulate the metadata that defines + * an output of a script, such as its identifier and title. + */ +public class ScriptOutput { + public String id; + public String title; + public String description; + public Class type; +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/WpsScriptWrapper.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/WpsScriptWrapper.java new file mode 100644 index 000000000..60232784d --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/WpsScriptWrapper.java @@ -0,0 +1,200 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + + +package org.noise_planet.noisemodelling.webserver.script; + +import net.opengis.ows11.CodeType; +import net.opengis.ows11.DomainMetadataType; +import net.opengis.ows11.LanguageStringType; +import net.opengis.ows11.Ows11Factory; +import net.opengis.wps10.*; +import org.apache.commons.text.StringEscapeUtils; +import org.geotools.wps.WPSConfiguration; +import org.geotools.xsd.Encoder; +import org.locationtech.jts.geom.Geometry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.math.BigInteger; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.*; +import java.util.*; +import java.util.stream.Stream; + +/** + * The `WpsScriptWrapper` class provides functionalities to manage, organize, and process + * Groovy scripts for use in a Web Processing Service (WPS) environment. It includes methods + * for loading scripts, parsing their metadata, grouping them into categories, and generating + * WPS-compliant XML documents. + * + * The class relies on the directory structure of Groovy script files to organize them into + * groups, and it provides mechanisms for extracting script information, such as inputs, + * outputs, descriptions, and other metadata. These capabilities facilitate the integration + * of scripts into a WPS framework by generating necessary XML representations. + */ +public class WpsScriptWrapper { + + private Logger logger = LoggerFactory.getLogger(WpsScriptWrapper.class); + + /** + * The root directory where Groovy script files are stored and managed. + * This variable represents the base directory from which scripts are loaded, + * grouped, and processed within the WpsScriptWrapper class. + */ + private Path scriptsRoot; + + /** + * Default constructor for the WpsScriptWrapper class. + * + * This constructor initializes the WpsScriptWrapper instance by setting the + * `scriptsRoot` field to point to the default directory containing Groovy + * script files. The directory is resolved relative to the current working + * directory of the application and is expected to exist at: + * "noisemodelling-scripts/src/main/groovy/org/noise_planet/noisemodelling/scripts". + */ + public WpsScriptWrapper(Path scriptDir) { + this.scriptsRoot = scriptDir; + } + + + /** + * Scans a predefined directory structure containing Groovy scripts and organizes them into groups. + *

    + * This method traverses the directory structure rooted at the `scriptsRoot` location recursively. + * It identifies Groovy script files (files ending with the `.groovy` extension), extracts their names + * (excluding the file extension), and groups them into categories based on the directory structure. + * Each group corresponds to a directory path relative to the root directory. + *

    + * If the root directory does not exist or contains no valid files, an empty map is returned. + * + * @return a map where the keys are group names (relative directory paths) and the values are lists + * of script metadata + */ + public static Map scanScriptsGrouped(ClassLoader loader, String scriptDirectoryName) throws IOException { + Map grouped = new TreeMap<>(); + Logger logger = LoggerFactory.getLogger(WpsScriptWrapper.class.getName()); + File baseDir = new File(scriptDirectoryName).getAbsoluteFile(); + logger.info("Scanning scripts in directory: " + baseDir); + if (!baseDir.exists()) { + logger.warn("Directory does not exist {}, will try to use ClassLoader resources package instead..", baseDir); + // The location may be stored into the jar not the local file system + try { + URL resourceUrl = loader.getResource(scriptDirectoryName); + if (resourceUrl == null) { + throw new IOException("Can't find scripts in Jar files using this URL " + loader.getResource(scriptDirectoryName)); + } + URI resourcesScriptUri = resourceUrl.toURI(); + walkUri(grouped, logger, resourcesScriptUri, scriptDirectoryName); + } catch (URISyntaxException | IOException | IllegalArgumentException e) { + logger.warn("Can't find scripts in Jar files using this URL {}.", loader.getResource(scriptDirectoryName), e); + return new TreeMap<>(); + } + } else { + walkUri(grouped, logger, baseDir.toURI(), scriptDirectoryName); + } + int scriptCount = grouped.size(); + if(scriptCount == 0) { + logger.warn("No scripts found in directory/package: {}", scriptDirectoryName); + } else { + logger.info("Found {} scripts in directory/package: {}", scriptCount, scriptDirectoryName); + } + return grouped; + } + + /** + * Walks through the contents of a given URI, which can point to either a directory in the file system or a location within a JAR file, to find and process Groovy script files. + * @param grouped a map to store the metadata of found scripts, where the key is a unique identifier for each script and the value is a ScriptMetadata object containing details about the script + * @param logger a Logger instance for logging information and warnings during the script discovery process + * @param resourcesScriptUri a URI pointing to the location to be scanned for Groovy script files; this can be a file system path or a JAR file path + * @param scriptDirectoryName the name of the script directory being scanned, used for logging purposes and to ensure correct path handling within JAR files + * @throws IOException if an I/O error occurs while accessing the URI or reading script files, or if the URI is malformed and cannot be processed correctly + */ + + public static void walkUri(Map grouped, Logger logger, URI resourcesScriptUri, String scriptDirectoryName) throws IOException { + String scheme = resourcesScriptUri.getScheme(); + + if ("jar".equals(scheme)) { + // --- JAR LOGIC script folder not found, use the Jar file system to read the scripts --- + String uriStr = resourcesScriptUri.toString(); + String[] parts = uriStr.split("!/"); + URI jarUri = URI.create(parts[0]); + String absoluteScriptPath = scriptDirectoryName.startsWith("/") ? scriptDirectoryName : "/" + scriptDirectoryName; + + FileSystem fileSystem = null; + try { + try { + fileSystem = FileSystems.getFileSystem(jarUri); + } catch (FileSystemNotFoundException e) { + fileSystem = FileSystems.newFileSystem(jarUri, Collections.emptyMap()); + } + Path basePath = fileSystem.getPath(absoluteScriptPath); + scanPath(grouped, logger, basePath, resourcesScriptUri); + } finally { + // Keep open if scripts are read lazily, otherwise close. + if (fileSystem != null) { fileSystem.close(); } + } + } else { + // Regular file system logic + // Paths.get(URI) handles "file:/Users/..." correctly + Path basePath = Paths.get(resourcesScriptUri); + scanPath(grouped, logger, basePath, resourcesScriptUri); + } + } + + /** + * Shared logic to walk a Path (regardless of FileSystem type) and extract metadata. + */ + private static void scanPath(Map grouped, Logger logger, Path basePath, URI originUri) throws IOException { + if (!Files.exists(basePath)) { + return; + } + + try (Stream stream = Files.walk(basePath)) { + stream.filter(p -> Files.isRegularFile(p) && p.toString().endsWith(".groovy") && !p.endsWith("package-info.groovy")) + .forEach(p -> { + try { + // Relativize identifies the folder structure inside "scripts" + Path relativePath = basePath.relativize(p); + + // Get parent folder name as the "group" + Path parentPath = relativePath.getParent(); + String group = (parentPath != null) ? parentPath.toString() : ""; + + // Normalize path separators for the Metadata object (always use /) + group = group.replace("\\", "/"); + + ScriptMetadata script = new ScriptMetadata(group, p.toUri(), originUri); + grouped.put(script.id, script); + + logger.debug("Loaded script: {} in group: {}", relativePath, group); + } catch (Exception e) { + logger.warn("Error while loading script metadata for file: {}", p, e); + } + }); + } + } +} + + diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/WpsXmlDocumentGenerator.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/WpsXmlDocumentGenerator.java new file mode 100644 index 000000000..eb6b653bc --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/script/WpsXmlDocumentGenerator.java @@ -0,0 +1,348 @@ +package org.noise_planet.noisemodelling.webserver.script; + + +import net.opengis.ows11.*; +import net.opengis.wps10.*; +import org.geotools.wps.WPSConfiguration; +import org.geotools.xsd.Encoder; +import org.jspecify.annotations.NonNull; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.io.WKTWriter; +import org.noise_planet.noisemodelling.webserver.Configuration; +import org.noise_planet.noisemodelling.webserver.NoiseModellingServer; +import org.noise_planet.noisemodelling.webserver.OwsController; +import org.noise_planet.noisemodelling.webserver.database.DatabaseManagement; +import org.noise_planet.noisemodelling.webserver.utilities.Logging; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.namespace.QName; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.math.BigInteger; +import java.sql.SQLException; +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * A utility class for generating WPS (Web Processing Service) XML documents. + * This class provides methods to construct a DescribeProcess XML for a specific script by + * defining its inputs, outputs, and other metadata. + */ +public class WpsXmlDocumentGenerator { + + private final static Wps10Factory wpsf = Wps10Factory.eINSTANCE; + private final static Ows11Factory owsf = Ows11Factory.eINSTANCE; + private final static Map, String> javaClassToXsdType; + static { + javaClassToXsdType = new HashMap<>(); + javaClassToXsdType.put(String.class, "xs:string"); + javaClassToXsdType.put(Boolean.class, "xs:boolean"); + javaClassToXsdType.put(Integer.class, "xs:int"); + javaClassToXsdType.put(Double.class, "xs:double"); + } + + /** + * Shortcut method to generate wps xml generator string + * @param value String + * @return Instance + */ + private static LanguageStringType languageString(String value) { + LanguageStringType languageStringType = owsf.createLanguageStringType(); + languageStringType.setValue(value); + return languageStringType; + } + + /** + * Parameter identifier + * @param value String + * @return Instance + */ + private static CodeType codetype(String value) { + CodeType codeType = owsf.createCodeType(); + codeType.setValue(value); + return codeType; + } + + /** + * Creates and initializes a {@link DomainMetadataType} instance with the specified name. + * It can be a parameter type (String, number.) + * @param name String + * @return Instance + */ + private static DomainMetadataType domainMetadataType(String name) { + DomainMetadataType domainMetadataType = owsf.createDomainMetadataType(); + domainMetadataType.setValue(name); + return domainMetadataType; + } + + public static ValueType valueType(String value) { + ValueType valueType = owsf.createValueType(); + valueType.setValue(value); + return valueType; + } + + public static void dataInputs(DataInputsType inputs, ScriptInput scriptInput) { + InputDescriptionType input = wpsf.createInputDescriptionType(); + inputs.getInput().add(input); + input.setIdentifier(codetype(scriptInput.id)); + input.setTitle(languageString(scriptInput.title)); + input.setAbstract(languageString(scriptInput.description)); + input.setMaxOccurs(scriptInput.maxOccurs < 0 ? BigInteger.valueOf(Long.MAX_VALUE) : BigInteger.valueOf(scriptInput.maxOccurs)); + input.setMinOccurs(BigInteger.valueOf(scriptInput.minOccurs)); + LiteralInputType literalInputType = wpsf.createLiteralInputType(); + input.setLiteralData(literalInputType); + if (scriptInput.type.equals(Boolean.class)) { + // Special handling for boolean input + literalInputType.setDataType(domainMetadataType("xs:boolean")); + literalInputType.setAllowedValues(owsf.createAllowedValuesType()); + literalInputType.getAllowedValues().getValue().add(valueType("true")); + literalInputType.getAllowedValues().getValue().add(valueType("false")); + } else { + // Set default value + if(scriptInput.defaultValue != null) { + literalInputType.setDefaultValue(scriptInput.defaultValue.toString()); + } + // Generate allowed values + if(!scriptInput.allowedValues.isEmpty()) { + literalInputType.setAllowedValues(owsf.createAllowedValuesType()); + for (String allowedValue : scriptInput.allowedValues) { + literalInputType.getAllowedValues().getValue().add(valueType(allowedValue)); + } + } else { + // If there is restricted values we must not set the data type + literalInputType.setDataType(domainMetadataType(javaClassToXsdType.getOrDefault(scriptInput.type, "xs:string"))); + } + } + } + + public static void processOutputs(ProcessOutputsType outputs, ScriptOutput scriptOutput) { + OutputDescriptionType output = wpsf.createOutputDescriptionType(); + outputs.getOutput().add(output); + output.setIdentifier(codetype(scriptOutput.id)); + output.setTitle(languageString(scriptOutput.title)); + output.setAbstract(languageString(scriptOutput.description)); + if(!scriptOutput.type.equals(Geometry.class)) { + output.setLiteralOutput(wpsf.createLiteralOutputType()); + if(scriptOutput.type.equals(Boolean.class)) { + output.getLiteralOutput().setDataType(domainMetadataType("xs:boolean")); + } else { + output.getLiteralOutput().setDataType(domainMetadataType(javaClassToXsdType.getOrDefault(scriptOutput.type, "xs:string"))); + } + } else { + // Geometry output is converted to WKT + SupportedComplexDataType complex = wpsf.createSupportedComplexDataType(); + output.setComplexOutput(complex); + complex.setSupported(wpsf.createComplexDataCombinationsType()); + ComplexDataDescriptionType ddt = wpsf.createComplexDataDescriptionType(); + ddt.setMimeType("application/wkt"); + complex.getSupported().getFormat().add(ddt); + ComplexDataDescriptionType def = wpsf.createComplexDataDescriptionType(); + def.setMimeType(ddt.getMimeType()); + complex.setDefault(wpsf.createComplexDataCombinationType()); + complex.getDefault().setFormat(def); + } + } + + /** + * Generates a WPS DescribeProcess XML for a specific Groovy script. + * + * @param wrapper the ScriptWrapper representing the script + * @return XML string for WPS DescribeProcess + */ + public static String generateDescribeProcessXML(ScriptMetadata wrapper) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + ProcessDescriptionsType processDescriptionsType = wpsf.createProcessDescriptionsType(); + processDescriptionsType.setLang("en"); + processDescriptionsType.setService("WPS"); + + ProcessDescriptionType processDescriptionType = wpsf.createProcessDescriptionType(); + processDescriptionsType.getProcessDescription().add(processDescriptionType); + processDescriptionType.setIdentifier(codetype(wrapper.id)); + processDescriptionType.setTitle(languageString(wrapper.title)); + processDescriptionType.setAbstract(languageString(wrapper.description)); + processDescriptionType.setProcessVersion("1.0.0"); + processDescriptionType.setStoreSupported(true); // complex data output(s) from this process can be requested to be stored by the WPS server + processDescriptionType.setStatusSupported(true); // support for Asynchronous WPS + DataInputsType dataInputsType = wpsf.createDataInputsType(); + processDescriptionType.setDataInputs(dataInputsType); + for (ScriptInput input : wrapper.inputs.values()) { + dataInputs(dataInputsType, input); + } + processDescriptionType.setProcessOutputs(wpsf.createProcessOutputsType()); + for(ScriptOutput output : wrapper.outputs.values()) { + processOutputs(processDescriptionType.getProcessOutputs(), output); + } + + + Encoder encoder = new Encoder(new WPSConfiguration()); + encoder.encode(processDescriptionsType, new QName("http://www.opengis.net/wps/1.0.0", "ProcessDescriptions"), baos); + return baos.toString(); + } + + + + /** + * Generates a WPS GetCapabilities XML document listing all available scripts. + * + * @param scripts the list of available ScriptWrapper instances + * @return XML string for WPS GetCapabilities + */ + public static String generateCapabilitiesXML(Map scripts) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + WPSCapabilitiesType capabilities = wpsf.createWPSCapabilitiesType(); + capabilities.setService("WPS"); + capabilities.setVersion("1.0.0"); + + ServiceIdentificationType serviceIdentification = owsf.createServiceIdentificationType(); + capabilities.setServiceIdentification(serviceIdentification); + serviceIdentification.getTitle().add(languageString("NoiseModelling WPS")); + serviceIdentification.getAbstract().add(languageString("WPS service of NoiseModelling")); + + CodeType serviceType = codetype("WPS"); + serviceIdentification.setServiceType(serviceType); + serviceIdentification.setServiceTypeVersion ("1.0.0"); + + ProcessOfferingsType processOfferings = wpsf.createProcessOfferingsType(); + capabilities.setProcessOfferings(processOfferings); + + for (ScriptMetadata script : scripts.values()) { + ProcessBriefType process = getProcessBriefType(script); + processOfferings.getProcess().add(process); + } + + Encoder encoder = new Encoder(new WPSConfiguration()); + encoder.encode(capabilities, new QName("http://www.opengis.net/wps/1.0.0", "Capabilities"), baos); + return baos.toString(); + } + + private static @NonNull ProcessBriefType getProcessBriefType(ScriptMetadata script) { + ProcessBriefType process = wpsf.createProcessBriefType(); + process.setProcessVersion("1.0.0"); + process.setIdentifier(codetype(script.id)); + process.setTitle(languageString(script.title)); + process.setAbstract(languageString(script.description)); + return process; + } + + /** + * Generates WPS execute response with status by job state + */ + @SuppressWarnings("unchecked") + public static String generateExecuteResponseDocument(Job job, Map jobData, Configuration webServerConfiguration) + throws IOException, DatatypeConfigurationException, SQLException, ParseException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ExecuteResponseType response = wpsf.createExecuteResponseType(); + response.setLang("en"); + response.setService("WPS"); + if(job != null) { + response.setProcess(getProcessBriefType(job.executionPlan.scriptMetadata)); + } + int jobId = (int) jobData.get("id"); + response.setStatusLocation(webServerConfiguration.getWebSiteFullUrl() + "/builder/jobs/" + jobId); + response.setStatus(wpsf.createStatusType()); + String startDate = jobData.get("startDate").toString(); + // Converts timestamp to XMLGregorianCalendar for standardized serialization + response.getStatus().setCreationTime(DatabaseManagement.dateToXMLGregorianCalendar(startDate)); + // Sets status details by job state + switch (JobStates.valueOf(jobData.get("status").toString())) { + case QUEUED: + response.getStatus().setProcessAccepted(JobStates.QUEUED.name()); + break; + case RUNNING: + response.getStatus().setProcessStarted(wpsf.createProcessStartedType()); + response.getStatus().getProcessStarted().setValue(getLastLoggingLines(webServerConfiguration, jobId)); + // Extracts progression percentage for status encoding + response.getStatus().getProcessStarted().setPercentCompleted(job == null ? BigInteger.valueOf(0) : job.getProgression()); + break; + case COMPLETED: + String output = ""; + if(job != null && job.getExecutionPlan().getOutputs() != null) { + output = castJobOutputToString(job.getExecutionPlan().getOutputs()); + } + // Fetch logs output for this job and attach to response (up to a maximum number of lines) + String lastLines = getLastLoggingLines(webServerConfiguration, jobId); + response.getStatus().setProcessSucceeded(lastLines); + // Copy the wps outputs if available + response.setProcessOutputs(wpsf.createProcessOutputsType1()); + OutputDataType outputDataType = wpsf.createOutputDataType(); + outputDataType.setIdentifier(codetype("result")); + DataType data = wpsf.createDataType(); + if(job != null) { + outputDataType.setTitle(languageString(job.getExecutionPlan().scriptMetadata.title)); + // If the output is a Geometry it is a complex output, otherwise it is a literal output + if(job.getExecutionPlan().getOutputs() != null && job.getExecutionPlan().getOutputs() instanceof Geometry) { + ComplexDataType complexDataType = wpsf.createComplexDataType(); + complexDataType.setMimeType("application/wkt"); + complexDataType.getData().add(output); + data.setComplexData(complexDataType); + } else { + LiteralDataType literalDataType = wpsf.createLiteralDataType(); + literalDataType.setValue(output); + data.setLiteralData(literalDataType); + } + } + outputDataType.setData(data); + response.getProcessOutputs().getOutput().add(outputDataType); + break; + case CANCELED: + case FAILED: + response.getStatus().setProcessFailed(wpsf.createProcessFailedType()); + // Attaches exception report to failed process status; generates default if absent + if(job != null && job.getJobException() != null) { + response.getStatus().getProcessFailed().setExceptionReport(generateExceptionDocument(job.getJobException())); + } else { + response.getStatus().getProcessFailed().setExceptionReport(owsf.createExceptionReportType()); + } + break; + } + Encoder encoder = new Encoder(new WPSConfiguration()); + encoder.encode(response, new QName("http://www.opengis.net/wps/1.0.0", "ExecuteResponse"), baos); + return baos.toString(); + + } + + public static @NonNull String getLastLoggingLines(Configuration webServerConfiguration, int jobId) throws IOException { + String lastLines = ""; + File logFile = new File(webServerConfiguration.getWorkingDirectory(), + NoiseModellingServer.LOGGING_FILE_NAME); + if(logFile.exists()) { + lastLines = Logging.getLastLines(logFile, OwsController.MAXIMUM_LINES_TO_FETCH, + Job.getThreadName(jobId), new AtomicInteger()); + } + return lastLines; + } + + public static String castJobOutputToString(Object output) { + if(output instanceof Map && ((Map) output).size() == 1) { + // Take first key if this is a map [result: "my result"} + castJobOutputToString(((Map) output).values().iterator().next()); + } else if(output instanceof Geometry) { + // Convert Geometry to WKT + WKTWriter wktWriter = new WKTWriter(2); + return wktWriter.write((Geometry) output); + } + return output.toString(); + } + + /** + * Generates an exception report from stack trace details + * @return Exception report + */ + public static ExceptionReportType generateExceptionDocument(Exception ex) { + ExceptionType e = owsf.createExceptionType(); + e.setExceptionCode(ex.getMessage()); + e.setLocator(ex.getClass().getName()); + for (StackTraceElement traceElement : ex.getStackTrace()) { + e.getExceptionText().add(traceElement.toString()); + } + ExceptionReportType report = Ows11Factory.eINSTANCE.createExceptionReportType(); + report.setVersion("2.0"); + report.getException().add(e); + return report; + } +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/Auth.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/Auth.java new file mode 100644 index 000000000..0cb08a037 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/Auth.java @@ -0,0 +1,102 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.secure; + +import io.javalin.http.Context; +import io.javalin.http.UnauthorizedResponse; +import org.noise_planet.noisemodelling.webserver.Configuration; +import org.noise_planet.noisemodelling.webserver.UserController; +import org.noise_planet.noisemodelling.webserver.database.DatabaseManagement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; + +/** + * Handle auth + */ +public class Auth { + JWTProvider provider; + DataSource serverDataSource; + Configuration configuration; + Logger logger = LoggerFactory.getLogger(Auth.class); + + public Auth(JWTProvider provider, DataSource serverDataSource, Configuration configuration) { + this.provider = provider; + this.serverDataSource = serverDataSource; + this.configuration = configuration; + } + + /** + * + * @param ctx Javalin Web context + * @param serverDataSource server database connection + * @return User or null if not connected + * @throws SQLException JDBC exception + */ + public static User getUserFromContext(Context ctx, DataSource serverDataSource, + JWTProvider provider) throws SQLException { + int userId = JavalinJWT.getUserIdentifierFromContext(ctx, provider); + if(userId > 0) { + return DatabaseManagement.getUser(serverDataSource, userId); + } + return null; + } + + /** + * Check visitor credentials using Json Web Token. + * Redirect user if non-authorized to the login page + * @param ctx Javalin Web context + */ + public void handleAccess(Context ctx) { + var permittedRoles = ctx.routeRoles(); + if(configuration.isUnsecure()) { + ctx.attribute("user", new User(1, DatabaseManagement.ADMIN_EMAIL, + new HashSet<>(Arrays.asList(Role.values())), "")); + return; // anyone can access + } + if (permittedRoles.contains(Role.ANYONE)) { + return; // anyone can access + } + // Read visitor token + int userIdentifier = JavalinJWT.getUserIdentifierFromContext(ctx, provider); + if(userIdentifier >= 0) { + try { + User user = DatabaseManagement.getUser(serverDataSource, userIdentifier); + if(!user.registerToken.isEmpty()) { + // The administrator has reset the TOTP code + // User must validate the new TOTP code to be able to log in + ctx.attribute("messages", + String.format("Unauthorized access please login before proceeding", + ctx.contextPath()+"/login")); + throw new UnauthorizedResponse(); + } + if (user.roles.stream().noneMatch(permittedRoles::contains)) { + ctx.attribute("messages", "You do not have the minimal authorization access to see this page"); + throw new UnauthorizedResponse(); + } + // Give access to the user to thymeleaf and controllers + ctx.attribute("user", user); + } catch (SQLException e) { + ctx.attribute("messages", "Exception while authenticating the user"); + throw new UnauthorizedResponse(); + } + } else { + ctx.attribute("messages", + String.format("Unauthorized access please login before proceeding", + ctx.contextPath()+"/login")); + throw new UnauthorizedResponse(); + } + } +} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTAccessManager.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTAccessManager.java new file mode 100644 index 000000000..9f8f01a68 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTAccessManager.java @@ -0,0 +1,56 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.secure; + +import com.auth0.jwt.interfaces.DecodedJWT; +import io.javalin.http.Context; +import io.javalin.http.Handler; +import io.javalin.http.UnauthorizedResponse; +import io.javalin.security.RouteRole; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +/** + * Derived from + * ... + */ +public class JWTAccessManager implements Handler { + private final String userRoleClaim; + private final Map rolesMapping; + private final RouteRole defaultRole; + + public JWTAccessManager(String userRoleClaim, Map rolesMapping, RouteRole defaultRole) { + this.userRoleClaim = userRoleClaim; + this.rolesMapping = rolesMapping; + this.defaultRole = defaultRole; + } + + private RouteRole extractRole(Context context) { + if (!JavalinJWT.containsJWT(context)) { + return defaultRole; + } + + DecodedJWT jwt = JavalinJWT.getDecodedFromContext(context); + String userLevel = jwt.getClaim(userRoleClaim).asString(); + + return Optional.ofNullable(rolesMapping.get(userLevel)).orElse(defaultRole); + } + + @Override + public void handle(@NotNull Context context) { + RouteRole role = extractRole(context); + Set permittedRoles = context.routeRoles(); + if (!permittedRoles.contains(role)) { + throw new UnauthorizedResponse(); + } + } +} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTGenerator.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTGenerator.java new file mode 100644 index 000000000..5923d9df8 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTGenerator.java @@ -0,0 +1,20 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.secure; + +import com.auth0.jwt.algorithms.Algorithm; + +/** + * Derived from + * javalin-jwt + */ +@FunctionalInterface +public interface JWTGenerator { + String generate(T obj, Algorithm algorithm); +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTProvider.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTProvider.java new file mode 100644 index 000000000..e70751621 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTProvider.java @@ -0,0 +1,44 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.secure; + +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.interfaces.DecodedJWT; + +import java.util.Optional; + +/** + * Derived from + * ... + */ +public class JWTProvider { + private final Algorithm algorithm; + private final JWTGenerator generator; + private final JWTVerifier verifier; + + public JWTProvider(Algorithm algorithm, JWTGenerator generator, JWTVerifier verifier) { + this.algorithm = algorithm; + this.generator = generator; + this.verifier = verifier; + } + + public String generateToken(T obj) { + return generator.generate(obj, algorithm); + } + + public Optional validateToken(String token) { + try { + return Optional.of(verifier.verify(token)); + } catch (JWTVerificationException ex) { + return Optional.empty(); + } + } +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTProviderFactory.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTProviderFactory.java new file mode 100644 index 000000000..33528d68b --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JWTProviderFactory.java @@ -0,0 +1,58 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.secure; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTCreator; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; + +import java.security.SecureRandom; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Base64; + +/** + * Generator of Json Web Token used when a user as validated its identity with another method + * Java Web Token will manage the identification process for each secure web page + */ +public class JWTProviderFactory { + + /** + * @return Random secret token + */ + public static String generateServerSecretToken() { + SecureRandom secureRandom = new SecureRandom(); + byte[] keyBytes = new byte[32]; // 256-bit key for HS256 + secureRandom.nextBytes(keyBytes); + return Base64.getUrlEncoder().withoutPadding().encodeToString(keyBytes); + } + + /** + * Create the instance of the generator of Json Web Token + * @param serverSecretToken Private static signature key of the server + * @return instance of the generator + */ + public static JWTProvider createHMAC512(String serverSecretToken) { + JWTGenerator generator = (user, alg) -> { + JWTCreator.Builder token = JWT.create() + .withClaim("user_identifier", user.identifier) + .withIssuer("NoiseModelling") + .withIssuedAt(Instant.now()) + .withExpiresAt(Instant.now().plus(7, ChronoUnit.DAYS)); + return token.sign(alg); + }; + + Algorithm algorithm = Algorithm.HMAC256(serverSecretToken); + JWTVerifier verifier = JWT.require(algorithm).build(); + + return new JWTProvider<>(algorithm, generator, verifier); + } + +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JavalinJWT.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JavalinJWT.java new file mode 100644 index 000000000..e385efac3 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/JavalinJWT.java @@ -0,0 +1,96 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.secure; + +import com.auth0.jwt.interfaces.DecodedJWT; +import io.javalin.http.Handler; +import io.javalin.http.Context; +import io.javalin.http.InternalServerErrorResponse; + +import java.util.Optional; + +/** + * Derived from + * ... + */ +public class JavalinJWT { + + private final static String CONTEXT_ATTRIBUTE = "jwt"; + private final static String COOKIE_KEY = "jwt"; + + + public static boolean containsJWT(Context context) { + return context.attribute(CONTEXT_ATTRIBUTE) != null; + } + + public static Context addDecodedToContext(Context context, DecodedJWT jwt) { + context.attribute(CONTEXT_ATTRIBUTE, jwt); + return context; + } + + public static DecodedJWT getDecodedFromContext(Context context) { + Object attribute = context.attribute(CONTEXT_ATTRIBUTE); + + if (!(attribute instanceof DecodedJWT)) { + throw new InternalServerErrorResponse("The context carried invalid object as JavalinJWT"); + } + + return (DecodedJWT) attribute; + } + + public static Optional getTokenFromHeader(Context context) { + return Optional.ofNullable(context.header("Authorization")) + .flatMap(header -> { + String[] split = header.split(" "); + if (split.length != 2 || !split[0].equals("Bearer")) { + return Optional.empty(); + } + + return Optional.of(split[1]); + }); + } + + public static Optional getTokenFromCookie(Context context) { + return Optional.ofNullable(context.cookie(COOKIE_KEY)); + } + + public static Context addTokenToCookie(Context context, String token) { + return context.cookie(COOKIE_KEY, token); + } + + public static Handler createHeaderDecodeHandler(JWTProvider jwtProvider) { + return context -> getTokenFromHeader(context) + .flatMap(jwtProvider::validateToken) + .ifPresent(jwt -> JavalinJWT.addDecodedToContext(context, jwt)); + } + + public static Handler createCookieDecodeHandler(JWTProvider jwtProvider) { + return context -> getTokenFromCookie(context) + .flatMap(jwtProvider::validateToken) + .ifPresent(jwt -> JavalinJWT.addDecodedToContext(context, jwt)); + } + + + /** + * Return the user identifier from the web context (extracted from verified Json Web Token) + * @param ctx Web context + * @param provider Json Web Token verifier + * @return User identifier or -1 if token is invalid + */ + public static int getUserIdentifierFromContext(Context ctx, JWTProvider provider) { + // Read visitor token + Optional decodedJWT = JavalinJWT.getTokenFromCookie(ctx) + .flatMap(provider::validateToken); + if(decodedJWT.isPresent()) { + return decodedJWT.get().getClaim("user_identifier").asInt(); + } else { + return -1; + } + } +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/Role.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/Role.java new file mode 100644 index 000000000..9292fe7d7 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/Role.java @@ -0,0 +1,21 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + + +package org.noise_planet.noisemodelling.webserver.secure; + +import io.javalin.security.RouteRole; + +public enum Role implements RouteRole { + /** Non registered user */ + ANYONE, + /** Can launch/cancel its own job */ + RUNNER, + /** Can add/remove users, see cancel any jobs */ + ADMINISTRATOR} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/User.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/User.java new file mode 100644 index 000000000..e3ba2f54b --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/secure/User.java @@ -0,0 +1,68 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + + +package org.noise_planet.noisemodelling.webserver.secure; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Set; + +public class User { + + public User(int identifier, String email, Set roles, String registerToken) { + this.identifier = identifier; + this.email = email; + this.roles = roles; + this.registerToken = registerToken; + } + + /** Database identifier for this user */ + int identifier; + /** User email or name */ + String email; + /** User roles/rights */ + Set roles; + /** User register link token, user cannot be authenticated if it is not empty */ + String registerToken; + + public String getRegisterToken() { + return registerToken; + } + + public Set getRoles() { + return roles; + } + + public String getEmail() { + return email; + } + + public int getIdentifier() { + return identifier; + } + + public boolean isAdministrator() { + return roles.contains(Role.ADMINISTRATOR); + } + + public String getRegisterUrl(String proxyBaseUrl) { + if(registerToken.isEmpty()) + return ""; + return getRegisterUrl(proxyBaseUrl, + getRegisterToken()); + } + public static String getRegisterUrl(String proxyBaseUrl, String registerToken) { + return String.format("%s/register/%s", + proxyBaseUrl, + URLEncoder.encode(registerToken, StandardCharsets.UTF_8)); + } +} + diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/FileUtilities.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/FileUtilities.java new file mode 100644 index 000000000..9cb58e356 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/FileUtilities.java @@ -0,0 +1,140 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.utilities; + +import com.fasterxml.jackson.core.*; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +public class FileUtilities { + + + /** + * Merge GeoJSON files + * @param inputFiles Input files to merge + * @param outputFile Merged output file destination + * @throws IOException If an I/O error occurs + */ + public static void mergeGeoJSONFiles(List inputFiles, File outputFile) throws IOException { + JsonFactory factory = new JsonFactory(); + + // Merges multiple GeoJSON files into a single FeatureCollection preserving first CRS + try (FileOutputStream os = new FileOutputStream(outputFile); + JsonGenerator gen = factory.createGenerator(os, JsonEncoding.UTF8)) { + + gen.writeStartObject(); + gen.writeStringField("type", "FeatureCollection"); + + boolean featuresArrayStarted = false; + + for (int i = 0; i < inputFiles.size(); i++) { + String fileName = inputFiles.get(i); + File f = new File(fileName); + + if (!f.exists()) { + continue; + } + + // try-with-resources for the parser of each file + try (JsonParser parser = factory.createParser(f)) { + while (parser.nextToken() != null) { + String fieldName = parser.currentName(); + + // 1. Capture CRS only from the FIRST file + if (i == 0 && "crs".equals(fieldName)) { + gen.writeFieldName("crs"); + parser.nextToken(); // Move to the start of the CRS object + gen.copyCurrentStructure(parser); + } + + // 2. Handle the "features" array + else if ("features".equals(fieldName) && parser.currentToken() == JsonToken.START_ARRAY) { + // If this is the first file we are processing, open the global features array + if (!featuresArrayStarted) { + gen.writeArrayFieldStart("features"); + featuresArrayStarted = true; + } + + // Stream every feature object from the current file into the output + while (parser.nextToken() != JsonToken.END_ARRAY) { + gen.copyCurrentStructure(parser); + } + // Stop parsing this file once we finish its features array + break; + } + } + } + } + + // Close the features array and the root object + if (featuresArrayStarted) { + gen.writeEndArray(); + } else { + // Fallback if no features were ever found + gen.writeArrayFieldStart("features"); + gen.writeEndArray(); + } + + gen.writeEndObject(); + } + } + + + /** + * Collects library information from ClassLoader manifests. + */ + public static List collectLibraryIdentifiers() { + List libraries = new ArrayList<>(); + SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.getDefault()); + + try { + Enumeration resources = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF"); + + while (resources.hasMoreElements()) { + try (var inputStream = resources.nextElement().openStream()) { + Manifest manifest = new Manifest(inputStream); + Attributes attributes = manifest.getMainAttributes(); + + String bundleName = attributes.getValue("Bundle-Name"); + if (bundleName != null) { + String version = attributes.getValue("Bundle-Version"); + String commit = attributes.getValue("Implementation-Build"); + String lastModRaw = attributes.getValue("Bnd-LastModified"); + + String formattedDate = null; + if (lastModRaw != null) { + try { + formattedDate = sdf.format(new Date(Long.parseLong(lastModRaw))); + } catch (NumberFormatException ignored) {} + } + + libraries.add(new LibraryInfo(bundleName, formattedDate, version, commit, + lastModRaw == null ? 0 : Long.parseLong(lastModRaw))); + } + } catch (IOException e) { + // Log internally or skip individual failed manifest reads + } + } + } catch (IOException e) { + // Error finding resources + } + + // Sort by name + libraries.sort(Comparator.comparing(LibraryInfo::getName)); + return libraries; + } +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/LibraryInfo.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/LibraryInfo.java new file mode 100644 index 000000000..20bdc86ed --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/LibraryInfo.java @@ -0,0 +1,37 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and + * education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE + * provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.utilities; + +/** + * Represents information about a library, including its name, + * last modified date, version, and commit hash. + */ +public class LibraryInfo { + private final String name; + private final String lastModified; + private final String version; + private final String commit; + private final long lastModifiedTimeStamp; + + public LibraryInfo(String name, String lastModified, String version, String commit, long lastModifiedTimeStamp) { + this.name = name != null ? name : "Unknown"; + this.lastModified = lastModified != null ? lastModified : " - "; + this.version = version != null ? version : " - "; + this.commit = commit != null ? commit : " - "; + this.lastModifiedTimeStamp = lastModifiedTimeStamp; + } + + public String getName() { return name; } + public String getLastModified() { return lastModified; } + public String getVersion() { return version; } + public String getCommit() { return commit; } + public long getLastModifiedTimeStamp() { return lastModifiedTimeStamp; } +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/Logging.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/Logging.java new file mode 100644 index 000000000..802ea544c --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/Logging.java @@ -0,0 +1,432 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + +package org.noise_planet.noisemodelling.webserver.utilities; + +import org.apache.log4j.Appender; +import org.apache.log4j.PatternLayout; +import org.apache.log4j.RollingFileAppender; +import org.jetbrains.annotations.NotNull; +import groovy.sql.Sql; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Utility functions related to logging features + */ +public class Logging { + + public static final String DEFAULT_LOG_FORMAT = "[%t][%c{1}] %-5p %d{dd MMM HH:mm:ss} - %m%n"; + public static final Pattern LOG_PATTERN = + Pattern.compile("^\\[(?.+?)\\]\\[(?[^\\]]+)\\]"); + public static final String LINE_SEPARATOR = System.lineSeparator(); + + + public static void initConsoleLogging() { + // Reset everything to clear hidden configs from JARs + org.apache.log4j.LogManager.resetConfiguration(); + + org.apache.log4j.Logger rootLogger = org.apache.log4j.Logger.getRootLogger(); + rootLogger.setLevel(org.apache.log4j.Level.INFO); + + // Create the Console Appender + org.apache.log4j.ConsoleAppender console = new org.apache.log4j.ConsoleAppender(); + console.setName("stdout"); + console.setLayout(new org.apache.log4j.PatternLayout(DEFAULT_LOG_FORMAT)); + console.setThreshold(org.apache.log4j.Level.INFO); + console.activateOptions(); + rootLogger.addAppender(console); + } + + public static void configureLoggerFromWorkingDirectory(String workingDirectory, String loggingFileName, boolean verbose) { + final org.apache.log4j.Logger rootLogger = org.apache.log4j.Logger.getRootLogger(); + + // Check if there is a log4j configuration file in the working directory + File log4jConfigFile = new File(workingDirectory, "log4j.properties"); + if (log4jConfigFile.exists()) { + // Replace our current configuration with the one from the file + org.apache.log4j.PropertyConfigurator.configure(log4jConfigFile.getAbsolutePath()); + if(verbose) { + rootLogger.info("Logger initialized successfully from configuration file: " + log4jConfigFile.getAbsolutePath()); + } + } else { + if(verbose) { + System.out.println("No log4j.properties found in working directory." + " Initializing default logger " + + "configuration."); + System.out.println("You can place a log4j.properties file in the working directory to customize " + + "logging behavior."); + } + try { + // Create rolling file appender + RollingFileAppender rollingAppender = createRollingFileAppender(workingDirectory, loggingFileName); + + if (rollingAppender.getLayout() == null) { + rollingAppender.setLayout(new org.apache.log4j.PatternLayout(DEFAULT_LOG_FORMAT)); + } + rollingAppender.setImmediateFlush(true); + + rollingAppender.setThreshold(org.apache.log4j.Level.TRACE); + + // init stream + rollingAppender.activateOptions(); + + // Configure root logger + rootLogger.addAppender(rollingAppender); + + rootLogger.info("Logger initialized successfully at: " + new File(workingDirectory, loggingFileName).getAbsolutePath()); + + } catch (Exception e) { + System.err.println("Failed to configure logger: " + e.getMessage()); + } + } + + if(verbose) { + System.out.println("--- LOGGING DIAGNOSTIC ---"); + System.out.println("Root Logger Class: " + rootLogger.getClass().getName()); + System.out.println("Root Logger Level: " + rootLogger.getLevel()); + + Enumeration appenders = rootLogger.getAllAppenders(); + if (!appenders.hasMoreElements()) { + System.out.println("!!! ERROR: No appenders attached to Root Logger !!!"); + } else { + while (appenders.hasMoreElements()) { + Appender app = (Appender) appenders.nextElement(); + System.out.println("Appender: " + app.getName() + " [" + app.getClass().getSimpleName() + "]"); + } + } + System.out.println("--------------------------"); + } + } + + public static void clearAppenders() { + org.apache.log4j.Logger rootLogger = org.apache.log4j.Logger.getRootLogger(); + // Close file appenders to release file locks + Enumeration appenders = rootLogger.getAllAppenders(); + while (appenders.hasMoreElements()) { + Appender app = (Appender) appenders.nextElement(); + if (app instanceof RollingFileAppender) { + app.close(); + } + } + // Remove all appenders to reset logger state + rootLogger.removeAllAppenders(); + } + + @NotNull + public static RollingFileAppender createRollingFileAppender(String workingDirectory, String loggingFileName) { + RollingFileAppender rollingAppender = new RollingFileAppender(); + + // Configure appender properties + rollingAppender.setName("rollingFile"); + rollingAppender.setFile(new File(workingDirectory, loggingFileName).getPath()); + rollingAppender.setAppend(true); + rollingAppender.setMaxBackupIndex(5); + rollingAppender.setMaximumFileSize(10_000_000); + + // Create and set a pattern layout + PatternLayout layout = new PatternLayout(DEFAULT_LOG_FORMAT); + rollingAppender.setLayout(layout); + return rollingAppender; + } + + /** + * Build an HTML-friendly stack trace string similar to what SLF4J would print, + * including the exception type, message, stack frames, causes, and suppressed exceptions. + */ + public static String formatThrowableAsHtml(Throwable throwable) { + if (throwable == null) return ""; + StringBuilder sb = new StringBuilder(); + + // Detect circular references + java.util.IdentityHashMap seen = new java.util.IdentityHashMap<>(); + + Throwable t = throwable; + String prefix = ""; + while (t != null && !seen.containsKey(t)) { + seen.put(t, Boolean.TRUE); + + // Exception header (class: message) + String header = t.getClass().getName(); + String msg = t.getMessage(); + if (msg != null && !msg.isEmpty()) { + header += ": " + msg; + } + sb.append(StringUtilities.escapeHtml(prefix + header)).append("
    "); + + // Stack frames + for (StackTraceElement el : t.getStackTrace()) { + sb.append(StringUtilities.escapeHtml(prefix + "\tat " + el)).append("
    "); + } + + // Suppressed exceptions + for (Throwable sup : t.getSuppressed()) { + appendSuppressed(sb, sup, seen, prefix + "\t"); + } + + // Move to cause + t = t.getCause(); + if (t != null && !seen.containsKey(t)) { + sb.append(StringUtilities.escapeHtml(prefix + "Caused by: ")).append("
    "); + } + } + + return sb.toString(); + } + + public static void appendSuppressed(StringBuilder sb, Throwable sup, java.util.IdentityHashMap seen, String prefix) { + if (sup == null || seen.containsKey(sup)) return; + seen.put(sup, Boolean.TRUE); + + String header = sup.getClass().getName(); + String msg = sup.getMessage(); + if (msg != null && !msg.isEmpty()) { + header += ": " + msg; + } + sb.append(StringUtilities.escapeHtml(prefix + "Suppressed: " + header)).append("
    "); + for (StackTraceElement el : sup.getStackTrace()) { + sb.append(StringUtilities.escapeHtml(prefix + "\tat " + el)).append("
    "); + } + for (Throwable nested : sup.getSuppressed()) { + appendSuppressed(sb, nested, seen, prefix + "\t"); + } + if (sup.getCause() != null) { + sb.append(StringUtilities.escapeHtml(prefix + "Caused by: ")).append("
    "); + appendSuppressed(sb, sup.getCause(), seen, prefix + "\t"); + } + } + + + /** + * Return lines from the most recent to the old ones + * @param jobId + * @param numberOfLines + * @return + * @throws IOException + */ + public static String getAllLines(String jobId, File loggingFile, int numberOfLines) throws IOException { + List logFiles = new ArrayList<>(); + logFiles.add(loggingFile); + int logCounter = 1; + // Add rotating log files + while(true) { + File oldLogFile = new File(loggingFile + "." + (logCounter++)); + if(oldLogFile.exists()) { + logFiles.add(oldLogFile); + } else { + break; + } + } + StringBuilder rows = new StringBuilder(); + AtomicInteger fetchLines = new AtomicInteger(0); + for(File logFile : logFiles) { + rows.append(getLastLines(logFile, + numberOfLines == -1 ? -1 : numberOfLines - fetchLines.get(), + String.format("JOB_%s", jobId), fetchLines)); + if(numberOfLines != -1 && fetchLines.get() >= numberOfLines) { + break; + } + } + return rows.toString(); + } + + /** + * Equivalent to "tail -n x file" linux command. + * Retrieve the n last lines from a file but from the most recent to the oldest one. + * @param logFile + * @param maximumLinesToFetch + * @return + * @throws IOException + */ + public static String getLastLines(File logFile, int maximumLinesToFetch, String jobId, AtomicInteger fetchedLines) throws IOException { + AtomicInteger pushedLines = new AtomicInteger(); + StringBuilder sbMatch = new StringBuilder(); + final int buffer = 8192; + long read = 0; + String tailCache = ""; + int lastEndOfLine=0; + try(RandomAccessFile f = new RandomAccessFile(logFile.getAbsoluteFile(), "r")) { + long fileSize = f.length(); + long lastCursor = fileSize; + while((maximumLinesToFetch == -1 || pushedLines.get() < maximumLinesToFetch) && read < fileSize) { + long cursor = Math.max(0, fileSize - read - buffer); + read += buffer; + f.seek(cursor); + byte[] b = new byte[(int)(lastCursor - cursor)]; + f.readFully(b); + lastCursor = cursor; + String remainingLines = ""; + if(!tailCache.isEmpty() && lastEndOfLine > 0) { + remainingLines = tailCache.substring(0, Math.min(tailCache.length(), lastEndOfLine + 1)); + } + tailCache = new String(b, StandardCharsets.UTF_8); + if(!remainingLines.isEmpty()) { + tailCache = tailCache + remainingLines; + } + int previousHookLocation = tailCache.length(); + // Reverse search of end of line into the string buffer + lastEndOfLine = tailCache.lastIndexOf(LINE_SEPARATOR); + while (lastEndOfLine != -1 && (maximumLinesToFetch == -1 || pushedLines.get() < maximumLinesToFetch)) { + int nextEndOfLine = tailCache.lastIndexOf(LINE_SEPARATOR, Math.max(0, lastEndOfLine - 1)); + if(nextEndOfLine <= 0) { + break; + } + String line = tailCache.substring(nextEndOfLine + LINE_SEPARATOR.length(), lastEndOfLine); + if(!jobId.isEmpty()) { + Matcher matcher = LOG_PATTERN.matcher(line); + if (matcher.find()) { + String threadName = matcher.group("thread"); + String loggerName = matcher.group("logger"); + if((threadName.equals(jobId) || loggerName.equals(jobId)) && lastEndOfLine < previousHookLocation) { + // push other lines of this log + String logLines = tailCache.substring(nextEndOfLine + LINE_SEPARATOR.length(), previousHookLocation); + logLines.lines().forEach(s -> { + pushedLines.getAndIncrement(); + sbMatch.append(s); + sbMatch.append(LINE_SEPARATOR); + }); + } + previousHookLocation = nextEndOfLine + 1; + } + } else { + sbMatch.append(line); + sbMatch.append(LINE_SEPARATOR); + pushedLines.getAndIncrement(); + } + lastEndOfLine = nextEndOfLine; + } + } + } + fetchedLines.addAndGet(pushedLines.get()); + return sbMatch.toString(); + } + + + /** + * Executes a SQL query and return the result set as an ASCII table. + * + * @param sql An instance of groovy.sql.Sql + * @param query A String or GString (allows for parameter injection) + */ + public static String formatSqlQueryResult(Sql sql, Object query) { + return formatSqlQueryResult(sql, query, 30); + } + + /** + * Executes a SQL query and return the result set as an ASCII table. + * + * @param sql An instance of groovy.sql.Sql + * @param query A String or GString (allows for parameter injection) + * @param maxColWidth Maximum width of a column before truncation + */ + public static String formatSqlQueryResult(Sql sql, Object query, int maxColWidth) { + List> rawRows = new ArrayList<>(); + try { + List rows = sql.rows(query.toString()); + for (Object row : rows) { + if (row instanceof Map) { + rawRows.add((Map) row); + } + } + } catch (Exception e) { + LoggerFactory.getLogger(Logging.class).error("Error executing SQL query: {}", query, e); + return ""; + } + + if (rawRows.isEmpty()) { + return String.format("Query returned 0 rows.\nSQL: %s", query); + } + + List columnNames = new ArrayList<>(); + for (Object key : rawRows.get(0).keySet()) { + columnNames.add(key.toString()); + } + + // 1. Pre-format all data (Truncate strings and Round numbers) + List> formattedRows = new ArrayList<>(); + for (Map row : rawRows) { + Map formattedRow = new LinkedHashMap<>(); + for (String col : columnNames) { + Object val = row.get(col); + String formattedVal; + + if (val == null) { + formattedVal = "null"; + } else if (val instanceof Number && !(val instanceof Integer || val instanceof Long || val instanceof BigInteger)) { + // Round numbers to 2 decimal places + formattedVal = String.format(Locale.US, "%.2f", ((Number) val).doubleValue()); + } else { + // Truncate long strings (like Geometries) + formattedVal = val.toString(); + if (formattedVal.length() > maxColWidth) { + formattedVal = formattedVal.substring(0, maxColWidth - 3) + "..."; + } + } + formattedRow.put(col, formattedVal); + } + formattedRows.add(formattedRow); + } + + // 2. Calculate column widths based on formatted data + Map columnWidths = new HashMap<>(); + for (String col : columnNames) { + int headerLen = col.length(); + int maxDataLen = 0; + for (Map row : formattedRows) { + String val = row.get(col); + if (val != null) { + maxDataLen = Math.max(maxDataLen, val.length()); + } + } + columnWidths.put(col, Math.max(headerLen, maxDataLen)); + } + + // 3. Build the ASCII Table + StringBuilder lineSeparatorBuilder = new StringBuilder("+"); + for (String col : columnNames) { + int width = columnWidths.get(col); + lineSeparatorBuilder.append("-".repeat(Math.max(0, width + 2))); + lineSeparatorBuilder.append("+"); + } + String lineSeparator = lineSeparatorBuilder.toString(); + + StringBuilder table = new StringBuilder(); + table.append("\nSQL: ").append(query).append("\n"); + table.append(lineSeparator).append("\n|"); + + // Header + for (String col : columnNames) { + int width = columnWidths.get(col); + table.append(String.format(" %-" + width + "s |", col)); + } + table.append("\n").append(lineSeparator).append("\n"); + + // Rows + for (Map row : formattedRows) { + table.append("|"); + for (String col : columnNames) { + int width = columnWidths.get(col); + table.append(String.format(" %-" + width + "s |", row.get(col))); + } + table.append("\n"); + } + table.append(lineSeparator); + + return table.toString(); + } + +} diff --git a/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/PgPassUtilities.java b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/PgPassUtilities.java new file mode 100644 index 000000000..ec8551ef1 --- /dev/null +++ b/noisemodelling-scripts/src/main/java/org/noise_planet/noisemodelling/webserver/utilities/PgPassUtilities.java @@ -0,0 +1,117 @@ + +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and + * education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE + * provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.utilities; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Path; + +/** + * Utility class to handle PostgreSQL .pgpass file. + * See PostGIS help + */ +public class PgPassUtilities { + + public static final String PGPASS_FILENAME = ".pgpass"; + + /** + * Represents a line in the .pgpass file. + */ + public static class PgPassEntry { + public final String hostname; + public final String port; + public final String database; + public final String username; + public final String password; + + public PgPassEntry(String hostname, String port, String database, String username, String password) { + this.hostname = hostname; + this.port = port; + this.database = database; + this.username = username; + this.password = password; + } + } + + /** + * Fetch credentials from a specific file. + * See PostGIS help page + * @param pgPassFile The file to read + * @param hostname Hostname to match + * @param database Database name to match + * @return PgPassEntry if found, null otherwise + */ + public static PgPassEntry getCredentials(File pgPassFile, String hostname, String port, String database, String username) { + if (pgPassFile == null || !pgPassFile.exists() || !pgPassFile.canRead()) { + return null; + } + + try (BufferedReader br = new BufferedReader(new FileReader(pgPassFile))) { + String line; + while ((line = br.readLine()) != null) { + line = line.trim(); + if (line.isEmpty() || line.startsWith("#")) { + continue; + } + String[] parts = line.split("(? + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ +package org.noise_planet.noisemodelling.webserver.utilities; + + +import org.apache.commons.text.StringEscapeUtils; + +import java.time.Duration; +import java.util.Locale; + +public class StringUtilities { + + public static final int DURATION_DAYS = 0, DURATION_HOURS = 1, DURATION_MINUTES = 2, DURATION_SECONDS = 3; + + public static int[] splitDuration(Duration duration) { + long totalTimeSeconds = duration.getSeconds(); + long days = totalTimeSeconds / 86400L; + totalTimeSeconds = totalTimeSeconds % 86400L; + long hours = totalTimeSeconds / 3600L; + totalTimeSeconds = totalTimeSeconds % 3600; + long minutes = totalTimeSeconds / 60L; + totalTimeSeconds = totalTimeSeconds % 60; + return new int[] {(int) days, (int) hours, (int) minutes, (int) totalTimeSeconds}; + } + + public static String durationToString(Duration duration) { + String durationString; + int[] durationArray = splitDuration(duration); + if (durationArray[DURATION_DAYS] > 0) { + durationString = String.format(Locale.ROOT, "%dd %dh %dm %ds", durationArray[DURATION_DAYS], + durationArray[DURATION_HOURS], durationArray[DURATION_MINUTES], + durationArray[DURATION_SECONDS]); + } else { + durationString = String.format(Locale.ROOT, "%dh %dm %ds", durationArray[DURATION_HOURS], + durationArray[DURATION_MINUTES], durationArray[DURATION_SECONDS]); + } + return durationString; + } + + public static String escapeHtml(String input) { + return StringEscapeUtils.escapeHtml4(input); + } +} diff --git a/noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/reference_cnossos.json b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/autodoc/reference_cnossos.json similarity index 99% rename from noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/reference_cnossos.json rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/autodoc/reference_cnossos.json index 20afcdc1a..99f17997c 100644 --- a/noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/reference_cnossos.json +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/autodoc/reference_cnossos.json @@ -232,7 +232,7 @@ }, "Left": { "LH": [26.60, 24.10, 21.27, 15.57, 14.99, 10.86, 3.41, -15.80], - "LF": [26.60, 24.10, 21.27, 15.57, 14.99, 10.86, 3.41, -15.80] + "LF": [26.60, 24.10, 21.27, 18.25, 14.99, 10.86, 3.41, -15.80] } }, "TC20": { @@ -333,7 +333,7 @@ "LH": [40.27, 40.19, 40.02, 39.71, 35.90, 33.59, 31.47, 22.45], "LF": [43.01, 42.98, 42.92, 42.84, 37.90, 37.23, 39.96, 31.77] }, - "TC27_Reflection": { + "Reflection": { "LH": [35.56, 36.12, 38.09, 37.16, 32.44, 29.29, 25.96, 19.00], "LF": [37.83, 37.89, 38.82, 40.11, 34.12, 34.00, 32.98, 27.74] } diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/version.properties b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/version.properties new file mode 100644 index 000000000..afba2c572 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/version.properties @@ -0,0 +1 @@ +project.version=${project.version} diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/css/app.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/css/app.css new file mode 100644 index 000000000..defc0b66b --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/css/app.css @@ -0,0 +1,148 @@ +/** + * App-specific styles (unified with Builder/ColoringNoise theme) + */ + +/* Console font for log pages */ +@font-face { + font-family: "Multi-size, regular Misc-Fixed"; + src: url("../fonts/misc-fixed.ttf") format("truetype"); +} + +.console-text { + font-family: "Multi-size, regular Misc-Fixed", "Courier New", monospace; + padding: 1em; + font-size: 14px; + white-space: pre; + color: var(--text); +} + +.code { + padding: 0.6em 0 0.6em 0.6em; +} + +pre { + white-space: pre-wrap; + word-wrap: break-word; +} + +/* QR Code / Registration */ +.qrCodeText { + letter-spacing: 4px; + font-weight: bold; + margin-left: 10px; + font-family: "Courier New", monospace; + background: var(--surface-2); + padding: 0.5em 1em; + border-radius: var(--radius); + border: 1px solid var(--border); + display: inline-block; + margin-top: 0.5em; +} + +figcaption { + font-size: 0.8em; + margin: 0; + line-height: 1.4; + text-align: center; + color: var(--muted); + white-space: nowrap; +} + +/* GDPR text on login */ +.gdpr-text { + font-size: 12px; + line-height: 1.5; + color: var(--muted); + margin-top: 1.5em; +} + +.clickable-header { + cursor: pointer; +} + +/* Job table containers */ +.job-table-container { + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 0; + margin: 2em auto; + max-width: 100%; + width: calc(100% - 4em); + background: var(--surface); + box-shadow: var(--shadow-sm); + overflow: hidden; +} + +.pure-img-responsive { + max-width: 100%; + height: auto; +} + +/* Memory monitoring container */ +.memory-container { + margin: 2em; + max-width: 100%; + width: calc(100% - 4em); +} + +.memory-box { + padding: 20px; + background-color: #f9f9f9; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +.memory-box h3 { + margin-top: 0; +} + +.memory-stats { + margin-bottom: 20px; +} + +.memory-header { + display: flex; + justify-content: space-between; + margin-bottom: 8px; +} + +.memory-bar-container { + width: 100%; + height: 30px; + background-color: #e0e0e0; + border-radius: 4px; + overflow: hidden; + display: flex; +} + +.memory-used-bar { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + height: 100%; + transition: width 0.1s ease; + display: flex; + align-items: center; + justify-content: center; + color: white; + font-size: 12px; + font-weight: bold; +} + +.memory-free-bar { + background: linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%); + height: 100%; + transition: width 0.1s ease; + display: flex; + align-items: center; + justify-content: center; + color: #333; + font-size: 12px; + font-weight: bold; +} + +.memory-footer { + margin-top: 8px; + display: flex; + justify-content: space-between; + font-size: 12px; + color: #666; +} diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/css/pure-custom.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/css/pure-custom.css new file mode 100644 index 000000000..f79978d4a --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/css/pure-custom.css @@ -0,0 +1,477 @@ +/** + * Platform theme — unified with the Builder (ColoringNoise) + * Uses the same palette, Figtree font, and 5 px radius convention. + * Overrides PureCSS defaults for a consistent SaaS-like look. + */ + +/* ---------- Self-hosted Figtree (same files served from builder) ---------- */ +@font-face{ + font-family: 'Figtree'; + font-style: normal; + font-weight: 400 700; + font-display: swap; + src: url('../builder/dist/themes/coloringnoise/fonts/Figtree-latin.woff2') format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, + U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, + U+2212, U+2215, U+FEFF, U+FFFD; +} +@font-face{ + font-family: 'Figtree'; + font-style: normal; + font-weight: 400 700; + font-display: swap; + src: url('../builder/dist/themes/coloringnoise/fonts/Figtree-latin-ext.woff2') format('woff2'); + unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, + U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, + U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; +} + +/* ---------- Design tokens (mirror of builder theme) ---------- */ +:root{ + --cn-teal-1: #A0BABF; + --cn-teal-2: #B8D6D1; + --cn-green: #A8D5BA; + --cn-lime: #F5EEAB; + + --cn-orange-1:#F3C683; + --cn-orange-2:#E87E4D; + --cn-red: #CD463E; + + --cn-purple-1:#7B8FA3; + --cn-purple-2:#4B6478; + --cn-purple-3:#3B5068; + + --bg: #F7F8FA; + --surface: #FFFFFF; + --surface-2: #F2F4F7; + --surface-3: #E9EEF3; + + --text: #0F172A; + --muted: #475569; + + --border: rgba(15, 23, 42, 0.12); + --border-2: rgba(15, 23, 42, 0.18); + + --shadow: 0 10px 30px rgba(2, 6, 23, 0.08); + --shadow-sm: 0 2px 10px rgba(2, 6, 23, 0.06); + + --primary: var(--cn-purple-3); + --primary-2: var(--cn-purple-2); + + --radius: 5px; + + --ease: cubic-bezier(0.22, 0.61, 0.36, 1); + --duration: 0.18s; +} + +/* ---------- Base reset ---------- */ +*, *::before, *::after{ box-sizing: border-box; } + +body{ + font-family: 'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.5; + color: var(--text); + background: var(--bg); + background-image: none; +} + +a{ color: var(--primary); text-decoration: none; } +a:hover{ text-decoration: underline; } + +::selection{ + background: rgba(160, 186, 191, 0.40); + color: var(--text); +} + +/* ---------- Layout ---------- */ +#layout, +#menu, +.menu-link{ + transition: all 0.2s var(--ease); +} + +#layout{ + position: relative; + left: 0; + padding-left: 0; +} +#layout.active #menu{ left: 220px; width: 220px; } +#layout.active .menu-link{ left: 220px; } + +.content{ + margin: 0 auto; + padding: 0 2em; + margin-bottom: 50px; +} + +/* ---------- Header area ---------- */ +.header{ + margin: 0; + color: var(--text); + text-align: center; + padding: 2em 2em 0; +} +.header h1{ + margin: 0.2em 0; + font-size: 2em; + font-weight: 600; + color: var(--text); +} +.header h2{ + font-weight: 400; + color: var(--muted); + padding: 0; + margin-top: 0; + font-size: 1em; +} + +/* ---------- Sidebar menu ---------- */ +#menu{ + margin-left: -220px; + width: 220px; + position: fixed; + top: 0; + left: 0; + bottom: 0; + z-index: 1000; + background: linear-gradient(180deg, var(--cn-purple-3), #2d3e50); + overflow-y: auto; + display: flex; + flex-direction: column; + min-height: 100%; + box-shadow: 2px 0 12px rgba(2, 6, 23, 0.12); +} +#menu a{ + color: rgba(255,255,255,0.75); + border: none; + padding: 0.7em 1.2em; + font-size: 13px; + transition: background var(--duration) var(--ease), color var(--duration) var(--ease); +} +#menu ul{ + border: none; + background: transparent; +} +#menu ul, +#menu .menu-item-divided{ + border-top: 1px solid rgba(255,255,255,0.10); +} +#menu .pure-menu-link:hover, +#menu .pure-menu-link:focus{ + background: rgba(255,255,255,0.20); + color: #fff; +} +#menu .pure-menu-selected{ + background: rgba(255,255,255,0.15); +} +#menu .pure-menu-selected .pure-menu-link{ + color: #fff; +} +#menu .pure-menu-heading{ + font-size: 11px; + font-weight: 700; + color: rgba(255,255,255,0.85); + text-transform: uppercase; + letter-spacing: 0.10em; + margin: 0; + padding: 0.8em 1.2em; + background: rgba(255,255,255,0.10); + border-top: 1px solid rgba(255,255,255,0.08); + border-bottom: 1px solid rgba(255,255,255,0.08); +} + +/* Filler to push logout to bottom */ +#filler{ flex-grow: 1; } + +/* ---------- Hamburger menu link (small screens) ---------- */ +.menu-link{ + position: fixed; + display: block; + top: 0; + left: 0; + background: var(--cn-purple-3); + font-size: 10px; + z-index: 10; + width: 2em; + height: auto; + padding: 2.1em 1.6em; + border-radius: 0 0 var(--radius) 0; +} +.menu-link:hover, +.menu-link:focus{ + background: var(--cn-purple-2); +} +.menu-link span{ position: relative; display: block; } +.menu-link span, +.menu-link span:before, +.menu-link span:after{ + background-color: #fff; + pointer-events: none; + width: 100%; + height: 0.2em; +} +.menu-link span:before, +.menu-link span:after{ + position: absolute; + margin-top: -0.6em; + content: " "; +} +.menu-link span:after{ margin-top: 0.6em; } + +/* ---------- Tables ---------- */ +.pure-table{ + margin-left: auto; + margin-right: auto; + border-radius: var(--radius); + overflow: hidden; + border: 1px solid var(--border); + box-shadow: var(--shadow-sm); +} +.pure-table thead{ + background: var(--surface-2); +} +.pure-table th{ + font-weight: 600; + color: var(--text); + font-size: 13px; + padding: 0.7em 1em; + border-bottom: 1px solid var(--border-2); +} +.pure-table td{ + padding: 0.6em 1em; + font-size: 13px; + color: var(--text); + border-bottom: 1px solid var(--border); +} +.pure-table .pure-table-greyed{ + background-color: var(--surface-2); + font-weight: 600; + color: var(--muted); + width: 140px; +} + +/* ---------- Buttons (PureCSS override) ---------- */ +.pure-button{ + border-radius: var(--radius); + font-family: 'Figtree', sans-serif; + font-weight: 600; + font-size: 13px; + padding: 0.55em 1.4em; + transition: transform .05s ease, background var(--duration) var(--ease), + box-shadow var(--duration) var(--ease); + border: none; +} +.pure-button:active{ transform: translateY(1px); } + +.pure-button-primary{ + background: linear-gradient(135deg, var(--cn-purple-2), var(--cn-purple-3)); + color: #fff; + box-shadow: 0 2px 8px rgba(59, 80, 104, 0.25); +} +.pure-button-primary:hover{ + background: linear-gradient(135deg, #5A7A92, var(--cn-purple-2)); + box-shadow: 0 4px 16px rgba(59, 80, 104, 0.35); +} +.pure-button-primary:disabled{ + background: var(--surface-3); + color: var(--muted); + box-shadow: none; + cursor: not-allowed; + opacity: 1; +} + +/* ---------- Forms ---------- */ +.pure-form input[type="text"], +.pure-form input[type="email"], +.pure-form input[type="number"], +.pure-form input[type="password"], +.pure-form select, +.pure-form textarea{ + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 0.5em 0.8em; + font-family: 'Figtree', sans-serif; + font-size: 13px; + color: var(--text); + background: #fff; + transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease); +} +.pure-form input:focus, +.pure-form select:focus, +.pure-form textarea:focus{ + border-color: rgba(75, 100, 120, 0.50); + box-shadow: 0 0 0 3px rgba(160, 186, 191, 0.35); + outline: none; +} + +.pure-form legend{ + font-weight: 600; + color: var(--text); + font-size: 14px; + border-bottom: 1px solid var(--border); + padding-bottom: 0.5em; + margin-bottom: 1em; +} + +.pure-form label{ + font-weight: 500; + color: var(--muted); + font-size: 13px; +} + +.pure-form fieldset{ + border: none; + padding: 0; + margin: 0 0 1.5em; +} + +/* ---------- Messages / Aside ---------- */ +.l-box aside{ + background: var(--surface-2); + border: 1px solid var(--border); + border-left: 4px solid var(--cn-teal-1); + border-radius: var(--radius); + padding: 0.8em 1.2em; + margin: 0.8em 0; + color: var(--text); + font-size: 13px; +} + +/* ---------- Splash / Landing page ---------- */ +.splash-container{ + background: linear-gradient(135deg, var(--cn-purple-3) 0%, var(--cn-purple-2) 40%, var(--cn-teal-1) 100%); + z-index: 1; + overflow: hidden; + width: 100%; + height: 100%; + top: 0; + left: 0; + position: fixed !important; + display: flex; + align-items: center; + justify-content: center; +} + +.splash{ + text-align: center; + max-width: 1200px; + padding: 2em; +} + +.splash-head{ + font-size: 28px; + font-weight: 700; + color: #fff; + border: 2px solid rgba(255,255,255,0.35); + padding: 0.8em 1.4em; + border-radius: var(--radius); + line-height: 1.3; + text-transform: none; + letter-spacing: 0.02em; +} + +.splash-subhead{ + color: rgba(255,255,255,0.80); + letter-spacing: 0.03em; + font-size: 15px; + margin-top: 1em; +} + +.splash img{ + max-width: 800px; + width: 100%; + margin: 1.5em auto; + display: block; + opacity: 0.95; + filter: drop-shadow(0 4px 12px rgba(0,0,0,0.20)); +} + +.splash .pure-button{ + margin-top: 0.5em; + font-size: 15px; + padding: 0.7em 2em; + background: rgba(255,255,255,0.15); + color: #fff; + border: 2px solid rgba(255,255,255,0.35); + backdrop-filter: blur(4px); +} +.splash .pure-button:hover{ + background: rgba(255,255,255,0.25); + border-color: rgba(255,255,255,0.55); + box-shadow: 0 4px 20px rgba(0,0,0,0.15); +} + +/* ---------- Job table container ---------- */ +.job-table-container{ + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 0 0 1em; + background: var(--surface); + box-shadow: var(--shadow-sm); + overflow: visible; + margin: 1em auto; + max-width: 800px; +} +.job-table-container .pure-table{ + box-shadow: none; + border: none; + border-radius: 0; +} + +/* ---------- Misc helpers ---------- */ +.pure-g .centered{ + text-align: center; + margin-top: 1em; + margin-bottom: 0.5em; +} + +.content-subhead{ + margin: 50px 0 20px 0; + font-weight: 600; + color: var(--muted); +} + +/* ---------- Responsive ---------- */ +@media (min-width: 48em){ + .header, .content{ + padding-left: 2em; + padding-right: 2em; + } + #layout{ + padding-left: 220px; + left: 0; + } + #menu{ + margin-left: 0; + left: 0; + } + .menu-link{ + position: fixed; + left: 220px; + display: none; + } + #layout.active .menu-link{ + left: 220px; + } +} + +@media (max-width: 48em){ + #layout.active{ + position: relative; + left: 220px; + } +} + +@media (min-width: 78em){ + .splash-head{ + font-size: 38px; + } +} + +/* ---------- Scrollbar ---------- */ +::-webkit-scrollbar{ width: 8px; height: 8px; } +::-webkit-scrollbar-track{ background: var(--surface-2); border-radius: var(--radius); } +::-webkit-scrollbar-thumb{ background: var(--cn-teal-1); border-radius: var(--radius); border: 2px solid var(--surface-2); } +::-webkit-scrollbar-thumb:hover{ background: var(--cn-purple-1); } +*{ scrollbar-width: thin; scrollbar-color: var(--cn-teal-1) var(--surface-2); } diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/css/pure-min.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/css/pure-min.css new file mode 100644 index 000000000..d7a2c1890 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/css/pure-min.css @@ -0,0 +1,11 @@ +/*! +Pure v3.0.0 +Copyright 2013 Yahoo! +Licensed under the BSD License. +https://github.com/pure-css/pure/blob/master/LICENSE +*/ +/*! +normalize.css v | MIT License | https://necolas.github.io/normalize.css/ +Copyright (c) Nicolas Gallagher and Jonathan Neal +*/ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}html{font-family:sans-serif}.hidden,[hidden]{display:none!important}.pure-img{max-width:100%;height:auto;display:block}.pure-g{display:flex;flex-flow:row wrap;align-content:flex-start}.pure-u{display:inline-block;vertical-align:top}.pure-u-1,.pure-u-1-1,.pure-u-1-12,.pure-u-1-2,.pure-u-1-24,.pure-u-1-3,.pure-u-1-4,.pure-u-1-5,.pure-u-1-6,.pure-u-1-8,.pure-u-10-24,.pure-u-11-12,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-2-24,.pure-u-2-3,.pure-u-2-5,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24,.pure-u-3-24,.pure-u-3-4,.pure-u-3-5,.pure-u-3-8,.pure-u-4-24,.pure-u-4-5,.pure-u-5-12,.pure-u-5-24,.pure-u-5-5,.pure-u-5-6,.pure-u-5-8,.pure-u-6-24,.pure-u-7-12,.pure-u-7-24,.pure-u-7-8,.pure-u-8-24,.pure-u-9-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-1-24{width:4.1667%}.pure-u-1-12,.pure-u-2-24{width:8.3333%}.pure-u-1-8,.pure-u-3-24{width:12.5%}.pure-u-1-6,.pure-u-4-24{width:16.6667%}.pure-u-1-5{width:20%}.pure-u-5-24{width:20.8333%}.pure-u-1-4,.pure-u-6-24{width:25%}.pure-u-7-24{width:29.1667%}.pure-u-1-3,.pure-u-8-24{width:33.3333%}.pure-u-3-8,.pure-u-9-24{width:37.5%}.pure-u-2-5{width:40%}.pure-u-10-24,.pure-u-5-12{width:41.6667%}.pure-u-11-24{width:45.8333%}.pure-u-1-2,.pure-u-12-24{width:50%}.pure-u-13-24{width:54.1667%}.pure-u-14-24,.pure-u-7-12{width:58.3333%}.pure-u-3-5{width:60%}.pure-u-15-24,.pure-u-5-8{width:62.5%}.pure-u-16-24,.pure-u-2-3{width:66.6667%}.pure-u-17-24{width:70.8333%}.pure-u-18-24,.pure-u-3-4{width:75%}.pure-u-19-24{width:79.1667%}.pure-u-4-5{width:80%}.pure-u-20-24,.pure-u-5-6{width:83.3333%}.pure-u-21-24,.pure-u-7-8{width:87.5%}.pure-u-11-12,.pure-u-22-24{width:91.6667%}.pure-u-23-24{width:95.8333%}.pure-u-1,.pure-u-1-1,.pure-u-24-24,.pure-u-5-5{width:100%}.pure-button{display:inline-block;line-height:normal;white-space:nowrap;vertical-align:middle;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;user-select:none;box-sizing:border-box}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button-group{letter-spacing:-.31em;text-rendering:optimizespeed}.opera-only :-o-prefocus,.pure-button-group{word-spacing:-0.43em}.pure-button-group .pure-button{letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-button{font-family:inherit;font-size:100%;padding:.5em 1em;color:rgba(0,0,0,.8);border:none transparent;background-color:#e6e6e6;text-decoration:none;border-radius:2px}.pure-button-hover,.pure-button:focus,.pure-button:hover{background-image:linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1))}.pure-button:focus{outline:0}.pure-button-active,.pure-button:active{box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 0 6px rgba(0,0,0,.2) inset;border-color:#000}.pure-button-disabled,.pure-button-disabled:active,.pure-button-disabled:focus,.pure-button-disabled:hover,.pure-button[disabled]{border:none;background-image:none;opacity:.4;cursor:not-allowed;box-shadow:none;pointer-events:none}.pure-button-hidden{display:none}.pure-button-primary,.pure-button-selected,a.pure-button-primary,a.pure-button-selected{background-color:#0078e7;color:#fff}.pure-button-group .pure-button{margin:0;border-radius:0;border-right:1px solid rgba(0,0,0,.2)}.pure-button-group .pure-button:first-child{border-top-left-radius:2px;border-bottom-left-radius:2px}.pure-button-group .pure-button:last-child{border-top-right-radius:2px;border-bottom-right-radius:2px;border-right:none}.pure-form input[type=color],.pure-form input[type=date],.pure-form input[type=datetime-local],.pure-form input[type=datetime],.pure-form input[type=email],.pure-form input[type=month],.pure-form input[type=number],.pure-form input[type=password],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=text],.pure-form input[type=time],.pure-form input[type=url],.pure-form input[type=week],.pure-form select,.pure-form textarea{padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;vertical-align:middle;box-sizing:border-box}.pure-form input:not([type]){padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;box-sizing:border-box}.pure-form input[type=color]{padding:.2em .5em}.pure-form input[type=color]:focus,.pure-form input[type=date]:focus,.pure-form input[type=datetime-local]:focus,.pure-form input[type=datetime]:focus,.pure-form input[type=email]:focus,.pure-form input[type=month]:focus,.pure-form input[type=number]:focus,.pure-form input[type=password]:focus,.pure-form input[type=search]:focus,.pure-form input[type=tel]:focus,.pure-form input[type=text]:focus,.pure-form input[type=time]:focus,.pure-form input[type=url]:focus,.pure-form input[type=week]:focus,.pure-form select:focus,.pure-form textarea:focus{outline:0;border-color:#129fea}.pure-form input:not([type]):focus{outline:0;border-color:#129fea}.pure-form input[type=checkbox]:focus,.pure-form input[type=file]:focus,.pure-form input[type=radio]:focus{outline:thin solid #129FEA;outline:1px auto #129FEA}.pure-form .pure-checkbox,.pure-form .pure-radio{margin:.5em 0;display:block}.pure-form input[type=color][disabled],.pure-form input[type=date][disabled],.pure-form input[type=datetime-local][disabled],.pure-form input[type=datetime][disabled],.pure-form input[type=email][disabled],.pure-form input[type=month][disabled],.pure-form input[type=number][disabled],.pure-form input[type=password][disabled],.pure-form input[type=search][disabled],.pure-form input[type=tel][disabled],.pure-form input[type=text][disabled],.pure-form input[type=time][disabled],.pure-form input[type=url][disabled],.pure-form input[type=week][disabled],.pure-form select[disabled],.pure-form textarea[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input:not([type])[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input[readonly],.pure-form select[readonly],.pure-form textarea[readonly]{background-color:#eee;color:#777;border-color:#ccc}.pure-form input:focus:invalid,.pure-form select:focus:invalid,.pure-form textarea:focus:invalid{color:#b94a48;border-color:#e9322d}.pure-form input[type=checkbox]:focus:invalid:focus,.pure-form input[type=file]:focus:invalid:focus,.pure-form input[type=radio]:focus:invalid:focus{outline-color:#e9322d}.pure-form select{height:2.25em;border:1px solid #ccc;background-color:#fff}.pure-form select[multiple]{height:auto}.pure-form label{margin:.5em 0 .2em}.pure-form fieldset{margin:0;padding:.35em 0 .75em;border:0}.pure-form legend{display:block;width:100%;padding:.3em 0;margin-bottom:.3em;color:#333;border-bottom:1px solid #e5e5e5}.pure-form-stacked input[type=color],.pure-form-stacked input[type=date],.pure-form-stacked input[type=datetime-local],.pure-form-stacked input[type=datetime],.pure-form-stacked input[type=email],.pure-form-stacked input[type=file],.pure-form-stacked input[type=month],.pure-form-stacked input[type=number],.pure-form-stacked input[type=password],.pure-form-stacked input[type=search],.pure-form-stacked input[type=tel],.pure-form-stacked input[type=text],.pure-form-stacked input[type=time],.pure-form-stacked input[type=url],.pure-form-stacked input[type=week],.pure-form-stacked label,.pure-form-stacked select,.pure-form-stacked textarea{display:block;margin:.25em 0}.pure-form-stacked input:not([type]){display:block;margin:.25em 0}.pure-form-aligned input,.pure-form-aligned select,.pure-form-aligned textarea,.pure-form-message-inline{display:inline-block;vertical-align:middle}.pure-form-aligned textarea{vertical-align:top}.pure-form-aligned .pure-control-group{margin-bottom:.5em}.pure-form-aligned .pure-control-group label{text-align:right;display:inline-block;vertical-align:middle;width:10em;margin:0 1em 0 0}.pure-form-aligned .pure-controls{margin:1.5em 0 0 11em}.pure-form .pure-input-rounded,.pure-form input.pure-input-rounded{border-radius:2em;padding:.5em 1em}.pure-form .pure-group fieldset{margin-bottom:10px}.pure-form .pure-group input,.pure-form .pure-group textarea{display:block;padding:10px;margin:0 0 -1px;border-radius:0;position:relative;top:-1px}.pure-form .pure-group input:focus,.pure-form .pure-group textarea:focus{z-index:3}.pure-form .pure-group input:first-child,.pure-form .pure-group textarea:first-child{top:1px;border-radius:4px 4px 0 0;margin:0}.pure-form .pure-group input:first-child:last-child,.pure-form .pure-group textarea:first-child:last-child{top:1px;border-radius:4px;margin:0}.pure-form .pure-group input:last-child,.pure-form .pure-group textarea:last-child{top:-2px;border-radius:0 0 4px 4px;margin:0}.pure-form .pure-group button{margin:.35em 0}.pure-form .pure-input-1{width:100%}.pure-form .pure-input-3-4{width:75%}.pure-form .pure-input-2-3{width:66%}.pure-form .pure-input-1-2{width:50%}.pure-form .pure-input-1-3{width:33%}.pure-form .pure-input-1-4{width:25%}.pure-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:.875em}.pure-form-message{display:block;color:#666;font-size:.875em}@media only screen and (max-width :480px){.pure-form button[type=submit]{margin:.7em 0 0}.pure-form input:not([type]),.pure-form input[type=color],.pure-form input[type=date],.pure-form input[type=datetime-local],.pure-form input[type=datetime],.pure-form input[type=email],.pure-form input[type=month],.pure-form input[type=number],.pure-form input[type=password],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=text],.pure-form input[type=time],.pure-form input[type=url],.pure-form input[type=week],.pure-form label{margin-bottom:.3em;display:block}.pure-group input:not([type]),.pure-group input[type=color],.pure-group input[type=date],.pure-group input[type=datetime-local],.pure-group input[type=datetime],.pure-group input[type=email],.pure-group input[type=month],.pure-group input[type=number],.pure-group input[type=password],.pure-group input[type=search],.pure-group input[type=tel],.pure-group input[type=text],.pure-group input[type=time],.pure-group input[type=url],.pure-group input[type=week]{margin-bottom:0}.pure-form-aligned .pure-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.pure-form-aligned .pure-controls{margin:1.5em 0 0 0}.pure-form-message,.pure-form-message-inline{display:block;font-size:.75em;padding:.2em 0 .8em}}.pure-menu{box-sizing:border-box}.pure-menu-fixed{position:fixed;left:0;top:0;z-index:3}.pure-menu-item,.pure-menu-list{position:relative}.pure-menu-list{list-style:none;margin:0;padding:0}.pure-menu-item{padding:0;margin:0;height:100%}.pure-menu-heading,.pure-menu-link{display:block;text-decoration:none;white-space:nowrap}.pure-menu-horizontal{width:100%;white-space:nowrap}.pure-menu-horizontal .pure-menu-list{display:inline-block}.pure-menu-horizontal .pure-menu-heading,.pure-menu-horizontal .pure-menu-item,.pure-menu-horizontal .pure-menu-separator{display:inline-block;vertical-align:middle}.pure-menu-item .pure-menu-item{display:block}.pure-menu-children{display:none;position:absolute;left:100%;top:0;margin:0;padding:0;z-index:3}.pure-menu-horizontal .pure-menu-children{left:0;top:auto;width:inherit}.pure-menu-active>.pure-menu-children,.pure-menu-allow-hover:hover>.pure-menu-children{display:block;position:absolute}.pure-menu-has-children>.pure-menu-link:after{padding-left:.5em;content:"\25B8";font-size:small}.pure-menu-horizontal .pure-menu-has-children>.pure-menu-link:after{content:"\25BE"}.pure-menu-scrollable{overflow-y:scroll;overflow-x:hidden}.pure-menu-scrollable .pure-menu-list{display:block}.pure-menu-horizontal.pure-menu-scrollable .pure-menu-list{display:inline-block}.pure-menu-horizontal.pure-menu-scrollable{white-space:nowrap;overflow-y:hidden;overflow-x:auto;padding:.5em 0}.pure-menu-horizontal .pure-menu-children .pure-menu-separator,.pure-menu-separator{background-color:#ccc;height:1px;margin:.3em 0}.pure-menu-horizontal .pure-menu-separator{width:1px;height:1.3em;margin:0 .3em}.pure-menu-horizontal .pure-menu-children .pure-menu-separator{display:block;width:auto}.pure-menu-heading{text-transform:uppercase;color:#565d64}.pure-menu-link{color:#777}.pure-menu-children{background-color:#fff}.pure-menu-heading,.pure-menu-link{padding:.5em 1em}.pure-menu-disabled{opacity:.5}.pure-menu-disabled .pure-menu-link:hover{background-color:transparent;cursor:default}.pure-menu-active>.pure-menu-link,.pure-menu-link:focus,.pure-menu-link:hover{background-color:#eee}.pure-menu-selected>.pure-menu-link,.pure-menu-selected>.pure-menu-link:visited{color:#000}.pure-table{border-collapse:collapse;border-spacing:0;empty-cells:show;border:1px solid #cbcbcb}.pure-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.pure-table td,.pure-table th{border-left:1px solid #cbcbcb;border-width:0 0 0 1px;font-size:inherit;margin:0;overflow:visible;padding:.5em 1em}.pure-table thead{background-color:#e0e0e0;color:#000;text-align:left;vertical-align:bottom}.pure-table td{background-color:transparent}.pure-table-odd td{background-color:#f2f2f2}.pure-table-striped tr:nth-child(2n-1) td{background-color:#f2f2f2}.pure-table-bordered td{border-bottom:1px solid #cbcbcb}.pure-table-bordered tbody>tr:last-child>td{border-bottom-width:0}.pure-table-horizontal td,.pure-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #cbcbcb}.pure-table-horizontal tbody>tr:last-child>td{border-bottom-width:0} diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/favicon.ico b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/favicon.ico new file mode 100644 index 000000000..b3c2a2c82 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/favicon.ico differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/fonts/README b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/fonts/README new file mode 100644 index 000000000..17c99a40b --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/fonts/README @@ -0,0 +1,2 @@ + http://underpop.online.fr/l/linux-console-fonts-for-windows-in-ttf-and-fon/ + GNU GPL Version 2 license. \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/fonts/misc-fixed.ttf b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/fonts/misc-fixed.ttf new file mode 100644 index 000000000..cf1d11fb0 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/fonts/misc-fixed.ttf differ diff --git a/wpsbuilder/assets/img/logo_noisemap_alone_small.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/img/logo_noisemap_alone_small.png similarity index 100% rename from wpsbuilder/assets/img/logo_noisemap_alone_small.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/img/logo_noisemap_alone_small.png diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/axios.min.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/axios.min.js new file mode 100644 index 000000000..fc6c8b618 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/axios.min.js @@ -0,0 +1,3 @@ +/* axios v0.21.1 | (c) 2020 by Matt Zabriskie */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.axios=t():e.axios=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";function r(e){var t=new i(e),n=s(i.prototype.request,t);return o.extend(n,i.prototype,t),o.extend(n,t),n}var o=n(2),s=n(3),i=n(4),a=n(22),u=n(10),c=r(u);c.Axios=i,c.create=function(e){return r(a(c.defaults,e))},c.Cancel=n(23),c.CancelToken=n(24),c.isCancel=n(9),c.all=function(e){return Promise.all(e)},c.spread=n(25),c.isAxiosError=n(26),e.exports=c,e.exports.default=c},function(e,t,n){"use strict";function r(e){return"[object Array]"===R.call(e)}function o(e){return"undefined"==typeof e}function s(e){return null!==e&&!o(e)&&null!==e.constructor&&!o(e.constructor)&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function i(e){return"[object ArrayBuffer]"===R.call(e)}function a(e){return"undefined"!=typeof FormData&&e instanceof FormData}function u(e){var t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer}function c(e){return"string"==typeof e}function f(e){return"number"==typeof e}function p(e){return null!==e&&"object"==typeof e}function d(e){if("[object Object]"!==R.call(e))return!1;var t=Object.getPrototypeOf(e);return null===t||t===Object.prototype}function l(e){return"[object Date]"===R.call(e)}function h(e){return"[object File]"===R.call(e)}function m(e){return"[object Blob]"===R.call(e)}function y(e){return"[object Function]"===R.call(e)}function g(e){return p(e)&&y(e.pipe)}function v(e){return"undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams}function x(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function w(){return("undefined"==typeof navigator||"ReactNative"!==navigator.product&&"NativeScript"!==navigator.product&&"NS"!==navigator.product)&&("undefined"!=typeof window&&"undefined"!=typeof document)}function b(e,t){if(null!==e&&"undefined"!=typeof e)if("object"!=typeof e&&(e=[e]),r(e))for(var n=0,o=e.length;n=200&&e<300}};u.headers={common:{Accept:"application/json, text/plain, */*"}},s.forEach(["delete","get","head"],function(e){u.headers[e]={}}),s.forEach(["post","put","patch"],function(e){u.headers[e]=s.merge(a)}),e.exports=u},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t){r.forEach(e,function(n,r){r!==t&&r.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[r])})}},function(e,t,n){"use strict";var r=n(2),o=n(13),s=n(16),i=n(5),a=n(17),u=n(20),c=n(21),f=n(14);e.exports=function(e){return new Promise(function(t,n){var p=e.data,d=e.headers;r.isFormData(p)&&delete d["Content-Type"];var l=new XMLHttpRequest;if(e.auth){var h=e.auth.username||"",m=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";d.Authorization="Basic "+btoa(h+":"+m)}var y=a(e.baseURL,e.url);if(l.open(e.method.toUpperCase(),i(y,e.params,e.paramsSerializer),!0),l.timeout=e.timeout,l.onreadystatechange=function(){if(l&&4===l.readyState&&(0!==l.status||l.responseURL&&0===l.responseURL.indexOf("file:"))){var r="getAllResponseHeaders"in l?u(l.getAllResponseHeaders()):null,s=e.responseType&&"text"!==e.responseType?l.response:l.responseText,i={data:s,status:l.status,statusText:l.statusText,headers:r,config:e,request:l};o(t,n,i),l=null}},l.onabort=function(){l&&(n(f("Request aborted",e,"ECONNABORTED",l)),l=null)},l.onerror=function(){n(f("Network Error",e,null,l)),l=null},l.ontimeout=function(){var t="timeout of "+e.timeout+"ms exceeded";e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),n(f(t,e,"ECONNABORTED",l)),l=null},r.isStandardBrowserEnv()){var g=(e.withCredentials||c(y))&&e.xsrfCookieName?s.read(e.xsrfCookieName):void 0;g&&(d[e.xsrfHeaderName]=g)}if("setRequestHeader"in l&&r.forEach(d,function(e,t){"undefined"==typeof p&&"content-type"===t.toLowerCase()?delete d[t]:l.setRequestHeader(t,e)}),r.isUndefined(e.withCredentials)||(l.withCredentials=!!e.withCredentials),e.responseType)try{l.responseType=e.responseType}catch(t){if("json"!==e.responseType)throw t}"function"==typeof e.onDownloadProgress&&l.addEventListener("progress",e.onDownloadProgress),"function"==typeof e.onUploadProgress&&l.upload&&l.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then(function(e){l&&(l.abort(),n(e),l=null)}),p||(p=null),l.send(p)})}},function(e,t,n){"use strict";var r=n(14);e.exports=function(e,t,n){var o=n.config.validateStatus;n.status&&o&&!o(n.status)?t(r("Request failed with status code "+n.status,n.config,null,n.request,n)):e(n)}},function(e,t,n){"use strict";var r=n(15);e.exports=function(e,t,n,o,s){var i=new Error(e);return r(i,t,n,o,s)}},function(e,t){"use strict";e.exports=function(e,t,n,r,o){return e.config=t,n&&(e.code=n),e.request=r,e.response=o,e.isAxiosError=!0,e.toJSON=function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:this.config,code:this.code}},e}},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){return{write:function(e,t,n,o,s,i){var a=[];a.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&a.push("expires="+new Date(n).toGMTString()),r.isString(o)&&a.push("path="+o),r.isString(s)&&a.push("domain="+s),i===!0&&a.push("secure"),document.cookie=a.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},function(e,t,n){"use strict";var r=n(18),o=n(19);e.exports=function(e,t){return e&&!r(t)?o(e,t):t}},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},function(e,t,n){"use strict";var r=n(2),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,s,i={};return e?(r.forEach(e.split("\n"),function(e){if(s=e.indexOf(":"),t=r.trim(e.substr(0,s)).toLowerCase(),n=r.trim(e.substr(s+1)),t){if(i[t]&&o.indexOf(t)>=0)return;"set-cookie"===t?i[t]=(i[t]?i[t]:[]).concat([n]):i[t]=i[t]?i[t]+", "+n:n}}),i):i}},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){function e(e){var t=e;return n&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}var t,n=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a");return t=e(window.location.href),function(n){var o=r.isString(n)?e(n):n;return o.protocol===t.protocol&&o.host===t.host}}():function(){return function(){return!0}}()},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t){function n(e,t){return r.isPlainObject(e)&&r.isPlainObject(t)?r.merge(e,t):r.isPlainObject(t)?r.merge({},t):r.isArray(t)?t.slice():t}function o(o){r.isUndefined(t[o])?r.isUndefined(e[o])||(s[o]=n(void 0,e[o])):s[o]=n(e[o],t[o])}t=t||{};var s={},i=["url","method","data"],a=["headers","auth","proxy","params"],u=["baseURL","transformRequest","transformResponse","paramsSerializer","timeout","timeoutMessage","withCredentials","adapter","responseType","xsrfCookieName","xsrfHeaderName","onUploadProgress","onDownloadProgress","decompress","maxContentLength","maxBodyLength","maxRedirects","transport","httpAgent","httpsAgent","cancelToken","socketPath","responseEncoding"],c=["validateStatus"];r.forEach(i,function(e){r.isUndefined(t[e])||(s[e]=n(void 0,t[e]))}),r.forEach(a,o),r.forEach(u,function(o){r.isUndefined(t[o])?r.isUndefined(e[o])||(s[o]=n(void 0,e[o])):s[o]=n(void 0,t[o])}),r.forEach(c,function(r){r in t?s[r]=n(e[r],t[r]):r in e&&(s[r]=n(void 0,e[r]))});var f=i.concat(a).concat(u).concat(c),p=Object.keys(e).concat(Object.keys(t)).filter(function(e){return f.indexOf(e)===-1});return r.forEach(p,o),s}},function(e,t){"use strict";function n(e){this.message=e}n.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},n.prototype.__CANCEL__=!0,e.exports=n},function(e,t,n){"use strict";function r(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new o(e),t(n.reason))})}var o=n(23);r.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},r.source=function(){var e,t=new r(function(t){e=t});return{token:t,cancel:e}},e.exports=r},function(e,t){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}},function(e,t){"use strict";e.exports=function(e){return"object"==typeof e&&e.isAxiosError===!0}}])}); +//# sourceMappingURL=axios.min.map \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/axios.min.map b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/axios.min.map new file mode 100644 index 000000000..a897631d1 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/axios.min.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///axios.min.js","webpack:///webpack/bootstrap 081842adca0968bb3270","webpack:///./index.js","webpack:///./lib/axios.js","webpack:///./lib/utils.js","webpack:///./lib/helpers/bind.js","webpack:///./lib/core/Axios.js","webpack:///./lib/helpers/buildURL.js","webpack:///./lib/core/InterceptorManager.js","webpack:///./lib/core/dispatchRequest.js","webpack:///./lib/core/transformData.js","webpack:///./lib/cancel/isCancel.js","webpack:///./lib/defaults.js","webpack:///./lib/helpers/normalizeHeaderName.js","webpack:///./lib/adapters/xhr.js","webpack:///./lib/core/settle.js","webpack:///./lib/core/createError.js","webpack:///./lib/core/enhanceError.js","webpack:///./lib/helpers/cookies.js","webpack:///./lib/core/buildFullPath.js","webpack:///./lib/helpers/isAbsoluteURL.js","webpack:///./lib/helpers/combineURLs.js","webpack:///./lib/helpers/parseHeaders.js","webpack:///./lib/helpers/isURLSameOrigin.js","webpack:///./lib/core/mergeConfig.js","webpack:///./lib/cancel/Cancel.js","webpack:///./lib/cancel/CancelToken.js","webpack:///./lib/helpers/spread.js","webpack:///./lib/helpers/isAxiosError.js"],"names":["root","factory","exports","module","define","amd","this","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","createInstance","defaultConfig","context","Axios","instance","bind","prototype","request","utils","extend","mergeConfig","defaults","axios","create","instanceConfig","Cancel","CancelToken","isCancel","all","promises","Promise","spread","isAxiosError","default","isArray","val","toString","isUndefined","isBuffer","constructor","isArrayBuffer","isFormData","FormData","isArrayBufferView","result","ArrayBuffer","isView","buffer","isString","isNumber","isObject","isPlainObject","Object","getPrototypeOf","isDate","isFile","isBlob","isFunction","isStream","pipe","isURLSearchParams","URLSearchParams","trim","str","replace","isStandardBrowserEnv","navigator","product","window","document","forEach","obj","fn","i","l","length","key","hasOwnProperty","merge","assignValue","slice","arguments","a","b","thisArg","stripBOM","content","charCodeAt","args","Array","apply","interceptors","InterceptorManager","response","buildURL","dispatchRequest","config","url","method","toLowerCase","chain","undefined","promise","resolve","interceptor","unshift","fulfilled","rejected","push","then","shift","getUri","params","paramsSerializer","data","encode","encodeURIComponent","serializedParams","parts","v","toISOString","JSON","stringify","join","hashmarkIndex","indexOf","handlers","use","eject","h","throwIfCancellationRequested","cancelToken","throwIfRequested","transformData","headers","transformRequest","common","adapter","transformResponse","reason","reject","fns","value","__CANCEL__","setContentTypeIfUnset","getDefaultAdapter","XMLHttpRequest","process","normalizeHeaderName","DEFAULT_CONTENT_TYPE","Content-Type","parse","e","timeout","xsrfCookieName","xsrfHeaderName","maxContentLength","maxBodyLength","validateStatus","status","Accept","normalizedName","name","toUpperCase","settle","cookies","buildFullPath","parseHeaders","isURLSameOrigin","createError","requestData","requestHeaders","auth","username","password","unescape","Authorization","btoa","fullPath","baseURL","open","onreadystatechange","readyState","responseURL","responseHeaders","getAllResponseHeaders","responseData","responseType","responseText","statusText","onabort","onerror","ontimeout","timeoutErrorMessage","xsrfValue","withCredentials","read","setRequestHeader","onDownloadProgress","addEventListener","onUploadProgress","upload","cancel","abort","send","enhanceError","message","code","error","Error","toJSON","description","number","fileName","lineNumber","columnNumber","stack","write","expires","path","domain","secure","cookie","Date","toGMTString","match","RegExp","decodeURIComponent","remove","now","isAbsoluteURL","combineURLs","requestedURL","test","relativeURL","ignoreDuplicateOf","parsed","split","line","substr","concat","resolveURL","href","msie","urlParsingNode","setAttribute","protocol","host","search","hash","hostname","port","pathname","charAt","originURL","userAgent","createElement","location","requestURL","config1","config2","getMergedValue","target","source","mergeDeepProperties","prop","valueFromConfig2Keys","mergeDeepPropertiesKeys","defaultToConfig2Keys","directMergeKeys","axiosKeys","otherKeys","keys","filter","executor","TypeError","resolvePromise","token","callback","arr","payload"],"mappings":"CAAA,SAAAA,EAAAC,GACA,gBAAAC,UAAA,gBAAAC,QACAA,OAAAD,QAAAD,IACA,kBAAAG,gBAAAC,IACAD,UAAAH,GACA,gBAAAC,SACAA,QAAA,MAAAD,IAEAD,EAAA,MAAAC,KACCK,KAAA,WACD,MCAgB,UAAUC,GCN1B,QAAAC,GAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAP,OAGA,IAAAC,GAAAO,EAAAD,IACAP,WACAS,GAAAF,EACAG,QAAA,EAUA,OANAL,GAAAE,GAAAI,KAAAV,EAAAD,QAAAC,IAAAD,QAAAM,GAGAL,EAAAS,QAAA,EAGAT,EAAAD,QAvBA,GAAAQ,KAqCA,OATAF,GAAAM,EAAAP,EAGAC,EAAAO,EAAAL,EAGAF,EAAAQ,EAAA,GAGAR,EAAA,KDgBM,SAAUL,EAAQD,EAASM,GEtDjCL,EAAAD,QAAAM,EAAA,IF4DM,SAAUL,EAAQD,EAASM,GG5DjC,YAcA,SAAAS,GAAAC,GACA,GAAAC,GAAA,GAAAC,GAAAF,GACAG,EAAAC,EAAAF,EAAAG,UAAAC,QAAAL,EAQA,OALAM,GAAAC,OAAAL,EAAAD,EAAAG,UAAAJ,GAGAM,EAAAC,OAAAL,EAAAF,GAEAE,EAtBA,GAAAI,GAAAjB,EAAA,GACAc,EAAAd,EAAA,GACAY,EAAAZ,EAAA,GACAmB,EAAAnB,EAAA,IACAoB,EAAApB,EAAA,IAsBAqB,EAAAZ,EAAAW,EAGAC,GAAAT,QAGAS,EAAAC,OAAA,SAAAC,GACA,MAAAd,GAAAU,EAAAE,EAAAD,SAAAG,KAIAF,EAAAG,OAAAxB,EAAA,IACAqB,EAAAI,YAAAzB,EAAA,IACAqB,EAAAK,SAAA1B,EAAA,GAGAqB,EAAAM,IAAA,SAAAC,GACA,MAAAC,SAAAF,IAAAC,IAEAP,EAAAS,OAAA9B,EAAA,IAGAqB,EAAAU,aAAA/B,EAAA,IAEAL,EAAAD,QAAA2B,EAGA1B,EAAAD,QAAAsC,QAAAX,GHmEM,SAAU1B,EAAQD,EAASM,GI1HjC,YAgBA,SAAAiC,GAAAC,GACA,yBAAAC,EAAA9B,KAAA6B,GASA,QAAAE,GAAAF,GACA,yBAAAA,GASA,QAAAG,GAAAH,GACA,cAAAA,IAAAE,EAAAF,IAAA,OAAAA,EAAAI,cAAAF,EAAAF,EAAAI,cACA,kBAAAJ,GAAAI,YAAAD,UAAAH,EAAAI,YAAAD,SAAAH,GASA,QAAAK,GAAAL,GACA,+BAAAC,EAAA9B,KAAA6B,GASA,QAAAM,GAAAN,GACA,yBAAAO,WAAAP,YAAAO,UASA,QAAAC,GAAAR,GACA,GAAAS,EAMA,OAJAA,GADA,mBAAAC,0BAAA,OACAA,YAAAC,OAAAX,GAEA,GAAAA,EAAA,QAAAA,EAAAY,iBAAAF,aAWA,QAAAG,GAAAb,GACA,sBAAAA,GASA,QAAAc,GAAAd,GACA,sBAAAA,GASA,QAAAe,GAAAf,GACA,cAAAA,GAAA,gBAAAA,GASA,QAAAgB,GAAAhB,GACA,uBAAAC,EAAA9B,KAAA6B,GACA,QAGA,IAAAnB,GAAAoC,OAAAC,eAAAlB,EACA,eAAAnB,OAAAoC,OAAApC,UASA,QAAAsC,GAAAnB,GACA,wBAAAC,EAAA9B,KAAA6B,GASA,QAAAoB,GAAApB,GACA,wBAAAC,EAAA9B,KAAA6B,GASA,QAAAqB,GAAArB,GACA,wBAAAC,EAAA9B,KAAA6B,GASA,QAAAsB,GAAAtB,GACA,4BAAAC,EAAA9B,KAAA6B,GASA,QAAAuB,GAAAvB,GACA,MAAAe,GAAAf,IAAAsB,EAAAtB,EAAAwB,MASA,QAAAC,GAAAzB,GACA,yBAAA0B,kBAAA1B,YAAA0B,iBASA,QAAAC,GAAAC,GACA,MAAAA,GAAAC,QAAA,WAAAA,QAAA,WAkBA,QAAAC,KACA,0BAAAC,YAAA,gBAAAA,UAAAC,SACA,iBAAAD,UAAAC,SACA,OAAAD,UAAAC,WAIA,mBAAAC,SACA,mBAAAC,WAgBA,QAAAC,GAAAC,EAAAC,GAEA,UAAAD,GAAA,mBAAAA,GAUA,GALA,gBAAAA,KAEAA,OAGArC,EAAAqC,GAEA,OAAAE,GAAA,EAAAC,EAAAH,EAAAI,OAAmCF,EAAAC,EAAOD,IAC1CD,EAAAlE,KAAA,KAAAiE,EAAAE,KAAAF,OAIA,QAAAK,KAAAL,GACAnB,OAAApC,UAAA6D,eAAAvE,KAAAiE,EAAAK,IACAJ,EAAAlE,KAAA,KAAAiE,EAAAK,KAAAL,GAuBA,QAAAO,KAEA,QAAAC,GAAA5C,EAAAyC,GACAzB,EAAAP,EAAAgC,KAAAzB,EAAAhB,GACAS,EAAAgC,GAAAE,EAAAlC,EAAAgC,GAAAzC,GACKgB,EAAAhB,GACLS,EAAAgC,GAAAE,KAA4B3C,GACvBD,EAAAC,GACLS,EAAAgC,GAAAzC,EAAA6C,QAEApC,EAAAgC,GAAAzC,EAIA,OAbAS,MAaA6B,EAAA,EAAAC,EAAAO,UAAAN,OAAuCF,EAAAC,EAAOD,IAC9CH,EAAAW,UAAAR,GAAAM,EAEA,OAAAnC,GAWA,QAAAzB,GAAA+D,EAAAC,EAAAC,GAQA,MAPAd,GAAAa,EAAA,SAAAhD,EAAAyC,GACAQ,GAAA,kBAAAjD,GACA+C,EAAAN,GAAA7D,EAAAoB,EAAAiD,GAEAF,EAAAN,GAAAzC,IAGA+C,EASA,QAAAG,GAAAC,GAIA,MAHA,SAAAA,EAAAC,WAAA,KACAD,IAAAN,MAAA,IAEAM,EAlUA,GAAAvE,GAAAd,EAAA,GAMAmC,EAAAgB,OAAApC,UAAAoB,QA+TAxC,GAAAD,SACAuC,UACAM,gBACAF,WACAG,aACAE,oBACAK,WACAC,WACAC,WACAC,gBACAd,cACAiB,SACAC,SACAC,SACAC,aACAC,WACAE,oBACAK,uBACAK,UACAQ,QACA3D,SACA2C,OACAuB,aJkIM,SAAUzF,EAAQD,GK/dxB,YAEAC,GAAAD,QAAA,SAAA6E,EAAAY,GACA,kBAEA,OADAI,GAAA,GAAAC,OAAAR,UAAAN,QACAF,EAAA,EAAmBA,EAAAe,EAAAb,OAAiBF,IACpCe,EAAAf,GAAAQ,UAAAR,EAEA,OAAAD,GAAAkB,MAAAN,EAAAI,MLweM,SAAU5F,EAAQD,EAASM,GMhfjC,YAaA,SAAAY,GAAAW,GACAzB,KAAAsB,SAAAG,EACAzB,KAAA4F,cACA1E,QAAA,GAAA2E,GACAC,SAAA,GAAAD,IAfA,GAAA1E,GAAAjB,EAAA,GACA6F,EAAA7F,EAAA,GACA2F,EAAA3F,EAAA,GACA8F,EAAA9F,EAAA,GACAmB,EAAAnB,EAAA,GAoBAY,GAAAG,UAAAC,QAAA,SAAA+E,GAGA,gBAAAA,IACAA,EAAAf,UAAA,OACAe,EAAAC,IAAAhB,UAAA,IAEAe,QAGAA,EAAA5E,EAAArB,KAAAsB,SAAA2E,GAGAA,EAAAE,OACAF,EAAAE,OAAAF,EAAAE,OAAAC,cACGpG,KAAAsB,SAAA6E,OACHF,EAAAE,OAAAnG,KAAAsB,SAAA6E,OAAAC,cAEAH,EAAAE,OAAA,KAIA,IAAAE,IAAAL,EAAAM,QACAC,EAAAxE,QAAAyE,QAAAP,EAUA,KARAjG,KAAA4F,aAAA1E,QAAAqD,QAAA,SAAAkC,GACAJ,EAAAK,QAAAD,EAAAE,UAAAF,EAAAG,YAGA5G,KAAA4F,aAAAE,SAAAvB,QAAA,SAAAkC,GACAJ,EAAAQ,KAAAJ,EAAAE,UAAAF,EAAAG,YAGAP,EAAAzB,QACA2B,IAAAO,KAAAT,EAAAU,QAAAV,EAAAU,QAGA,OAAAR,IAGAzF,EAAAG,UAAA+F,OAAA,SAAAf,GAEA,MADAA,GAAA5E,EAAArB,KAAAsB,SAAA2E,GACAF,EAAAE,EAAAC,IAAAD,EAAAgB,OAAAhB,EAAAiB,kBAAAjD,QAAA,WAIA9C,EAAAoD,SAAA,0CAAA4B,GAEArF,EAAAG,UAAAkF,GAAA,SAAAD,EAAAD,GACA,MAAAjG,MAAAkB,QAAAG,EAAA4E,OACAE,SACAD,MACAiB,MAAAlB,OAAyBkB,WAKzBhG,EAAAoD,SAAA,+BAAA4B,GAEArF,EAAAG,UAAAkF,GAAA,SAAAD,EAAAiB,EAAAlB,GACA,MAAAjG,MAAAkB,QAAAG,EAAA4E,OACAE,SACAD,MACAiB,aAKAtH,EAAAD,QAAAkB,GNufM,SAAUjB,EAAQD,EAASM,GOrlBjC,YAIA,SAAAkH,GAAAhF,GACA,MAAAiF,oBAAAjF,GACA6B,QAAA,aACAA,QAAA,YACAA,QAAA,aACAA,QAAA,YACAA,QAAA,aACAA,QAAA,aATA,GAAA9C,GAAAjB,EAAA,EAmBAL,GAAAD,QAAA,SAAAsG,EAAAe,EAAAC,GAEA,IAAAD,EACA,MAAAf,EAGA,IAAAoB,EACA,IAAAJ,EACAI,EAAAJ,EAAAD,OACG,IAAA9F,EAAA0C,kBAAAoD,GACHK,EAAAL,EAAA5E,eACG,CACH,GAAAkF,KAEApG,GAAAoD,QAAA0C,EAAA,SAAA7E,EAAAyC,GACA,OAAAzC,GAAA,mBAAAA,KAIAjB,EAAAgB,QAAAC,GACAyC,GAAA,KAEAzC,MAGAjB,EAAAoD,QAAAnC,EAAA,SAAAoF,GACArG,EAAAoC,OAAAiE,GACAA,IAAAC,cACStG,EAAAgC,SAAAqE,KACTA,EAAAE,KAAAC,UAAAH,IAEAD,EAAAV,KAAAO,EAAAvC,GAAA,IAAAuC,EAAAI,SAIAF,EAAAC,EAAAK,KAAA,KAGA,GAAAN,EAAA,CACA,GAAAO,GAAA3B,EAAA4B,QAAA,IACAD,MAAA,IACA3B,IAAAjB,MAAA,EAAA4C,IAGA3B,MAAA4B,QAAA,mBAAAR,EAGA,MAAApB,KP6lBM,SAAUrG,EAAQD,EAASM,GQjqBjC,YAIA,SAAA2F,KACA7F,KAAA+H,YAHA,GAAA5G,GAAAjB,EAAA,EAcA2F,GAAA5E,UAAA+G,IAAA,SAAArB,EAAAC,GAKA,MAJA5G,MAAA+H,SAAAlB,MACAF,YACAC,aAEA5G,KAAA+H,SAAAnD,OAAA,GAQAiB,EAAA5E,UAAAgH,MAAA,SAAA5H,GACAL,KAAA+H,SAAA1H,KACAL,KAAA+H,SAAA1H,GAAA,OAYAwF,EAAA5E,UAAAsD,QAAA,SAAAE,GACAtD,EAAAoD,QAAAvE,KAAA+H,SAAA,SAAAG,GACA,OAAAA,GACAzD,EAAAyD,MAKArI,EAAAD,QAAAiG,GRwqBM,SAAUhG,EAAQD,EAASM,GS3tBjC,YAUA,SAAAiI,GAAAlC,GACAA,EAAAmC,aACAnC,EAAAmC,YAAAC,mBAVA,GAAAlH,GAAAjB,EAAA,GACAoI,EAAApI,EAAA,GACA0B,EAAA1B,EAAA,GACAoB,EAAApB,EAAA,GAiBAL,GAAAD,QAAA,SAAAqG,GACAkC,EAAAlC,GAGAA,EAAAsC,QAAAtC,EAAAsC,YAGAtC,EAAAkB,KAAAmB,EACArC,EAAAkB,KACAlB,EAAAsC,QACAtC,EAAAuC,kBAIAvC,EAAAsC,QAAApH,EAAA4D,MACAkB,EAAAsC,QAAAE,WACAxC,EAAAsC,QAAAtC,EAAAE,YACAF,EAAAsC,SAGApH,EAAAoD,SACA,qDACA,SAAA4B,SACAF,GAAAsC,QAAApC,IAIA,IAAAuC,GAAAzC,EAAAyC,SAAApH,EAAAoH,OAEA,OAAAA,GAAAzC,GAAAa,KAAA,SAAAhB,GAUA,MATAqC,GAAAlC,GAGAH,EAAAqB,KAAAmB,EACAxC,EAAAqB,KACArB,EAAAyC,QACAtC,EAAA0C,mBAGA7C,GACG,SAAA8C,GAcH,MAbAhH,GAAAgH,KACAT,EAAAlC,GAGA2C,KAAA9C,WACA8C,EAAA9C,SAAAqB,KAAAmB,EACAM,EAAA9C,SAAAqB,KACAyB,EAAA9C,SAAAyC,QACAtC,EAAA0C,qBAKA5G,QAAA8G,OAAAD,OTouBM,SAAU/I,EAAQD,EAASM,GUhzBjC,YAEA,IAAAiB,GAAAjB,EAAA,EAUAL,GAAAD,QAAA,SAAAuH,EAAAoB,EAAAO,GAMA,MAJA3H,GAAAoD,QAAAuE,EAAA,SAAArE,GACA0C,EAAA1C,EAAA0C,EAAAoB,KAGApB,IVwzBM,SAAUtH,EAAQD,GW10BxB,YAEAC,GAAAD,QAAA,SAAAmJ,GACA,SAAAA,MAAAC,cXk1BM,SAAUnJ,EAAQD,EAASM,GYr1BjC,YASA,SAAA+I,GAAAV,EAAAQ,IACA5H,EAAAmB,YAAAiG,IAAApH,EAAAmB,YAAAiG,EAAA,mBACAA,EAAA,gBAAAQ,GAIA,QAAAG,KACA,GAAAR,EAQA,OAPA,mBAAAS,gBAEAT,EAAAxI,EAAA,IACG,mBAAAkJ,UAAA,qBAAA/F,OAAApC,UAAAoB,SAAA9B,KAAA6I,WAEHV,EAAAxI,EAAA,KAEAwI,EAtBA,GAAAvH,GAAAjB,EAAA,GACAmJ,EAAAnJ,EAAA,IAEAoJ,GACAC,eAAA,qCAqBAjI,GACAoH,QAAAQ,IAEAV,kBAAA,SAAArB,EAAAoB,GAGA,MAFAc,GAAAd,EAAA,UACAc,EAAAd,EAAA,gBACApH,EAAAuB,WAAAyE,IACAhG,EAAAsB,cAAA0E,IACAhG,EAAAoB,SAAA4E,IACAhG,EAAAwC,SAAAwD,IACAhG,EAAAqC,OAAA2D,IACAhG,EAAAsC,OAAA0D,GAEAA,EAEAhG,EAAAyB,kBAAAuE,GACAA,EAAAnE,OAEA7B,EAAA0C,kBAAAsD,IACA8B,EAAAV,EAAA,mDACApB,EAAA9E,YAEAlB,EAAAgC,SAAAgE,IACA8B,EAAAV,EAAA,kCACAb,KAAAC,UAAAR,IAEAA,IAGAwB,mBAAA,SAAAxB,GAEA,mBAAAA,GACA,IACAA,EAAAO,KAAA8B,MAAArC,GACO,MAAAsC,IAEP,MAAAtC,KAOAuC,QAAA,EAEAC,eAAA,aACAC,eAAA,eAEAC,kBAAA,EACAC,eAAA,EAEAC,eAAA,SAAAC,GACA,MAAAA,IAAA,KAAAA,EAAA,KAIA1I,GAAAiH,SACAE,QACAwB,OAAA,sCAIA9I,EAAAoD,SAAA,gCAAA4B,GACA7E,EAAAiH,QAAApC,QAGAhF,EAAAoD,SAAA,+BAAA4B,GACA7E,EAAAiH,QAAApC,GAAAhF,EAAA4D,MAAAuE,KAGAzJ,EAAAD,QAAA0B,GZ41BM,SAAUzB,EAAQD,EAASM,Ga77BjC,YAEA,IAAAiB,GAAAjB,EAAA,EAEAL,GAAAD,QAAA,SAAA2I,EAAA2B,GACA/I,EAAAoD,QAAAgE,EAAA,SAAAQ,EAAAoB,GACAA,IAAAD,GAAAC,EAAAC,gBAAAF,EAAAE,gBACA7B,EAAA2B,GAAAnB,QACAR,GAAA4B,Qbu8BM,SAAUtK,EAAQD,EAASM,Gc/8BjC,YAEA,IAAAiB,GAAAjB,EAAA,GACAmK,EAAAnK,EAAA,IACAoK,EAAApK,EAAA,IACA6F,EAAA7F,EAAA,GACAqK,EAAArK,EAAA,IACAsK,EAAAtK,EAAA,IACAuK,EAAAvK,EAAA,IACAwK,EAAAxK,EAAA,GAEAL,GAAAD,QAAA,SAAAqG,GACA,UAAAlE,SAAA,SAAAyE,EAAAqC,GACA,GAAA8B,GAAA1E,EAAAkB,KACAyD,EAAA3E,EAAAsC,OAEApH,GAAAuB,WAAAiI,UACAC,GAAA,eAGA,IAAA1J,GAAA,GAAAiI,eAGA,IAAAlD,EAAA4E,KAAA,CACA,GAAAC,GAAA7E,EAAA4E,KAAAC,UAAA,GACAC,EAAA9E,EAAA4E,KAAAE,SAAAC,SAAA3D,mBAAApB,EAAA4E,KAAAE,WAAA,EACAH,GAAAK,cAAA,SAAAC,KAAAJ,EAAA,IAAAC,GAGA,GAAAI,GAAAZ,EAAAtE,EAAAmF,QAAAnF,EAAAC,IA4EA,IA3EAhF,EAAAmK,KAAApF,EAAAE,OAAAiE,cAAArE,EAAAoF,EAAAlF,EAAAgB,OAAAhB,EAAAiB,mBAAA,GAGAhG,EAAAwI,QAAAzD,EAAAyD,QAGAxI,EAAAoK,mBAAA,WACA,GAAApK,GAAA,IAAAA,EAAAqK,aAQA,IAAArK,EAAA8I,QAAA9I,EAAAsK,aAAA,IAAAtK,EAAAsK,YAAA1D,QAAA,WAKA,GAAA2D,GAAA,yBAAAvK,GAAAsJ,EAAAtJ,EAAAwK,yBAAA,KACAC,EAAA1F,EAAA2F,cAAA,SAAA3F,EAAA2F,aAAA1K,EAAA4E,SAAA5E,EAAA2K,aACA/F,GACAqB,KAAAwE,EACA3B,OAAA9I,EAAA8I,OACA8B,WAAA5K,EAAA4K,WACAvD,QAAAkD,EACAxF,SACA/E,UAGAmJ,GAAA7D,EAAAqC,EAAA/C,GAGA5E,EAAA,OAIAA,EAAA6K,QAAA,WACA7K,IAIA2H,EAAA6B,EAAA,kBAAAzE,EAAA,eAAA/E,IAGAA,EAAA,OAIAA,EAAA8K,QAAA,WAGAnD,EAAA6B,EAAA,gBAAAzE,EAAA,KAAA/E,IAGAA,EAAA,MAIAA,EAAA+K,UAAA,WACA,GAAAC,GAAA,cAAAjG,EAAAyD,QAAA,aACAzD,GAAAiG,sBACAA,EAAAjG,EAAAiG,qBAEArD,EAAA6B,EAAAwB,EAAAjG,EAAA,eACA/E,IAGAA,EAAA,MAMAC,EAAA+C,uBAAA,CAEA,GAAAiI,IAAAlG,EAAAmG,iBAAA3B,EAAAU,KAAAlF,EAAA0D,eACAW,EAAA+B,KAAApG,EAAA0D,gBACArD,MAEA6F,KACAvB,EAAA3E,EAAA2D,gBAAAuC,GAuBA,GAlBA,oBAAAjL,IACAC,EAAAoD,QAAAqG,EAAA,SAAAxI,EAAAyC,GACA,mBAAA8F,IAAA,iBAAA9F,EAAAuB,oBAEAwE,GAAA/F,GAGA3D,EAAAoL,iBAAAzH,EAAAzC,KAMAjB,EAAAmB,YAAA2D,EAAAmG,mBACAlL,EAAAkL,kBAAAnG,EAAAmG,iBAIAnG,EAAA2F,aACA,IACA1K,EAAA0K,aAAA3F,EAAA2F,aACO,MAAAnC,GAGP,YAAAxD,EAAA2F,aACA,KAAAnC,GAMA,kBAAAxD,GAAAsG,oBACArL,EAAAsL,iBAAA,WAAAvG,EAAAsG,oBAIA,kBAAAtG,GAAAwG,kBAAAvL,EAAAwL,QACAxL,EAAAwL,OAAAF,iBAAA,WAAAvG,EAAAwG,kBAGAxG,EAAAmC,aAEAnC,EAAAmC,YAAA7B,QAAAO,KAAA,SAAA6F,GACAzL,IAIAA,EAAA0L,QACA/D,EAAA8D,GAEAzL,EAAA,QAIAyJ,IACAA,EAAA,MAIAzJ,EAAA2L,KAAAlC,Odw9BM,SAAU9K,EAAQD,EAASM,GexoCjC,YAEA,IAAAwK,GAAAxK,EAAA,GASAL,GAAAD,QAAA,SAAA4G,EAAAqC,EAAA/C,GACA,GAAAiE,GAAAjE,EAAAG,OAAA8D,cACAjE,GAAAkE,QAAAD,MAAAjE,EAAAkE,QAGAnB,EAAA6B,EACA,mCAAA5E,EAAAkE,OACAlE,EAAAG,OACA,KACAH,EAAA5E,QACA4E,IAPAU,EAAAV,KfypCM,SAAUjG,EAAQD,EAASM,GgBvqCjC,YAEA,IAAA4M,GAAA5M,EAAA,GAYAL,GAAAD,QAAA,SAAAmN,EAAA9G,EAAA+G,EAAA9L,EAAA4E,GACA,GAAAmH,GAAA,GAAAC,OAAAH,EACA,OAAAD,GAAAG,EAAAhH,EAAA+G,EAAA9L,EAAA4E,KhB+qCM,SAAUjG,EAAQD,GiB/rCxB,YAYAC,GAAAD,QAAA,SAAAqN,EAAAhH,EAAA+G,EAAA9L,EAAA4E,GA4BA,MA3BAmH,GAAAhH,SACA+G,IACAC,EAAAD,QAGAC,EAAA/L,UACA+L,EAAAnH,WACAmH,EAAAhL,cAAA,EAEAgL,EAAAE,OAAA,WACA,OAEAJ,QAAA/M,KAAA+M,QACA5C,KAAAnK,KAAAmK,KAEAiD,YAAApN,KAAAoN,YACAC,OAAArN,KAAAqN,OAEAC,SAAAtN,KAAAsN,SACAC,WAAAvN,KAAAuN,WACAC,aAAAxN,KAAAwN,aACAC,MAAAzN,KAAAyN,MAEAxH,OAAAjG,KAAAiG,OACA+G,KAAAhN,KAAAgN,OAGAC,IjBusCM,SAAUpN,EAAQD,EAASM,GkB/uCjC,YAEA,IAAAiB,GAAAjB,EAAA,EAEAL,GAAAD,QACAuB,EAAA+C,uBAGA,WACA,OACAwJ,MAAA,SAAAvD,EAAApB,EAAA4E,EAAAC,EAAAC,EAAAC,GACA,GAAAC,KACAA,GAAAlH,KAAAsD,EAAA,IAAA9C,mBAAA0B,IAEA5H,EAAA+B,SAAAyK,IACAI,EAAAlH,KAAA,cAAAmH,MAAAL,GAAAM,eAGA9M,EAAA8B,SAAA2K,IACAG,EAAAlH,KAAA,QAAA+G,GAGAzM,EAAA8B,SAAA4K,IACAE,EAAAlH,KAAA,UAAAgH,GAGAC,KAAA,GACAC,EAAAlH,KAAA,UAGAvC,SAAAyJ,SAAAnG,KAAA,OAGAyE,KAAA,SAAAlC,GACA,GAAA+D,GAAA5J,SAAAyJ,OAAAG,MAAA,GAAAC,QAAA,aAA4DhE,EAAA,aAC5D,OAAA+D,GAAAE,mBAAAF,EAAA,UAGAG,OAAA,SAAAlE,GACAnK,KAAA0N,MAAAvD,EAAA,GAAA6D,KAAAM,MAAA,YAMA,WACA,OACAZ,MAAA,aACArB,KAAA,WAA+B,aAC/BgC,OAAA,kBlByvCM,SAAUxO,EAAQD,EAASM,GmB1yCjC,YAEA,IAAAqO,GAAArO,EAAA,IACAsO,EAAAtO,EAAA,GAWAL,GAAAD,QAAA,SAAAwL,EAAAqD,GACA,MAAArD,KAAAmD,EAAAE,GACAD,EAAApD,EAAAqD,GAEAA,InBkzCM,SAAU5O,EAAQD,GoBp0CxB,YAQAC,GAAAD,QAAA,SAAAsG,GAIA,sCAAAwI,KAAAxI,KpB40CM,SAAUrG,EAAQD,GqBx1CxB,YASAC,GAAAD,QAAA,SAAAwL,EAAAuD,GACA,MAAAA,GACAvD,EAAAnH,QAAA,eAAA0K,EAAA1K,QAAA,WACAmH,IrBg2CM,SAAUvL,EAAQD,EAASM,GsB52CjC,YAEA,IAAAiB,GAAAjB,EAAA,GAIA0O,GACA,6DACA,kEACA,gEACA,qCAgBA/O,GAAAD,QAAA,SAAA2I,GACA,GACA1D,GACAzC,EACAsC,EAHAmK,IAKA,OAAAtG,IAEApH,EAAAoD,QAAAgE,EAAAuG,MAAA,eAAAC,GAKA,GAJArK,EAAAqK,EAAAjH,QAAA,KACAjD,EAAA1D,EAAA4C,KAAAgL,EAAAC,OAAA,EAAAtK,IAAA0B,cACAhE,EAAAjB,EAAA4C,KAAAgL,EAAAC,OAAAtK,EAAA,IAEAG,EAAA,CACA,GAAAgK,EAAAhK,IAAA+J,EAAA9G,QAAAjD,IAAA,EACA,MAEA,gBAAAA,EACAgK,EAAAhK,IAAAgK,EAAAhK,GAAAgK,EAAAhK,OAAAoK,QAAA7M,IAEAyM,EAAAhK,GAAAgK,EAAAhK,GAAAgK,EAAAhK,GAAA,KAAAzC,OAKAyM,GAnBiBA,ItBu4CX,SAAUhP,EAAQD,EAASM,GuBv6CjC,YAEA,IAAAiB,GAAAjB,EAAA,EAEAL,GAAAD,QACAuB,EAAA+C,uBAIA,WAWA,QAAAgL,GAAAhJ,GACA,GAAAiJ,GAAAjJ,CAWA,OATAkJ,KAEAC,EAAAC,aAAA,OAAAH,GACAA,EAAAE,EAAAF,MAGAE,EAAAC,aAAA,OAAAH,IAIAA,KAAAE,EAAAF,KACAI,SAAAF,EAAAE,SAAAF,EAAAE,SAAAtL,QAAA,YACAuL,KAAAH,EAAAG,KACAC,OAAAJ,EAAAI,OAAAJ,EAAAI,OAAAxL,QAAA,aACAyL,KAAAL,EAAAK,KAAAL,EAAAK,KAAAzL,QAAA,YACA0L,SAAAN,EAAAM,SACAC,KAAAP,EAAAO,KACAC,SAAA,MAAAR,EAAAQ,SAAAC,OAAA,GACAT,EAAAQ,SACA,IAAAR,EAAAQ,UAhCA,GAEAE,GAFAX,EAAA,kBAAAV,KAAAvK,UAAA6L,WACAX,EAAA/K,SAAA2L,cAAA,IA2CA,OARAF,GAAAb,EAAA7K,OAAA6L,SAAAf,MAQA,SAAAgB,GACA,GAAAtB,GAAA1N,EAAA8B,SAAAkN,GAAAjB,EAAAiB,IACA,OAAAtB,GAAAU,WAAAQ,EAAAR,UACAV,EAAAW,OAAAO,EAAAP,SAKA,WACA,kBACA,cvBi7CM,SAAU3P,EAAQD,EAASM,GwBj/CjC,YAEA,IAAAiB,GAAAjB,EAAA,EAUAL,GAAAD,QAAA,SAAAwQ,EAAAC,GAgBA,QAAAC,GAAAC,EAAAC,GACA,MAAArP,GAAAiC,cAAAmN,IAAApP,EAAAiC,cAAAoN,GACArP,EAAA4D,MAAAwL,EAAAC,GACKrP,EAAAiC,cAAAoN,GACLrP,EAAA4D,SAA2ByL,GACtBrP,EAAAgB,QAAAqO,GACLA,EAAAvL,QAEAuL,EAGA,QAAAC,GAAAC,GACAvP,EAAAmB,YAAA+N,EAAAK,IAEKvP,EAAAmB,YAAA8N,EAAAM,MACLzK,EAAAyK,GAAAJ,EAAAhK,OAAA8J,EAAAM,KAFAzK,EAAAyK,GAAAJ,EAAAF,EAAAM,GAAAL,EAAAK,IA3BAL,OACA,IAAApK,MAEA0K,GAAA,uBACAC,GAAA,mCACAC,GACA,oEACA,uFACA,sEACA,0EACA,4DAEAC,GAAA,iBAqBA3P,GAAAoD,QAAAoM,EAAA,SAAAD,GACAvP,EAAAmB,YAAA+N,EAAAK,MACAzK,EAAAyK,GAAAJ,EAAAhK,OAAA+J,EAAAK,OAIAvP,EAAAoD,QAAAqM,EAAAH,GAEAtP,EAAAoD,QAAAsM,EAAA,SAAAH,GACAvP,EAAAmB,YAAA+N,EAAAK,IAEKvP,EAAAmB,YAAA8N,EAAAM,MACLzK,EAAAyK,GAAAJ,EAAAhK,OAAA8J,EAAAM,KAFAzK,EAAAyK,GAAAJ,EAAAhK,OAAA+J,EAAAK,MAMAvP,EAAAoD,QAAAuM,EAAA,SAAAJ,GACAA,IAAAL,GACApK,EAAAyK,GAAAJ,EAAAF,EAAAM,GAAAL,EAAAK,IACKA,IAAAN,KACLnK,EAAAyK,GAAAJ,EAAAhK,OAAA8J,EAAAM,MAIA,IAAAK,GAAAJ,EACA1B,OAAA2B,GACA3B,OAAA4B,GACA5B,OAAA6B,GAEAE,EAAA3N,OACA4N,KAAAb,GACAnB,OAAA5L,OAAA4N,KAAAZ,IACAa,OAAA,SAAArM,GACA,MAAAkM,GAAAjJ,QAAAjD,MAAA,GAKA,OAFA1D,GAAAoD,QAAAyM,EAAAP,GAEAxK,IxBy/CM,SAAUpG,EAAQD,GyB9kDxB,YAQA,SAAA8B,GAAAqL,GACA/M,KAAA+M,UAGArL,EAAAT,UAAAoB,SAAA,WACA,gBAAArC,KAAA+M,QAAA,KAAA/M,KAAA+M,QAAA,KAGArL,EAAAT,UAAA+H,YAAA,EAEAnJ,EAAAD,QAAA8B,GzBqlDM,SAAU7B,EAAQD,EAASM,G0BvmDjC,YAUA,SAAAyB,GAAAwP,GACA,qBAAAA,GACA,SAAAC,WAAA,+BAGA,IAAAC,EACArR,MAAAuG,QAAA,GAAAxE,SAAA,SAAAyE,GACA6K,EAAA7K,GAGA,IAAA8K,GAAAtR,IACAmR,GAAA,SAAApE,GACAuE,EAAA1I,SAKA0I,EAAA1I,OAAA,GAAAlH,GAAAqL,GACAsE,EAAAC,EAAA1I,WA1BA,GAAAlH,GAAAxB,EAAA,GAiCAyB,GAAAV,UAAAoH,iBAAA,WACA,GAAArI,KAAA4I,OACA,KAAA5I,MAAA4I,QAQAjH,EAAA6O,OAAA,WACA,GAAA7D,GACA2E,EAAA,GAAA3P,GAAA,SAAAlB,GACAkM,EAAAlM,GAEA,QACA6Q,QACA3E,WAIA9M,EAAAD,QAAA+B,G1B8mDM,SAAU9B,EAAQD,G2BtqDxB,YAsBAC,GAAAD,QAAA,SAAA2R,GACA,gBAAAC,GACA,MAAAD,GAAA5L,MAAA,KAAA6L,M3B+qDM,SAAU3R,EAAQD,G4BvsDxB,YAQAC,GAAAD,QAAA,SAAA6R,GACA,sBAAAA,MAAAxP,gBAAA","file":"axios.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"axios\"] = factory();\n\telse\n\t\troot[\"axios\"] = factory();\n})(this, function() {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"axios\"] = factory();\n\telse\n\t\troot[\"axios\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(1);\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar bind = __webpack_require__(3);\n\tvar Axios = __webpack_require__(4);\n\tvar mergeConfig = __webpack_require__(22);\n\tvar defaults = __webpack_require__(10);\n\t\n\t/**\n\t * Create an instance of Axios\n\t *\n\t * @param {Object} defaultConfig The default config for the instance\n\t * @return {Axios} A new instance of Axios\n\t */\n\tfunction createInstance(defaultConfig) {\n\t var context = new Axios(defaultConfig);\n\t var instance = bind(Axios.prototype.request, context);\n\t\n\t // Copy axios.prototype to instance\n\t utils.extend(instance, Axios.prototype, context);\n\t\n\t // Copy context to instance\n\t utils.extend(instance, context);\n\t\n\t return instance;\n\t}\n\t\n\t// Create the default instance to be exported\n\tvar axios = createInstance(defaults);\n\t\n\t// Expose Axios class to allow class inheritance\n\taxios.Axios = Axios;\n\t\n\t// Factory for creating new instances\n\taxios.create = function create(instanceConfig) {\n\t return createInstance(mergeConfig(axios.defaults, instanceConfig));\n\t};\n\t\n\t// Expose Cancel & CancelToken\n\taxios.Cancel = __webpack_require__(23);\n\taxios.CancelToken = __webpack_require__(24);\n\taxios.isCancel = __webpack_require__(9);\n\t\n\t// Expose all/spread\n\taxios.all = function all(promises) {\n\t return Promise.all(promises);\n\t};\n\taxios.spread = __webpack_require__(25);\n\t\n\t// Expose isAxiosError\n\taxios.isAxiosError = __webpack_require__(26);\n\t\n\tmodule.exports = axios;\n\t\n\t// Allow use of default import syntax in TypeScript\n\tmodule.exports.default = axios;\n\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar bind = __webpack_require__(3);\n\t\n\t/*global toString:true*/\n\t\n\t// utils is a library of generic helper functions non-specific to axios\n\t\n\tvar toString = Object.prototype.toString;\n\t\n\t/**\n\t * Determine if a value is an Array\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an Array, otherwise false\n\t */\n\tfunction isArray(val) {\n\t return toString.call(val) === '[object Array]';\n\t}\n\t\n\t/**\n\t * Determine if a value is undefined\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if the value is undefined, otherwise false\n\t */\n\tfunction isUndefined(val) {\n\t return typeof val === 'undefined';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Buffer\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Buffer, otherwise false\n\t */\n\tfunction isBuffer(val) {\n\t return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n\t && typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val);\n\t}\n\t\n\t/**\n\t * Determine if a value is an ArrayBuffer\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n\t */\n\tfunction isArrayBuffer(val) {\n\t return toString.call(val) === '[object ArrayBuffer]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a FormData\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an FormData, otherwise false\n\t */\n\tfunction isFormData(val) {\n\t return (typeof FormData !== 'undefined') && (val instanceof FormData);\n\t}\n\t\n\t/**\n\t * Determine if a value is a view on an ArrayBuffer\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n\t */\n\tfunction isArrayBufferView(val) {\n\t var result;\n\t if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n\t result = ArrayBuffer.isView(val);\n\t } else {\n\t result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Determine if a value is a String\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a String, otherwise false\n\t */\n\tfunction isString(val) {\n\t return typeof val === 'string';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Number\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Number, otherwise false\n\t */\n\tfunction isNumber(val) {\n\t return typeof val === 'number';\n\t}\n\t\n\t/**\n\t * Determine if a value is an Object\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is an Object, otherwise false\n\t */\n\tfunction isObject(val) {\n\t return val !== null && typeof val === 'object';\n\t}\n\t\n\t/**\n\t * Determine if a value is a plain Object\n\t *\n\t * @param {Object} val The value to test\n\t * @return {boolean} True if value is a plain Object, otherwise false\n\t */\n\tfunction isPlainObject(val) {\n\t if (toString.call(val) !== '[object Object]') {\n\t return false;\n\t }\n\t\n\t var prototype = Object.getPrototypeOf(val);\n\t return prototype === null || prototype === Object.prototype;\n\t}\n\t\n\t/**\n\t * Determine if a value is a Date\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Date, otherwise false\n\t */\n\tfunction isDate(val) {\n\t return toString.call(val) === '[object Date]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a File\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a File, otherwise false\n\t */\n\tfunction isFile(val) {\n\t return toString.call(val) === '[object File]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Blob\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Blob, otherwise false\n\t */\n\tfunction isBlob(val) {\n\t return toString.call(val) === '[object Blob]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Function\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Function, otherwise false\n\t */\n\tfunction isFunction(val) {\n\t return toString.call(val) === '[object Function]';\n\t}\n\t\n\t/**\n\t * Determine if a value is a Stream\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a Stream, otherwise false\n\t */\n\tfunction isStream(val) {\n\t return isObject(val) && isFunction(val.pipe);\n\t}\n\t\n\t/**\n\t * Determine if a value is a URLSearchParams object\n\t *\n\t * @param {Object} val The value to test\n\t * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n\t */\n\tfunction isURLSearchParams(val) {\n\t return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;\n\t}\n\t\n\t/**\n\t * Trim excess whitespace off the beginning and end of a string\n\t *\n\t * @param {String} str The String to trim\n\t * @returns {String} The String freed of excess whitespace\n\t */\n\tfunction trim(str) {\n\t return str.replace(/^\\s*/, '').replace(/\\s*$/, '');\n\t}\n\t\n\t/**\n\t * Determine if we're running in a standard browser environment\n\t *\n\t * This allows axios to run in a web worker, and react-native.\n\t * Both environments support XMLHttpRequest, but not fully standard globals.\n\t *\n\t * web workers:\n\t * typeof window -> undefined\n\t * typeof document -> undefined\n\t *\n\t * react-native:\n\t * navigator.product -> 'ReactNative'\n\t * nativescript\n\t * navigator.product -> 'NativeScript' or 'NS'\n\t */\n\tfunction isStandardBrowserEnv() {\n\t if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' ||\n\t navigator.product === 'NativeScript' ||\n\t navigator.product === 'NS')) {\n\t return false;\n\t }\n\t return (\n\t typeof window !== 'undefined' &&\n\t typeof document !== 'undefined'\n\t );\n\t}\n\t\n\t/**\n\t * Iterate over an Array or an Object invoking a function for each item.\n\t *\n\t * If `obj` is an Array callback will be called passing\n\t * the value, index, and complete array for each item.\n\t *\n\t * If 'obj' is an Object callback will be called passing\n\t * the value, key, and complete object for each property.\n\t *\n\t * @param {Object|Array} obj The object to iterate\n\t * @param {Function} fn The callback to invoke for each item\n\t */\n\tfunction forEach(obj, fn) {\n\t // Don't bother if no value provided\n\t if (obj === null || typeof obj === 'undefined') {\n\t return;\n\t }\n\t\n\t // Force an array if not already something iterable\n\t if (typeof obj !== 'object') {\n\t /*eslint no-param-reassign:0*/\n\t obj = [obj];\n\t }\n\t\n\t if (isArray(obj)) {\n\t // Iterate over array values\n\t for (var i = 0, l = obj.length; i < l; i++) {\n\t fn.call(null, obj[i], i, obj);\n\t }\n\t } else {\n\t // Iterate over object keys\n\t for (var key in obj) {\n\t if (Object.prototype.hasOwnProperty.call(obj, key)) {\n\t fn.call(null, obj[key], key, obj);\n\t }\n\t }\n\t }\n\t}\n\t\n\t/**\n\t * Accepts varargs expecting each argument to be an object, then\n\t * immutably merges the properties of each object and returns result.\n\t *\n\t * When multiple objects contain the same key the later object in\n\t * the arguments list will take precedence.\n\t *\n\t * Example:\n\t *\n\t * ```js\n\t * var result = merge({foo: 123}, {foo: 456});\n\t * console.log(result.foo); // outputs 456\n\t * ```\n\t *\n\t * @param {Object} obj1 Object to merge\n\t * @returns {Object} Result of all merge properties\n\t */\n\tfunction merge(/* obj1, obj2, obj3, ... */) {\n\t var result = {};\n\t function assignValue(val, key) {\n\t if (isPlainObject(result[key]) && isPlainObject(val)) {\n\t result[key] = merge(result[key], val);\n\t } else if (isPlainObject(val)) {\n\t result[key] = merge({}, val);\n\t } else if (isArray(val)) {\n\t result[key] = val.slice();\n\t } else {\n\t result[key] = val;\n\t }\n\t }\n\t\n\t for (var i = 0, l = arguments.length; i < l; i++) {\n\t forEach(arguments[i], assignValue);\n\t }\n\t return result;\n\t}\n\t\n\t/**\n\t * Extends object a by mutably adding to it the properties of object b.\n\t *\n\t * @param {Object} a The object to be extended\n\t * @param {Object} b The object to copy properties from\n\t * @param {Object} thisArg The object to bind function to\n\t * @return {Object} The resulting value of object a\n\t */\n\tfunction extend(a, b, thisArg) {\n\t forEach(b, function assignValue(val, key) {\n\t if (thisArg && typeof val === 'function') {\n\t a[key] = bind(val, thisArg);\n\t } else {\n\t a[key] = val;\n\t }\n\t });\n\t return a;\n\t}\n\t\n\t/**\n\t * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n\t *\n\t * @param {string} content with BOM\n\t * @return {string} content value without BOM\n\t */\n\tfunction stripBOM(content) {\n\t if (content.charCodeAt(0) === 0xFEFF) {\n\t content = content.slice(1);\n\t }\n\t return content;\n\t}\n\t\n\tmodule.exports = {\n\t isArray: isArray,\n\t isArrayBuffer: isArrayBuffer,\n\t isBuffer: isBuffer,\n\t isFormData: isFormData,\n\t isArrayBufferView: isArrayBufferView,\n\t isString: isString,\n\t isNumber: isNumber,\n\t isObject: isObject,\n\t isPlainObject: isPlainObject,\n\t isUndefined: isUndefined,\n\t isDate: isDate,\n\t isFile: isFile,\n\t isBlob: isBlob,\n\t isFunction: isFunction,\n\t isStream: isStream,\n\t isURLSearchParams: isURLSearchParams,\n\t isStandardBrowserEnv: isStandardBrowserEnv,\n\t forEach: forEach,\n\t merge: merge,\n\t extend: extend,\n\t trim: trim,\n\t stripBOM: stripBOM\n\t};\n\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = function bind(fn, thisArg) {\n\t return function wrap() {\n\t var args = new Array(arguments.length);\n\t for (var i = 0; i < args.length; i++) {\n\t args[i] = arguments[i];\n\t }\n\t return fn.apply(thisArg, args);\n\t };\n\t};\n\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar buildURL = __webpack_require__(5);\n\tvar InterceptorManager = __webpack_require__(6);\n\tvar dispatchRequest = __webpack_require__(7);\n\tvar mergeConfig = __webpack_require__(22);\n\t\n\t/**\n\t * Create a new instance of Axios\n\t *\n\t * @param {Object} instanceConfig The default config for the instance\n\t */\n\tfunction Axios(instanceConfig) {\n\t this.defaults = instanceConfig;\n\t this.interceptors = {\n\t request: new InterceptorManager(),\n\t response: new InterceptorManager()\n\t };\n\t}\n\t\n\t/**\n\t * Dispatch a request\n\t *\n\t * @param {Object} config The config specific for this request (merged with this.defaults)\n\t */\n\tAxios.prototype.request = function request(config) {\n\t /*eslint no-param-reassign:0*/\n\t // Allow for axios('example/url'[, config]) a la fetch API\n\t if (typeof config === 'string') {\n\t config = arguments[1] || {};\n\t config.url = arguments[0];\n\t } else {\n\t config = config || {};\n\t }\n\t\n\t config = mergeConfig(this.defaults, config);\n\t\n\t // Set config.method\n\t if (config.method) {\n\t config.method = config.method.toLowerCase();\n\t } else if (this.defaults.method) {\n\t config.method = this.defaults.method.toLowerCase();\n\t } else {\n\t config.method = 'get';\n\t }\n\t\n\t // Hook up interceptors middleware\n\t var chain = [dispatchRequest, undefined];\n\t var promise = Promise.resolve(config);\n\t\n\t this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n\t chain.unshift(interceptor.fulfilled, interceptor.rejected);\n\t });\n\t\n\t this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n\t chain.push(interceptor.fulfilled, interceptor.rejected);\n\t });\n\t\n\t while (chain.length) {\n\t promise = promise.then(chain.shift(), chain.shift());\n\t }\n\t\n\t return promise;\n\t};\n\t\n\tAxios.prototype.getUri = function getUri(config) {\n\t config = mergeConfig(this.defaults, config);\n\t return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\\?/, '');\n\t};\n\t\n\t// Provide aliases for supported request methods\n\tutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n\t /*eslint func-names:0*/\n\t Axios.prototype[method] = function(url, config) {\n\t return this.request(mergeConfig(config || {}, {\n\t method: method,\n\t url: url,\n\t data: (config || {}).data\n\t }));\n\t };\n\t});\n\t\n\tutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n\t /*eslint func-names:0*/\n\t Axios.prototype[method] = function(url, data, config) {\n\t return this.request(mergeConfig(config || {}, {\n\t method: method,\n\t url: url,\n\t data: data\n\t }));\n\t };\n\t});\n\t\n\tmodule.exports = Axios;\n\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tfunction encode(val) {\n\t return encodeURIComponent(val).\n\t replace(/%3A/gi, ':').\n\t replace(/%24/g, '$').\n\t replace(/%2C/gi, ',').\n\t replace(/%20/g, '+').\n\t replace(/%5B/gi, '[').\n\t replace(/%5D/gi, ']');\n\t}\n\t\n\t/**\n\t * Build a URL by appending params to the end\n\t *\n\t * @param {string} url The base of the url (e.g., http://www.google.com)\n\t * @param {object} [params] The params to be appended\n\t * @returns {string} The formatted url\n\t */\n\tmodule.exports = function buildURL(url, params, paramsSerializer) {\n\t /*eslint no-param-reassign:0*/\n\t if (!params) {\n\t return url;\n\t }\n\t\n\t var serializedParams;\n\t if (paramsSerializer) {\n\t serializedParams = paramsSerializer(params);\n\t } else if (utils.isURLSearchParams(params)) {\n\t serializedParams = params.toString();\n\t } else {\n\t var parts = [];\n\t\n\t utils.forEach(params, function serialize(val, key) {\n\t if (val === null || typeof val === 'undefined') {\n\t return;\n\t }\n\t\n\t if (utils.isArray(val)) {\n\t key = key + '[]';\n\t } else {\n\t val = [val];\n\t }\n\t\n\t utils.forEach(val, function parseValue(v) {\n\t if (utils.isDate(v)) {\n\t v = v.toISOString();\n\t } else if (utils.isObject(v)) {\n\t v = JSON.stringify(v);\n\t }\n\t parts.push(encode(key) + '=' + encode(v));\n\t });\n\t });\n\t\n\t serializedParams = parts.join('&');\n\t }\n\t\n\t if (serializedParams) {\n\t var hashmarkIndex = url.indexOf('#');\n\t if (hashmarkIndex !== -1) {\n\t url = url.slice(0, hashmarkIndex);\n\t }\n\t\n\t url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n\t }\n\t\n\t return url;\n\t};\n\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tfunction InterceptorManager() {\n\t this.handlers = [];\n\t}\n\t\n\t/**\n\t * Add a new interceptor to the stack\n\t *\n\t * @param {Function} fulfilled The function to handle `then` for a `Promise`\n\t * @param {Function} rejected The function to handle `reject` for a `Promise`\n\t *\n\t * @return {Number} An ID used to remove interceptor later\n\t */\n\tInterceptorManager.prototype.use = function use(fulfilled, rejected) {\n\t this.handlers.push({\n\t fulfilled: fulfilled,\n\t rejected: rejected\n\t });\n\t return this.handlers.length - 1;\n\t};\n\t\n\t/**\n\t * Remove an interceptor from the stack\n\t *\n\t * @param {Number} id The ID that was returned by `use`\n\t */\n\tInterceptorManager.prototype.eject = function eject(id) {\n\t if (this.handlers[id]) {\n\t this.handlers[id] = null;\n\t }\n\t};\n\t\n\t/**\n\t * Iterate over all the registered interceptors\n\t *\n\t * This method is particularly useful for skipping over any\n\t * interceptors that may have become `null` calling `eject`.\n\t *\n\t * @param {Function} fn The function to call for each interceptor\n\t */\n\tInterceptorManager.prototype.forEach = function forEach(fn) {\n\t utils.forEach(this.handlers, function forEachHandler(h) {\n\t if (h !== null) {\n\t fn(h);\n\t }\n\t });\n\t};\n\t\n\tmodule.exports = InterceptorManager;\n\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar transformData = __webpack_require__(8);\n\tvar isCancel = __webpack_require__(9);\n\tvar defaults = __webpack_require__(10);\n\t\n\t/**\n\t * Throws a `Cancel` if cancellation has been requested.\n\t */\n\tfunction throwIfCancellationRequested(config) {\n\t if (config.cancelToken) {\n\t config.cancelToken.throwIfRequested();\n\t }\n\t}\n\t\n\t/**\n\t * Dispatch a request to the server using the configured adapter.\n\t *\n\t * @param {object} config The config that is to be used for the request\n\t * @returns {Promise} The Promise to be fulfilled\n\t */\n\tmodule.exports = function dispatchRequest(config) {\n\t throwIfCancellationRequested(config);\n\t\n\t // Ensure headers exist\n\t config.headers = config.headers || {};\n\t\n\t // Transform request data\n\t config.data = transformData(\n\t config.data,\n\t config.headers,\n\t config.transformRequest\n\t );\n\t\n\t // Flatten headers\n\t config.headers = utils.merge(\n\t config.headers.common || {},\n\t config.headers[config.method] || {},\n\t config.headers\n\t );\n\t\n\t utils.forEach(\n\t ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n\t function cleanHeaderConfig(method) {\n\t delete config.headers[method];\n\t }\n\t );\n\t\n\t var adapter = config.adapter || defaults.adapter;\n\t\n\t return adapter(config).then(function onAdapterResolution(response) {\n\t throwIfCancellationRequested(config);\n\t\n\t // Transform response data\n\t response.data = transformData(\n\t response.data,\n\t response.headers,\n\t config.transformResponse\n\t );\n\t\n\t return response;\n\t }, function onAdapterRejection(reason) {\n\t if (!isCancel(reason)) {\n\t throwIfCancellationRequested(config);\n\t\n\t // Transform response data\n\t if (reason && reason.response) {\n\t reason.response.data = transformData(\n\t reason.response.data,\n\t reason.response.headers,\n\t config.transformResponse\n\t );\n\t }\n\t }\n\t\n\t return Promise.reject(reason);\n\t });\n\t};\n\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\t/**\n\t * Transform the data for a request or a response\n\t *\n\t * @param {Object|String} data The data to be transformed\n\t * @param {Array} headers The headers for the request or response\n\t * @param {Array|Function} fns A single function or Array of functions\n\t * @returns {*} The resulting transformed data\n\t */\n\tmodule.exports = function transformData(data, headers, fns) {\n\t /*eslint no-param-reassign:0*/\n\t utils.forEach(fns, function transform(fn) {\n\t data = fn(data, headers);\n\t });\n\t\n\t return data;\n\t};\n\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = function isCancel(value) {\n\t return !!(value && value.__CANCEL__);\n\t};\n\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar normalizeHeaderName = __webpack_require__(11);\n\t\n\tvar DEFAULT_CONTENT_TYPE = {\n\t 'Content-Type': 'application/x-www-form-urlencoded'\n\t};\n\t\n\tfunction setContentTypeIfUnset(headers, value) {\n\t if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {\n\t headers['Content-Type'] = value;\n\t }\n\t}\n\t\n\tfunction getDefaultAdapter() {\n\t var adapter;\n\t if (typeof XMLHttpRequest !== 'undefined') {\n\t // For browsers use XHR adapter\n\t adapter = __webpack_require__(12);\n\t } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {\n\t // For node use HTTP adapter\n\t adapter = __webpack_require__(12);\n\t }\n\t return adapter;\n\t}\n\t\n\tvar defaults = {\n\t adapter: getDefaultAdapter(),\n\t\n\t transformRequest: [function transformRequest(data, headers) {\n\t normalizeHeaderName(headers, 'Accept');\n\t normalizeHeaderName(headers, 'Content-Type');\n\t if (utils.isFormData(data) ||\n\t utils.isArrayBuffer(data) ||\n\t utils.isBuffer(data) ||\n\t utils.isStream(data) ||\n\t utils.isFile(data) ||\n\t utils.isBlob(data)\n\t ) {\n\t return data;\n\t }\n\t if (utils.isArrayBufferView(data)) {\n\t return data.buffer;\n\t }\n\t if (utils.isURLSearchParams(data)) {\n\t setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');\n\t return data.toString();\n\t }\n\t if (utils.isObject(data)) {\n\t setContentTypeIfUnset(headers, 'application/json;charset=utf-8');\n\t return JSON.stringify(data);\n\t }\n\t return data;\n\t }],\n\t\n\t transformResponse: [function transformResponse(data) {\n\t /*eslint no-param-reassign:0*/\n\t if (typeof data === 'string') {\n\t try {\n\t data = JSON.parse(data);\n\t } catch (e) { /* Ignore */ }\n\t }\n\t return data;\n\t }],\n\t\n\t /**\n\t * A timeout in milliseconds to abort a request. If set to 0 (default) a\n\t * timeout is not created.\n\t */\n\t timeout: 0,\n\t\n\t xsrfCookieName: 'XSRF-TOKEN',\n\t xsrfHeaderName: 'X-XSRF-TOKEN',\n\t\n\t maxContentLength: -1,\n\t maxBodyLength: -1,\n\t\n\t validateStatus: function validateStatus(status) {\n\t return status >= 200 && status < 300;\n\t }\n\t};\n\t\n\tdefaults.headers = {\n\t common: {\n\t 'Accept': 'application/json, text/plain, */*'\n\t }\n\t};\n\t\n\tutils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {\n\t defaults.headers[method] = {};\n\t});\n\t\n\tutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n\t defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);\n\t});\n\t\n\tmodule.exports = defaults;\n\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tmodule.exports = function normalizeHeaderName(headers, normalizedName) {\n\t utils.forEach(headers, function processHeader(value, name) {\n\t if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {\n\t headers[normalizedName] = value;\n\t delete headers[name];\n\t }\n\t });\n\t};\n\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\tvar settle = __webpack_require__(13);\n\tvar cookies = __webpack_require__(16);\n\tvar buildURL = __webpack_require__(5);\n\tvar buildFullPath = __webpack_require__(17);\n\tvar parseHeaders = __webpack_require__(20);\n\tvar isURLSameOrigin = __webpack_require__(21);\n\tvar createError = __webpack_require__(14);\n\t\n\tmodule.exports = function xhrAdapter(config) {\n\t return new Promise(function dispatchXhrRequest(resolve, reject) {\n\t var requestData = config.data;\n\t var requestHeaders = config.headers;\n\t\n\t if (utils.isFormData(requestData)) {\n\t delete requestHeaders['Content-Type']; // Let the browser set it\n\t }\n\t\n\t var request = new XMLHttpRequest();\n\t\n\t // HTTP basic authentication\n\t if (config.auth) {\n\t var username = config.auth.username || '';\n\t var password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : '';\n\t requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);\n\t }\n\t\n\t var fullPath = buildFullPath(config.baseURL, config.url);\n\t request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);\n\t\n\t // Set the request timeout in MS\n\t request.timeout = config.timeout;\n\t\n\t // Listen for ready state\n\t request.onreadystatechange = function handleLoad() {\n\t if (!request || request.readyState !== 4) {\n\t return;\n\t }\n\t\n\t // The request errored out and we didn't get a response, this will be\n\t // handled by onerror instead\n\t // With one exception: request that using file: protocol, most browsers\n\t // will return status as 0 even though it's a successful request\n\t if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n\t return;\n\t }\n\t\n\t // Prepare the response\n\t var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;\n\t var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;\n\t var response = {\n\t data: responseData,\n\t status: request.status,\n\t statusText: request.statusText,\n\t headers: responseHeaders,\n\t config: config,\n\t request: request\n\t };\n\t\n\t settle(resolve, reject, response);\n\t\n\t // Clean up request\n\t request = null;\n\t };\n\t\n\t // Handle browser request cancellation (as opposed to a manual cancellation)\n\t request.onabort = function handleAbort() {\n\t if (!request) {\n\t return;\n\t }\n\t\n\t reject(createError('Request aborted', config, 'ECONNABORTED', request));\n\t\n\t // Clean up request\n\t request = null;\n\t };\n\t\n\t // Handle low level network errors\n\t request.onerror = function handleError() {\n\t // Real errors are hidden from us by the browser\n\t // onerror should only fire if it's a network error\n\t reject(createError('Network Error', config, null, request));\n\t\n\t // Clean up request\n\t request = null;\n\t };\n\t\n\t // Handle timeout\n\t request.ontimeout = function handleTimeout() {\n\t var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded';\n\t if (config.timeoutErrorMessage) {\n\t timeoutErrorMessage = config.timeoutErrorMessage;\n\t }\n\t reject(createError(timeoutErrorMessage, config, 'ECONNABORTED',\n\t request));\n\t\n\t // Clean up request\n\t request = null;\n\t };\n\t\n\t // Add xsrf header\n\t // This is only done if running in a standard browser environment.\n\t // Specifically not if we're in a web worker, or react-native.\n\t if (utils.isStandardBrowserEnv()) {\n\t // Add xsrf header\n\t var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ?\n\t cookies.read(config.xsrfCookieName) :\n\t undefined;\n\t\n\t if (xsrfValue) {\n\t requestHeaders[config.xsrfHeaderName] = xsrfValue;\n\t }\n\t }\n\t\n\t // Add headers to the request\n\t if ('setRequestHeader' in request) {\n\t utils.forEach(requestHeaders, function setRequestHeader(val, key) {\n\t if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {\n\t // Remove Content-Type if data is undefined\n\t delete requestHeaders[key];\n\t } else {\n\t // Otherwise add header to the request\n\t request.setRequestHeader(key, val);\n\t }\n\t });\n\t }\n\t\n\t // Add withCredentials to request if needed\n\t if (!utils.isUndefined(config.withCredentials)) {\n\t request.withCredentials = !!config.withCredentials;\n\t }\n\t\n\t // Add responseType to request if needed\n\t if (config.responseType) {\n\t try {\n\t request.responseType = config.responseType;\n\t } catch (e) {\n\t // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.\n\t // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.\n\t if (config.responseType !== 'json') {\n\t throw e;\n\t }\n\t }\n\t }\n\t\n\t // Handle progress if needed\n\t if (typeof config.onDownloadProgress === 'function') {\n\t request.addEventListener('progress', config.onDownloadProgress);\n\t }\n\t\n\t // Not all browsers support upload events\n\t if (typeof config.onUploadProgress === 'function' && request.upload) {\n\t request.upload.addEventListener('progress', config.onUploadProgress);\n\t }\n\t\n\t if (config.cancelToken) {\n\t // Handle cancellation\n\t config.cancelToken.promise.then(function onCanceled(cancel) {\n\t if (!request) {\n\t return;\n\t }\n\t\n\t request.abort();\n\t reject(cancel);\n\t // Clean up request\n\t request = null;\n\t });\n\t }\n\t\n\t if (!requestData) {\n\t requestData = null;\n\t }\n\t\n\t // Send the request\n\t request.send(requestData);\n\t });\n\t};\n\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar createError = __webpack_require__(14);\n\t\n\t/**\n\t * Resolve or reject a Promise based on response status.\n\t *\n\t * @param {Function} resolve A function that resolves the promise.\n\t * @param {Function} reject A function that rejects the promise.\n\t * @param {object} response The response.\n\t */\n\tmodule.exports = function settle(resolve, reject, response) {\n\t var validateStatus = response.config.validateStatus;\n\t if (!response.status || !validateStatus || validateStatus(response.status)) {\n\t resolve(response);\n\t } else {\n\t reject(createError(\n\t 'Request failed with status code ' + response.status,\n\t response.config,\n\t null,\n\t response.request,\n\t response\n\t ));\n\t }\n\t};\n\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar enhanceError = __webpack_require__(15);\n\t\n\t/**\n\t * Create an Error with the specified message, config, error code, request and response.\n\t *\n\t * @param {string} message The error message.\n\t * @param {Object} config The config.\n\t * @param {string} [code] The error code (for example, 'ECONNABORTED').\n\t * @param {Object} [request] The request.\n\t * @param {Object} [response] The response.\n\t * @returns {Error} The created error.\n\t */\n\tmodule.exports = function createError(message, config, code, request, response) {\n\t var error = new Error(message);\n\t return enhanceError(error, config, code, request, response);\n\t};\n\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Update an Error with the specified config, error code, and response.\n\t *\n\t * @param {Error} error The error to update.\n\t * @param {Object} config The config.\n\t * @param {string} [code] The error code (for example, 'ECONNABORTED').\n\t * @param {Object} [request] The request.\n\t * @param {Object} [response] The response.\n\t * @returns {Error} The error.\n\t */\n\tmodule.exports = function enhanceError(error, config, code, request, response) {\n\t error.config = config;\n\t if (code) {\n\t error.code = code;\n\t }\n\t\n\t error.request = request;\n\t error.response = response;\n\t error.isAxiosError = true;\n\t\n\t error.toJSON = function toJSON() {\n\t return {\n\t // Standard\n\t message: this.message,\n\t name: this.name,\n\t // Microsoft\n\t description: this.description,\n\t number: this.number,\n\t // Mozilla\n\t fileName: this.fileName,\n\t lineNumber: this.lineNumber,\n\t columnNumber: this.columnNumber,\n\t stack: this.stack,\n\t // Axios\n\t config: this.config,\n\t code: this.code\n\t };\n\t };\n\t return error;\n\t};\n\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tmodule.exports = (\n\t utils.isStandardBrowserEnv() ?\n\t\n\t // Standard browser envs support document.cookie\n\t (function standardBrowserEnv() {\n\t return {\n\t write: function write(name, value, expires, path, domain, secure) {\n\t var cookie = [];\n\t cookie.push(name + '=' + encodeURIComponent(value));\n\t\n\t if (utils.isNumber(expires)) {\n\t cookie.push('expires=' + new Date(expires).toGMTString());\n\t }\n\t\n\t if (utils.isString(path)) {\n\t cookie.push('path=' + path);\n\t }\n\t\n\t if (utils.isString(domain)) {\n\t cookie.push('domain=' + domain);\n\t }\n\t\n\t if (secure === true) {\n\t cookie.push('secure');\n\t }\n\t\n\t document.cookie = cookie.join('; ');\n\t },\n\t\n\t read: function read(name) {\n\t var match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n\t return (match ? decodeURIComponent(match[3]) : null);\n\t },\n\t\n\t remove: function remove(name) {\n\t this.write(name, '', Date.now() - 86400000);\n\t }\n\t };\n\t })() :\n\t\n\t // Non standard browser env (web workers, react-native) lack needed support.\n\t (function nonStandardBrowserEnv() {\n\t return {\n\t write: function write() {},\n\t read: function read() { return null; },\n\t remove: function remove() {}\n\t };\n\t })()\n\t);\n\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar isAbsoluteURL = __webpack_require__(18);\n\tvar combineURLs = __webpack_require__(19);\n\t\n\t/**\n\t * Creates a new URL by combining the baseURL with the requestedURL,\n\t * only when the requestedURL is not already an absolute URL.\n\t * If the requestURL is absolute, this function returns the requestedURL untouched.\n\t *\n\t * @param {string} baseURL The base URL\n\t * @param {string} requestedURL Absolute or relative URL to combine\n\t * @returns {string} The combined full path\n\t */\n\tmodule.exports = function buildFullPath(baseURL, requestedURL) {\n\t if (baseURL && !isAbsoluteURL(requestedURL)) {\n\t return combineURLs(baseURL, requestedURL);\n\t }\n\t return requestedURL;\n\t};\n\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Determines whether the specified URL is absolute\n\t *\n\t * @param {string} url The URL to test\n\t * @returns {boolean} True if the specified URL is absolute, otherwise false\n\t */\n\tmodule.exports = function isAbsoluteURL(url) {\n\t // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n\t // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n\t // by any combination of letters, digits, plus, period, or hyphen.\n\t return /^([a-z][a-z\\d\\+\\-\\.]*:)?\\/\\//i.test(url);\n\t};\n\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Creates a new URL by combining the specified URLs\n\t *\n\t * @param {string} baseURL The base URL\n\t * @param {string} relativeURL The relative URL\n\t * @returns {string} The combined URL\n\t */\n\tmodule.exports = function combineURLs(baseURL, relativeURL) {\n\t return relativeURL\n\t ? baseURL.replace(/\\/+$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n\t : baseURL;\n\t};\n\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\t// Headers whose duplicates are ignored by node\n\t// c.f. https://nodejs.org/api/http.html#http_message_headers\n\tvar ignoreDuplicateOf = [\n\t 'age', 'authorization', 'content-length', 'content-type', 'etag',\n\t 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n\t 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n\t 'referer', 'retry-after', 'user-agent'\n\t];\n\t\n\t/**\n\t * Parse headers into an object\n\t *\n\t * ```\n\t * Date: Wed, 27 Aug 2014 08:58:49 GMT\n\t * Content-Type: application/json\n\t * Connection: keep-alive\n\t * Transfer-Encoding: chunked\n\t * ```\n\t *\n\t * @param {String} headers Headers needing to be parsed\n\t * @returns {Object} Headers parsed into an object\n\t */\n\tmodule.exports = function parseHeaders(headers) {\n\t var parsed = {};\n\t var key;\n\t var val;\n\t var i;\n\t\n\t if (!headers) { return parsed; }\n\t\n\t utils.forEach(headers.split('\\n'), function parser(line) {\n\t i = line.indexOf(':');\n\t key = utils.trim(line.substr(0, i)).toLowerCase();\n\t val = utils.trim(line.substr(i + 1));\n\t\n\t if (key) {\n\t if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {\n\t return;\n\t }\n\t if (key === 'set-cookie') {\n\t parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);\n\t } else {\n\t parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n\t }\n\t }\n\t });\n\t\n\t return parsed;\n\t};\n\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\tmodule.exports = (\n\t utils.isStandardBrowserEnv() ?\n\t\n\t // Standard browser envs have full support of the APIs needed to test\n\t // whether the request URL is of the same origin as current location.\n\t (function standardBrowserEnv() {\n\t var msie = /(msie|trident)/i.test(navigator.userAgent);\n\t var urlParsingNode = document.createElement('a');\n\t var originURL;\n\t\n\t /**\n\t * Parse a URL to discover it's components\n\t *\n\t * @param {String} url The URL to be parsed\n\t * @returns {Object}\n\t */\n\t function resolveURL(url) {\n\t var href = url;\n\t\n\t if (msie) {\n\t // IE needs attribute set twice to normalize properties\n\t urlParsingNode.setAttribute('href', href);\n\t href = urlParsingNode.href;\n\t }\n\t\n\t urlParsingNode.setAttribute('href', href);\n\t\n\t // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n\t return {\n\t href: urlParsingNode.href,\n\t protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n\t host: urlParsingNode.host,\n\t search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n\t hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n\t hostname: urlParsingNode.hostname,\n\t port: urlParsingNode.port,\n\t pathname: (urlParsingNode.pathname.charAt(0) === '/') ?\n\t urlParsingNode.pathname :\n\t '/' + urlParsingNode.pathname\n\t };\n\t }\n\t\n\t originURL = resolveURL(window.location.href);\n\t\n\t /**\n\t * Determine if a URL shares the same origin as the current location\n\t *\n\t * @param {String} requestURL The URL to test\n\t * @returns {boolean} True if URL shares the same origin, otherwise false\n\t */\n\t return function isURLSameOrigin(requestURL) {\n\t var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;\n\t return (parsed.protocol === originURL.protocol &&\n\t parsed.host === originURL.host);\n\t };\n\t })() :\n\t\n\t // Non standard browser envs (web workers, react-native) lack needed support.\n\t (function nonStandardBrowserEnv() {\n\t return function isURLSameOrigin() {\n\t return true;\n\t };\n\t })()\n\t);\n\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar utils = __webpack_require__(2);\n\t\n\t/**\n\t * Config-specific merge-function which creates a new config-object\n\t * by merging two configuration objects together.\n\t *\n\t * @param {Object} config1\n\t * @param {Object} config2\n\t * @returns {Object} New object resulting from merging config2 to config1\n\t */\n\tmodule.exports = function mergeConfig(config1, config2) {\n\t // eslint-disable-next-line no-param-reassign\n\t config2 = config2 || {};\n\t var config = {};\n\t\n\t var valueFromConfig2Keys = ['url', 'method', 'data'];\n\t var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy', 'params'];\n\t var defaultToConfig2Keys = [\n\t 'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer',\n\t 'timeout', 'timeoutMessage', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',\n\t 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'decompress',\n\t 'maxContentLength', 'maxBodyLength', 'maxRedirects', 'transport', 'httpAgent',\n\t 'httpsAgent', 'cancelToken', 'socketPath', 'responseEncoding'\n\t ];\n\t var directMergeKeys = ['validateStatus'];\n\t\n\t function getMergedValue(target, source) {\n\t if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n\t return utils.merge(target, source);\n\t } else if (utils.isPlainObject(source)) {\n\t return utils.merge({}, source);\n\t } else if (utils.isArray(source)) {\n\t return source.slice();\n\t }\n\t return source;\n\t }\n\t\n\t function mergeDeepProperties(prop) {\n\t if (!utils.isUndefined(config2[prop])) {\n\t config[prop] = getMergedValue(config1[prop], config2[prop]);\n\t } else if (!utils.isUndefined(config1[prop])) {\n\t config[prop] = getMergedValue(undefined, config1[prop]);\n\t }\n\t }\n\t\n\t utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) {\n\t if (!utils.isUndefined(config2[prop])) {\n\t config[prop] = getMergedValue(undefined, config2[prop]);\n\t }\n\t });\n\t\n\t utils.forEach(mergeDeepPropertiesKeys, mergeDeepProperties);\n\t\n\t utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) {\n\t if (!utils.isUndefined(config2[prop])) {\n\t config[prop] = getMergedValue(undefined, config2[prop]);\n\t } else if (!utils.isUndefined(config1[prop])) {\n\t config[prop] = getMergedValue(undefined, config1[prop]);\n\t }\n\t });\n\t\n\t utils.forEach(directMergeKeys, function merge(prop) {\n\t if (prop in config2) {\n\t config[prop] = getMergedValue(config1[prop], config2[prop]);\n\t } else if (prop in config1) {\n\t config[prop] = getMergedValue(undefined, config1[prop]);\n\t }\n\t });\n\t\n\t var axiosKeys = valueFromConfig2Keys\n\t .concat(mergeDeepPropertiesKeys)\n\t .concat(defaultToConfig2Keys)\n\t .concat(directMergeKeys);\n\t\n\t var otherKeys = Object\n\t .keys(config1)\n\t .concat(Object.keys(config2))\n\t .filter(function filterAxiosKeys(key) {\n\t return axiosKeys.indexOf(key) === -1;\n\t });\n\t\n\t utils.forEach(otherKeys, mergeDeepProperties);\n\t\n\t return config;\n\t};\n\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * A `Cancel` is an object that is thrown when an operation is canceled.\n\t *\n\t * @class\n\t * @param {string=} message The message.\n\t */\n\tfunction Cancel(message) {\n\t this.message = message;\n\t}\n\t\n\tCancel.prototype.toString = function toString() {\n\t return 'Cancel' + (this.message ? ': ' + this.message : '');\n\t};\n\t\n\tCancel.prototype.__CANCEL__ = true;\n\t\n\tmodule.exports = Cancel;\n\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar Cancel = __webpack_require__(23);\n\t\n\t/**\n\t * A `CancelToken` is an object that can be used to request cancellation of an operation.\n\t *\n\t * @class\n\t * @param {Function} executor The executor function.\n\t */\n\tfunction CancelToken(executor) {\n\t if (typeof executor !== 'function') {\n\t throw new TypeError('executor must be a function.');\n\t }\n\t\n\t var resolvePromise;\n\t this.promise = new Promise(function promiseExecutor(resolve) {\n\t resolvePromise = resolve;\n\t });\n\t\n\t var token = this;\n\t executor(function cancel(message) {\n\t if (token.reason) {\n\t // Cancellation has already been requested\n\t return;\n\t }\n\t\n\t token.reason = new Cancel(message);\n\t resolvePromise(token.reason);\n\t });\n\t}\n\t\n\t/**\n\t * Throws a `Cancel` if cancellation has been requested.\n\t */\n\tCancelToken.prototype.throwIfRequested = function throwIfRequested() {\n\t if (this.reason) {\n\t throw this.reason;\n\t }\n\t};\n\t\n\t/**\n\t * Returns an object that contains a new `CancelToken` and a function that, when called,\n\t * cancels the `CancelToken`.\n\t */\n\tCancelToken.source = function source() {\n\t var cancel;\n\t var token = new CancelToken(function executor(c) {\n\t cancel = c;\n\t });\n\t return {\n\t token: token,\n\t cancel: cancel\n\t };\n\t};\n\t\n\tmodule.exports = CancelToken;\n\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Syntactic sugar for invoking a function and expanding an array for arguments.\n\t *\n\t * Common use case would be to use `Function.prototype.apply`.\n\t *\n\t * ```js\n\t * function f(x, y, z) {}\n\t * var args = [1, 2, 3];\n\t * f.apply(null, args);\n\t * ```\n\t *\n\t * With `spread` this example can be re-written.\n\t *\n\t * ```js\n\t * spread(function(x, y, z) {})([1, 2, 3]);\n\t * ```\n\t *\n\t * @param {Function} callback\n\t * @returns {Function}\n\t */\n\tmodule.exports = function spread(callback) {\n\t return function wrap(arr) {\n\t return callback.apply(null, arr);\n\t };\n\t};\n\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports) {\n\n\t'use strict';\n\t\n\t/**\n\t * Determines whether the payload is an error thrown by Axios\n\t *\n\t * @param {*} payload The value to test\n\t * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n\t */\n\tmodule.exports = function isAxiosError(payload) {\n\t return (typeof payload === 'object') && (payload.isAxiosError === true);\n\t};\n\n\n/***/ })\n/******/ ])\n});\n;\n\n\n// WEBPACK FOOTER //\n// axios.min.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 081842adca0968bb3270","module.exports = require('./lib/axios');\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./index.js\n// module id = 0\n// module chunks = 0","'use strict';\n\nvar utils = require('./utils');\nvar bind = require('./helpers/bind');\nvar Axios = require('./core/Axios');\nvar mergeConfig = require('./core/mergeConfig');\nvar defaults = require('./defaults');\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n * @return {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n var context = new Axios(defaultConfig);\n var instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context);\n\n // Copy context to instance\n utils.extend(instance, context);\n\n return instance;\n}\n\n// Create the default instance to be exported\nvar axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Factory for creating new instances\naxios.create = function create(instanceConfig) {\n return createInstance(mergeConfig(axios.defaults, instanceConfig));\n};\n\n// Expose Cancel & CancelToken\naxios.Cancel = require('./cancel/Cancel');\naxios.CancelToken = require('./cancel/CancelToken');\naxios.isCancel = require('./cancel/isCancel');\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\naxios.spread = require('./helpers/spread');\n\n// Expose isAxiosError\naxios.isAxiosError = require('./helpers/isAxiosError');\n\nmodule.exports = axios;\n\n// Allow use of default import syntax in TypeScript\nmodule.exports.default = axios;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/axios.js\n// module id = 1\n// module chunks = 0","'use strict';\n\nvar bind = require('./helpers/bind');\n\n/*global toString:true*/\n\n// utils is a library of generic helper functions non-specific to axios\n\nvar toString = Object.prototype.toString;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an Array, otherwise false\n */\nfunction isArray(val) {\n return toString.call(val) === '[object Array]';\n}\n\n/**\n * Determine if a value is undefined\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nfunction isUndefined(val) {\n return typeof val === 'undefined';\n}\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nfunction isArrayBuffer(val) {\n return toString.call(val) === '[object ArrayBuffer]';\n}\n\n/**\n * Determine if a value is a FormData\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nfunction isFormData(val) {\n return (typeof FormData !== 'undefined') && (val instanceof FormData);\n}\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n var result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a String, otherwise false\n */\nfunction isString(val) {\n return typeof val === 'string';\n}\n\n/**\n * Determine if a value is a Number\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Number, otherwise false\n */\nfunction isNumber(val) {\n return typeof val === 'number';\n}\n\n/**\n * Determine if a value is an Object\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an Object, otherwise false\n */\nfunction isObject(val) {\n return val !== null && typeof val === 'object';\n}\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {Object} val The value to test\n * @return {boolean} True if value is a plain Object, otherwise false\n */\nfunction isPlainObject(val) {\n if (toString.call(val) !== '[object Object]') {\n return false;\n }\n\n var prototype = Object.getPrototypeOf(val);\n return prototype === null || prototype === Object.prototype;\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Date, otherwise false\n */\nfunction isDate(val) {\n return toString.call(val) === '[object Date]';\n}\n\n/**\n * Determine if a value is a File\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a File, otherwise false\n */\nfunction isFile(val) {\n return toString.call(val) === '[object File]';\n}\n\n/**\n * Determine if a value is a Blob\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nfunction isBlob(val) {\n return toString.call(val) === '[object Blob]';\n}\n\n/**\n * Determine if a value is a Function\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nfunction isFunction(val) {\n return toString.call(val) === '[object Function]';\n}\n\n/**\n * Determine if a value is a Stream\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nfunction isStream(val) {\n return isObject(val) && isFunction(val.pipe);\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nfunction isURLSearchParams(val) {\n return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;\n}\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n * @returns {String} The String freed of excess whitespace\n */\nfunction trim(str) {\n return str.replace(/^\\s*/, '').replace(/\\s*$/, '');\n}\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n */\nfunction isStandardBrowserEnv() {\n if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' ||\n navigator.product === 'NativeScript' ||\n navigator.product === 'NS')) {\n return false;\n }\n return (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined'\n );\n}\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n */\nfunction forEach(obj, fn) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (var i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Iterate over object keys\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n fn.call(null, obj[key], key, obj);\n }\n }\n }\n}\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n var result = {};\n function assignValue(val, key) {\n if (isPlainObject(result[key]) && isPlainObject(val)) {\n result[key] = merge(result[key], val);\n } else if (isPlainObject(val)) {\n result[key] = merge({}, val);\n } else if (isArray(val)) {\n result[key] = val.slice();\n } else {\n result[key] = val;\n }\n }\n\n for (var i = 0, l = arguments.length; i < l; i++) {\n forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n * @return {Object} The resulting value of object a\n */\nfunction extend(a, b, thisArg) {\n forEach(b, function assignValue(val, key) {\n if (thisArg && typeof val === 'function') {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n });\n return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n * @return {string} content value without BOM\n */\nfunction stripBOM(content) {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n}\n\nmodule.exports = {\n isArray: isArray,\n isArrayBuffer: isArrayBuffer,\n isBuffer: isBuffer,\n isFormData: isFormData,\n isArrayBufferView: isArrayBufferView,\n isString: isString,\n isNumber: isNumber,\n isObject: isObject,\n isPlainObject: isPlainObject,\n isUndefined: isUndefined,\n isDate: isDate,\n isFile: isFile,\n isBlob: isBlob,\n isFunction: isFunction,\n isStream: isStream,\n isURLSearchParams: isURLSearchParams,\n isStandardBrowserEnv: isStandardBrowserEnv,\n forEach: forEach,\n merge: merge,\n extend: extend,\n trim: trim,\n stripBOM: stripBOM\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/utils.js\n// module id = 2\n// module chunks = 0","'use strict';\n\nmodule.exports = function bind(fn, thisArg) {\n return function wrap() {\n var args = new Array(arguments.length);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i];\n }\n return fn.apply(thisArg, args);\n };\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/helpers/bind.js\n// module id = 3\n// module chunks = 0","'use strict';\n\nvar utils = require('./../utils');\nvar buildURL = require('../helpers/buildURL');\nvar InterceptorManager = require('./InterceptorManager');\nvar dispatchRequest = require('./dispatchRequest');\nvar mergeConfig = require('./mergeConfig');\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n */\nfunction Axios(instanceConfig) {\n this.defaults = instanceConfig;\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n}\n\n/**\n * Dispatch a request\n *\n * @param {Object} config The config specific for this request (merged with this.defaults)\n */\nAxios.prototype.request = function request(config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof config === 'string') {\n config = arguments[1] || {};\n config.url = arguments[0];\n } else {\n config = config || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n // Set config.method\n if (config.method) {\n config.method = config.method.toLowerCase();\n } else if (this.defaults.method) {\n config.method = this.defaults.method.toLowerCase();\n } else {\n config.method = 'get';\n }\n\n // Hook up interceptors middleware\n var chain = [dispatchRequest, undefined];\n var promise = Promise.resolve(config);\n\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n chain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n chain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n while (chain.length) {\n promise = promise.then(chain.shift(), chain.shift());\n }\n\n return promise;\n};\n\nAxios.prototype.getUri = function getUri(config) {\n config = mergeConfig(this.defaults, config);\n return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\\?/, '');\n};\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method: method,\n url: url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method: method,\n url: url,\n data: data\n }));\n };\n});\n\nmodule.exports = Axios;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/core/Axios.js\n// module id = 4\n// module chunks = 0","'use strict';\n\nvar utils = require('./../utils');\n\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+').\n replace(/%5B/gi, '[').\n replace(/%5D/gi, ']');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @returns {string} The formatted url\n */\nmodule.exports = function buildURL(url, params, paramsSerializer) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n\n var serializedParams;\n if (paramsSerializer) {\n serializedParams = paramsSerializer(params);\n } else if (utils.isURLSearchParams(params)) {\n serializedParams = params.toString();\n } else {\n var parts = [];\n\n utils.forEach(params, function serialize(val, key) {\n if (val === null || typeof val === 'undefined') {\n return;\n }\n\n if (utils.isArray(val)) {\n key = key + '[]';\n } else {\n val = [val];\n }\n\n utils.forEach(val, function parseValue(v) {\n if (utils.isDate(v)) {\n v = v.toISOString();\n } else if (utils.isObject(v)) {\n v = JSON.stringify(v);\n }\n parts.push(encode(key) + '=' + encode(v));\n });\n });\n\n serializedParams = parts.join('&');\n }\n\n if (serializedParams) {\n var hashmarkIndex = url.indexOf('#');\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/helpers/buildURL.js\n// module id = 5\n// module chunks = 0","'use strict';\n\nvar utils = require('./../utils');\n\nfunction InterceptorManager() {\n this.handlers = [];\n}\n\n/**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\nInterceptorManager.prototype.use = function use(fulfilled, rejected) {\n this.handlers.push({\n fulfilled: fulfilled,\n rejected: rejected\n });\n return this.handlers.length - 1;\n};\n\n/**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n */\nInterceptorManager.prototype.eject = function eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n};\n\n/**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n */\nInterceptorManager.prototype.forEach = function forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n};\n\nmodule.exports = InterceptorManager;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/core/InterceptorManager.js\n// module id = 6\n// module chunks = 0","'use strict';\n\nvar utils = require('./../utils');\nvar transformData = require('./transformData');\nvar isCancel = require('../cancel/isCancel');\nvar defaults = require('../defaults');\n\n/**\n * Throws a `Cancel` if cancellation has been requested.\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n * @returns {Promise} The Promise to be fulfilled\n */\nmodule.exports = function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n // Ensure headers exist\n config.headers = config.headers || {};\n\n // Transform request data\n config.data = transformData(\n config.data,\n config.headers,\n config.transformRequest\n );\n\n // Flatten headers\n config.headers = utils.merge(\n config.headers.common || {},\n config.headers[config.method] || {},\n config.headers\n );\n\n utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n function cleanHeaderConfig(method) {\n delete config.headers[method];\n }\n );\n\n var adapter = config.adapter || defaults.adapter;\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData(\n response.data,\n response.headers,\n config.transformResponse\n );\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData(\n reason.response.data,\n reason.response.headers,\n config.transformResponse\n );\n }\n }\n\n return Promise.reject(reason);\n });\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/core/dispatchRequest.js\n// module id = 7\n// module chunks = 0","'use strict';\n\nvar utils = require('./../utils');\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Object|String} data The data to be transformed\n * @param {Array} headers The headers for the request or response\n * @param {Array|Function} fns A single function or Array of functions\n * @returns {*} The resulting transformed data\n */\nmodule.exports = function transformData(data, headers, fns) {\n /*eslint no-param-reassign:0*/\n utils.forEach(fns, function transform(fn) {\n data = fn(data, headers);\n });\n\n return data;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/core/transformData.js\n// module id = 8\n// module chunks = 0","'use strict';\n\nmodule.exports = function isCancel(value) {\n return !!(value && value.__CANCEL__);\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/cancel/isCancel.js\n// module id = 9\n// module chunks = 0","'use strict';\n\nvar utils = require('./utils');\nvar normalizeHeaderName = require('./helpers/normalizeHeaderName');\n\nvar DEFAULT_CONTENT_TYPE = {\n 'Content-Type': 'application/x-www-form-urlencoded'\n};\n\nfunction setContentTypeIfUnset(headers, value) {\n if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {\n headers['Content-Type'] = value;\n }\n}\n\nfunction getDefaultAdapter() {\n var adapter;\n if (typeof XMLHttpRequest !== 'undefined') {\n // For browsers use XHR adapter\n adapter = require('./adapters/xhr');\n } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {\n // For node use HTTP adapter\n adapter = require('./adapters/http');\n }\n return adapter;\n}\n\nvar defaults = {\n adapter: getDefaultAdapter(),\n\n transformRequest: [function transformRequest(data, headers) {\n normalizeHeaderName(headers, 'Accept');\n normalizeHeaderName(headers, 'Content-Type');\n if (utils.isFormData(data) ||\n utils.isArrayBuffer(data) ||\n utils.isBuffer(data) ||\n utils.isStream(data) ||\n utils.isFile(data) ||\n utils.isBlob(data)\n ) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isURLSearchParams(data)) {\n setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');\n return data.toString();\n }\n if (utils.isObject(data)) {\n setContentTypeIfUnset(headers, 'application/json;charset=utf-8');\n return JSON.stringify(data);\n }\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n /*eslint no-param-reassign:0*/\n if (typeof data === 'string') {\n try {\n data = JSON.parse(data);\n } catch (e) { /* Ignore */ }\n }\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n }\n};\n\ndefaults.headers = {\n common: {\n 'Accept': 'application/json, text/plain, */*'\n }\n};\n\nutils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {\n defaults.headers[method] = {};\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);\n});\n\nmodule.exports = defaults;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/defaults.js\n// module id = 10\n// module chunks = 0","'use strict';\n\nvar utils = require('../utils');\n\nmodule.exports = function normalizeHeaderName(headers, normalizedName) {\n utils.forEach(headers, function processHeader(value, name) {\n if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {\n headers[normalizedName] = value;\n delete headers[name];\n }\n });\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/helpers/normalizeHeaderName.js\n// module id = 11\n// module chunks = 0","'use strict';\n\nvar utils = require('./../utils');\nvar settle = require('./../core/settle');\nvar cookies = require('./../helpers/cookies');\nvar buildURL = require('./../helpers/buildURL');\nvar buildFullPath = require('../core/buildFullPath');\nvar parseHeaders = require('./../helpers/parseHeaders');\nvar isURLSameOrigin = require('./../helpers/isURLSameOrigin');\nvar createError = require('../core/createError');\n\nmodule.exports = function xhrAdapter(config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n var requestData = config.data;\n var requestHeaders = config.headers;\n\n if (utils.isFormData(requestData)) {\n delete requestHeaders['Content-Type']; // Let the browser set it\n }\n\n var request = new XMLHttpRequest();\n\n // HTTP basic authentication\n if (config.auth) {\n var username = config.auth.username || '';\n var password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : '';\n requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);\n }\n\n var fullPath = buildFullPath(config.baseURL, config.url);\n request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);\n\n // Set the request timeout in MS\n request.timeout = config.timeout;\n\n // Listen for ready state\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n\n // Prepare the response\n var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;\n var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;\n var response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config: config,\n request: request\n };\n\n settle(resolve, reject, response);\n\n // Clean up request\n request = null;\n };\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(createError('Request aborted', config, 'ECONNABORTED', request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError() {\n // Real errors are hidden from us by the browser\n // onerror should only fire if it's a network error\n reject(createError('Network Error', config, null, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle timeout\n request.ontimeout = function handleTimeout() {\n var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded';\n if (config.timeoutErrorMessage) {\n timeoutErrorMessage = config.timeoutErrorMessage;\n }\n reject(createError(timeoutErrorMessage, config, 'ECONNABORTED',\n request));\n\n // Clean up request\n request = null;\n };\n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n if (utils.isStandardBrowserEnv()) {\n // Add xsrf header\n var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ?\n cookies.read(config.xsrfCookieName) :\n undefined;\n\n if (xsrfValue) {\n requestHeaders[config.xsrfHeaderName] = xsrfValue;\n }\n }\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders, function setRequestHeader(val, key) {\n if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {\n // Remove Content-Type if data is undefined\n delete requestHeaders[key];\n } else {\n // Otherwise add header to the request\n request.setRequestHeader(key, val);\n }\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(config.withCredentials)) {\n request.withCredentials = !!config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (config.responseType) {\n try {\n request.responseType = config.responseType;\n } catch (e) {\n // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.\n // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.\n if (config.responseType !== 'json') {\n throw e;\n }\n }\n }\n\n // Handle progress if needed\n if (typeof config.onDownloadProgress === 'function') {\n request.addEventListener('progress', config.onDownloadProgress);\n }\n\n // Not all browsers support upload events\n if (typeof config.onUploadProgress === 'function' && request.upload) {\n request.upload.addEventListener('progress', config.onUploadProgress);\n }\n\n if (config.cancelToken) {\n // Handle cancellation\n config.cancelToken.promise.then(function onCanceled(cancel) {\n if (!request) {\n return;\n }\n\n request.abort();\n reject(cancel);\n // Clean up request\n request = null;\n });\n }\n\n if (!requestData) {\n requestData = null;\n }\n\n // Send the request\n request.send(requestData);\n });\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/adapters/xhr.js\n// module id = 12\n// module chunks = 0","'use strict';\n\nvar createError = require('./createError');\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n */\nmodule.exports = function settle(resolve, reject, response) {\n var validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(createError(\n 'Request failed with status code ' + response.status,\n response.config,\n null,\n response.request,\n response\n ));\n }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/core/settle.js\n// module id = 13\n// module chunks = 0","'use strict';\n\nvar enhanceError = require('./enhanceError');\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {Object} config The config.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n * @returns {Error} The created error.\n */\nmodule.exports = function createError(message, config, code, request, response) {\n var error = new Error(message);\n return enhanceError(error, config, code, request, response);\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/core/createError.js\n// module id = 14\n// module chunks = 0","'use strict';\n\n/**\n * Update an Error with the specified config, error code, and response.\n *\n * @param {Error} error The error to update.\n * @param {Object} config The config.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n * @returns {Error} The error.\n */\nmodule.exports = function enhanceError(error, config, code, request, response) {\n error.config = config;\n if (code) {\n error.code = code;\n }\n\n error.request = request;\n error.response = response;\n error.isAxiosError = true;\n\n error.toJSON = function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: this.config,\n code: this.code\n };\n };\n return error;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/core/enhanceError.js\n// module id = 15\n// module chunks = 0","'use strict';\n\nvar utils = require('./../utils');\n\nmodule.exports = (\n utils.isStandardBrowserEnv() ?\n\n // Standard browser envs support document.cookie\n (function standardBrowserEnv() {\n return {\n write: function write(name, value, expires, path, domain, secure) {\n var cookie = [];\n cookie.push(name + '=' + encodeURIComponent(value));\n\n if (utils.isNumber(expires)) {\n cookie.push('expires=' + new Date(expires).toGMTString());\n }\n\n if (utils.isString(path)) {\n cookie.push('path=' + path);\n }\n\n if (utils.isString(domain)) {\n cookie.push('domain=' + domain);\n }\n\n if (secure === true) {\n cookie.push('secure');\n }\n\n document.cookie = cookie.join('; ');\n },\n\n read: function read(name) {\n var match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove: function remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n };\n })() :\n\n // Non standard browser env (web workers, react-native) lack needed support.\n (function nonStandardBrowserEnv() {\n return {\n write: function write() {},\n read: function read() { return null; },\n remove: function remove() {}\n };\n })()\n);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/helpers/cookies.js\n// module id = 16\n// module chunks = 0","'use strict';\n\nvar isAbsoluteURL = require('../helpers/isAbsoluteURL');\nvar combineURLs = require('../helpers/combineURLs');\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n * @returns {string} The combined full path\n */\nmodule.exports = function buildFullPath(baseURL, requestedURL) {\n if (baseURL && !isAbsoluteURL(requestedURL)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/core/buildFullPath.js\n// module id = 17\n// module chunks = 0","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nmodule.exports = function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d\\+\\-\\.]*:)?\\/\\//i.test(url);\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/helpers/isAbsoluteURL.js\n// module id = 18\n// module chunks = 0","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n * @returns {string} The combined URL\n */\nmodule.exports = function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/+$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/helpers/combineURLs.js\n// module id = 19\n// module chunks = 0","'use strict';\n\nvar utils = require('./../utils');\n\n// Headers whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nvar ignoreDuplicateOf = [\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n];\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} headers Headers needing to be parsed\n * @returns {Object} Headers parsed into an object\n */\nmodule.exports = function parseHeaders(headers) {\n var parsed = {};\n var key;\n var val;\n var i;\n\n if (!headers) { return parsed; }\n\n utils.forEach(headers.split('\\n'), function parser(line) {\n i = line.indexOf(':');\n key = utils.trim(line.substr(0, i)).toLowerCase();\n val = utils.trim(line.substr(i + 1));\n\n if (key) {\n if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {\n return;\n }\n if (key === 'set-cookie') {\n parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n }\n });\n\n return parsed;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/helpers/parseHeaders.js\n// module id = 20\n// module chunks = 0","'use strict';\n\nvar utils = require('./../utils');\n\nmodule.exports = (\n utils.isStandardBrowserEnv() ?\n\n // Standard browser envs have full support of the APIs needed to test\n // whether the request URL is of the same origin as current location.\n (function standardBrowserEnv() {\n var msie = /(msie|trident)/i.test(navigator.userAgent);\n var urlParsingNode = document.createElement('a');\n var originURL;\n\n /**\n * Parse a URL to discover it's components\n *\n * @param {String} url The URL to be parsed\n * @returns {Object}\n */\n function resolveURL(url) {\n var href = url;\n\n if (msie) {\n // IE needs attribute set twice to normalize properties\n urlParsingNode.setAttribute('href', href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: urlParsingNode.port,\n pathname: (urlParsingNode.pathname.charAt(0) === '/') ?\n urlParsingNode.pathname :\n '/' + urlParsingNode.pathname\n };\n }\n\n originURL = resolveURL(window.location.href);\n\n /**\n * Determine if a URL shares the same origin as the current location\n *\n * @param {String} requestURL The URL to test\n * @returns {boolean} True if URL shares the same origin, otherwise false\n */\n return function isURLSameOrigin(requestURL) {\n var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;\n return (parsed.protocol === originURL.protocol &&\n parsed.host === originURL.host);\n };\n })() :\n\n // Non standard browser envs (web workers, react-native) lack needed support.\n (function nonStandardBrowserEnv() {\n return function isURLSameOrigin() {\n return true;\n };\n })()\n);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/helpers/isURLSameOrigin.js\n// module id = 21\n// module chunks = 0","'use strict';\n\nvar utils = require('../utils');\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n * @returns {Object} New object resulting from merging config2 to config1\n */\nmodule.exports = function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n var config = {};\n\n var valueFromConfig2Keys = ['url', 'method', 'data'];\n var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy', 'params'];\n var defaultToConfig2Keys = [\n 'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer',\n 'timeout', 'timeoutMessage', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',\n 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'decompress',\n 'maxContentLength', 'maxBodyLength', 'maxRedirects', 'transport', 'httpAgent',\n 'httpsAgent', 'cancelToken', 'socketPath', 'responseEncoding'\n ];\n var directMergeKeys = ['validateStatus'];\n\n function getMergedValue(target, source) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge(target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n function mergeDeepProperties(prop) {\n if (!utils.isUndefined(config2[prop])) {\n config[prop] = getMergedValue(config1[prop], config2[prop]);\n } else if (!utils.isUndefined(config1[prop])) {\n config[prop] = getMergedValue(undefined, config1[prop]);\n }\n }\n\n utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) {\n if (!utils.isUndefined(config2[prop])) {\n config[prop] = getMergedValue(undefined, config2[prop]);\n }\n });\n\n utils.forEach(mergeDeepPropertiesKeys, mergeDeepProperties);\n\n utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) {\n if (!utils.isUndefined(config2[prop])) {\n config[prop] = getMergedValue(undefined, config2[prop]);\n } else if (!utils.isUndefined(config1[prop])) {\n config[prop] = getMergedValue(undefined, config1[prop]);\n }\n });\n\n utils.forEach(directMergeKeys, function merge(prop) {\n if (prop in config2) {\n config[prop] = getMergedValue(config1[prop], config2[prop]);\n } else if (prop in config1) {\n config[prop] = getMergedValue(undefined, config1[prop]);\n }\n });\n\n var axiosKeys = valueFromConfig2Keys\n .concat(mergeDeepPropertiesKeys)\n .concat(defaultToConfig2Keys)\n .concat(directMergeKeys);\n\n var otherKeys = Object\n .keys(config1)\n .concat(Object.keys(config2))\n .filter(function filterAxiosKeys(key) {\n return axiosKeys.indexOf(key) === -1;\n });\n\n utils.forEach(otherKeys, mergeDeepProperties);\n\n return config;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/core/mergeConfig.js\n// module id = 22\n// module chunks = 0","'use strict';\n\n/**\n * A `Cancel` is an object that is thrown when an operation is canceled.\n *\n * @class\n * @param {string=} message The message.\n */\nfunction Cancel(message) {\n this.message = message;\n}\n\nCancel.prototype.toString = function toString() {\n return 'Cancel' + (this.message ? ': ' + this.message : '');\n};\n\nCancel.prototype.__CANCEL__ = true;\n\nmodule.exports = Cancel;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/cancel/Cancel.js\n// module id = 23\n// module chunks = 0","'use strict';\n\nvar Cancel = require('./Cancel');\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @class\n * @param {Function} executor The executor function.\n */\nfunction CancelToken(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n var resolvePromise;\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n var token = this;\n executor(function cancel(message) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new Cancel(message);\n resolvePromise(token.reason);\n });\n}\n\n/**\n * Throws a `Cancel` if cancellation has been requested.\n */\nCancelToken.prototype.throwIfRequested = function throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n};\n\n/**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\nCancelToken.source = function source() {\n var cancel;\n var token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token: token,\n cancel: cancel\n };\n};\n\nmodule.exports = CancelToken;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/cancel/CancelToken.js\n// module id = 24\n// module chunks = 0","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n * @returns {Function}\n */\nmodule.exports = function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/helpers/spread.js\n// module id = 25\n// module chunks = 0","'use strict';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nmodule.exports = function isAxiosError(payload) {\n return (typeof payload === 'object') && (payload.isAxiosError === true);\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/helpers/isAxiosError.js\n// module id = 26\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/logs_ws.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/logs_ws.js new file mode 100644 index 000000000..5144cbabc --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/logs_ws.js @@ -0,0 +1,19 @@ +// small helper function for selecting element by id +let id = id => document.getElementById(id); + +function openJobLogsStream(url) { + console.log("Opening WebSocket connection to " + url); + //Establish the WebSocket connection and set up event handlers + let ws = new WebSocket(url); + ws.onmessage = msg => addLogline(msg) + ws.onerror = () => console.error("WebSocket error: " + ws.readyState); + ws.onclose = () => { + console.log("WebSocket closed. Attempting to reconnect in 5 seconds..."); + setTimeout(() => openJobLogsStream(url), 5000); + }; + +} + +function addLogline(msg) { // Add log line to html + id("logs").insertAdjacentText("afterbegin", msg.data); +} diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/memory_ws.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/memory_ws.js new file mode 100644 index 000000000..8b16cc56b --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/memory_ws.js @@ -0,0 +1,40 @@ +// small helper function for selecting element by id +let id = id => document.getElementById(id); + +function openMemoryStatsStream(url) { + console.log("Opening WebSocket connection to " + url); + // Establish the WebSocket connection and set up event handlers + let ws = new WebSocket(url); + ws.onmessage = msg => updateMemoryGraph(JSON.parse(msg.data)); + ws.onerror = () => console.error("WebSocket error: " + ws.readyState); + ws.onclose = () => { + console.log("WebSocket closed. Attempting to reconnect in 5 seconds..."); + setTimeout(() => openMemoryStatsStream(url), 5000); + }; +} + +function updateMemoryGraph(data) { + const max = data.max; + const used = data.used; + const free = data.free; + + // Update text values + id("memory-max").textContent = formatBytes(max); + id("memory-used").textContent = formatBytes(used); + id("memory-free").textContent = formatBytes(free); + + // Update bars + const usedPercent = (used / max) * 100; + const freePercent = (free / max) * 100; + + id("memory-used-bar").style.width = usedPercent + "%"; + id("memory-free-bar").style.width = freePercent + "%"; +} + +function formatBytes(bytes) { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; +} diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/moment.min.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/moment.min.js new file mode 100644 index 000000000..770f8bc54 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/root/js/moment.min.js @@ -0,0 +1,7 @@ +//! moment.js +//! version : 2.18.1 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com +!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return sd.apply(null,arguments)}function b(a){sd=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){return null!=a&&"[object Object]"===Object.prototype.toString.call(a)}function e(a){var b;for(b in a)return!1;return!0}function f(a){return void 0===a}function g(a){return"number"==typeof a||"[object Number]"===Object.prototype.toString.call(a)}function h(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function i(a,b){var c,d=[];for(c=0;c0)for(c=0;c0?"future":"past"];return z(c)?c(b):c.replace(/%s/i,b)}function J(a,b){var c=a.toLowerCase();Hd[c]=Hd[c+"s"]=Hd[b]=a}function K(a){return"string"==typeof a?Hd[a]||Hd[a.toLowerCase()]:void 0}function L(a){var b,c,d={};for(c in a)j(a,c)&&(b=K(c),b&&(d[b]=a[c]));return d}function M(a,b){Id[a]=b}function N(a){var b=[];for(var c in a)b.push({unit:c,priority:Id[c]});return b.sort(function(a,b){return a.priority-b.priority}),b}function O(b,c){return function(d){return null!=d?(Q(this,b,d),a.updateOffset(this,c),this):P(this,b)}}function P(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():NaN}function Q(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}function R(a){return a=K(a),z(this[a])?this[a]():this}function S(a,b){if("object"==typeof a){a=L(a);for(var c=N(a),d=0;d=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function U(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(Md[a]=e),b&&(Md[b[0]]=function(){return T(e.apply(this,arguments),b[1],b[2])}),c&&(Md[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function V(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function W(a){var b,c,d=a.match(Jd);for(b=0,c=d.length;b=0&&Kd.test(a);)a=a.replace(Kd,c),Kd.lastIndex=0,d-=1;return a}function Z(a,b,c){ce[a]=z(b)?b:function(a,d){return a&&c?c:b}}function $(a,b){return j(ce,a)?ce[a](b._strict,b._locale):new RegExp(_(a))}function _(a){return aa(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function aa(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function ba(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),g(b)&&(d=function(a,c){c[b]=u(a)}),c=0;c=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function ta(a){var b=new Date(Date.UTC.apply(null,arguments));return a<100&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}function ua(a,b,c){var d=7+b-c,e=(7+ta(a,0,d).getUTCDay()-b)%7;return-e+d-1}function va(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=ua(a,d,e),j=1+7*(b-1)+h+i;return j<=0?(f=a-1,g=pa(f)+j):j>pa(a)?(f=a+1,g=j-pa(a)):(f=a,g=j),{year:f,dayOfYear:g}}function wa(a,b,c){var d,e,f=ua(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return g<1?(e=a.year()-1,d=g+xa(e,b,c)):g>xa(a.year(),b,c)?(d=g-xa(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function xa(a,b,c){var d=ua(a,b,c),e=ua(a+1,b,c);return(pa(a)-d+e)/7}function ya(a){return wa(a,this._week.dow,this._week.doy).week}function za(){return this._week.dow}function Aa(){return this._week.doy}function Ba(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function Ca(a){var b=wa(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function Da(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function Ea(a,b){return"string"==typeof a?b.weekdaysParse(a)%7||7:isNaN(a)?null:a}function Fa(a,b){return a?c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]:c(this._weekdays)?this._weekdays:this._weekdays.standalone}function Ga(a){return a?this._weekdaysShort[a.day()]:this._weekdaysShort}function Ha(a){return a?this._weekdaysMin[a.day()]:this._weekdaysMin}function Ia(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],d=0;d<7;++d)f=l([2e3,1]).day(d),this._minWeekdaysParse[d]=this.weekdaysMin(f,"").toLocaleLowerCase(),this._shortWeekdaysParse[d]=this.weekdaysShort(f,"").toLocaleLowerCase(),this._weekdaysParse[d]=this.weekdays(f,"").toLocaleLowerCase();return c?"dddd"===b?(e=ne.call(this._weekdaysParse,g),e!==-1?e:null):"ddd"===b?(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:null):(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null):"dddd"===b?(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null))):"ddd"===b?(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null))):(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:null)))}function Ja(a,b,c){var d,e,f;if(this._weekdaysParseExact)return Ia.call(this,a,b,c);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;d<7;d++){if(e=l([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}function Ka(a){if(!this.isValid())return null!=a?this:NaN;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=Da(a,this.localeData()),this.add(a-b,"d")):b}function La(a){if(!this.isValid())return null!=a?this:NaN;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function Ma(a){if(!this.isValid())return null!=a?this:NaN;if(null!=a){var b=Ea(a,this.localeData());return this.day(this.day()%7?b:b-7)}return this.day()||7}function Na(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysStrictRegex:this._weekdaysRegex):(j(this,"_weekdaysRegex")||(this._weekdaysRegex=ye),this._weekdaysStrictRegex&&a?this._weekdaysStrictRegex:this._weekdaysRegex)}function Oa(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(j(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=ze),this._weekdaysShortStrictRegex&&a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function Pa(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(j(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Ae),this._weekdaysMinStrictRegex&&a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Qa(){function a(a,b){return b.length-a.length}var b,c,d,e,f,g=[],h=[],i=[],j=[];for(b=0;b<7;b++)c=l([2e3,1]).day(b),d=this.weekdaysMin(c,""),e=this.weekdaysShort(c,""),f=this.weekdays(c,""),g.push(d),h.push(e),i.push(f),j.push(d),j.push(e),j.push(f);for(g.sort(a),h.sort(a),i.sort(a),j.sort(a),b=0;b<7;b++)h[b]=aa(h[b]),i[b]=aa(i[b]),j[b]=aa(j[b]);this._weekdaysRegex=new RegExp("^("+j.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+h.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+g.join("|")+")","i")}function Ra(){return this.hours()%12||12}function Sa(){return this.hours()||24}function Ta(a,b){U(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function Ua(a,b){return b._meridiemParse}function Va(a){return"p"===(a+"").toLowerCase().charAt(0)}function Wa(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function Xa(a){return a?a.toLowerCase().replace("_","-"):a}function Ya(a){for(var b,c,d,e,f=0;f0;){if(d=Za(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&v(e,c,!0)>=b-1)break;b--}f++}return null}function Za(a){var b=null;if(!Fe[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=Be._abbr,require("./locale/"+a),$a(b)}catch(a){}return Fe[a]}function $a(a,b){var c;return a&&(c=f(b)?bb(a):_a(a,b),c&&(Be=c)),Be._abbr}function _a(a,b){if(null!==b){var c=Ee;if(b.abbr=a,null!=Fe[a])y("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),c=Fe[a]._config;else if(null!=b.parentLocale){if(null==Fe[b.parentLocale])return Ge[b.parentLocale]||(Ge[b.parentLocale]=[]),Ge[b.parentLocale].push({name:a,config:b}),null;c=Fe[b.parentLocale]._config}return Fe[a]=new C(B(c,b)),Ge[a]&&Ge[a].forEach(function(a){_a(a.name,a.config)}),$a(a),Fe[a]}return delete Fe[a],null}function ab(a,b){if(null!=b){var c,d=Ee;null!=Fe[a]&&(d=Fe[a]._config),b=B(d,b),c=new C(b),c.parentLocale=Fe[a],Fe[a]=c,$a(a)}else null!=Fe[a]&&(null!=Fe[a].parentLocale?Fe[a]=Fe[a].parentLocale:null!=Fe[a]&&delete Fe[a]);return Fe[a]}function bb(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return Be;if(!c(a)){if(b=Za(a))return b;a=[a]}return Ya(a)}function cb(){return Ad(Fe)}function db(a){var b,c=a._a;return c&&n(a).overflow===-2&&(b=c[fe]<0||c[fe]>11?fe:c[ge]<1||c[ge]>ea(c[ee],c[fe])?ge:c[he]<0||c[he]>24||24===c[he]&&(0!==c[ie]||0!==c[je]||0!==c[ke])?he:c[ie]<0||c[ie]>59?ie:c[je]<0||c[je]>59?je:c[ke]<0||c[ke]>999?ke:-1,n(a)._overflowDayOfYear&&(bge)&&(b=ge),n(a)._overflowWeeks&&b===-1&&(b=le),n(a)._overflowWeekday&&b===-1&&(b=me),n(a).overflow=b),a}function eb(a){var b,c,d,e,f,g,h=a._i,i=He.exec(h)||Ie.exec(h);if(i){for(n(a).iso=!0,b=0,c=Ke.length;b10?"YYYY ":"YY "),f="HH:mm"+(c[4]?":ss":""),c[1]){var l=new Date(c[2]),m=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][l.getDay()];if(c[1].substr(0,3)!==m)return n(a).weekdayMismatch=!0,void(a._isValid=!1)}switch(c[5].length){case 2:0===i?h=" +0000":(i=k.indexOf(c[5][1].toUpperCase())-12,h=(i<0?" -":" +")+(""+i).replace(/^-?/,"0").match(/..$/)[0]+"00");break;case 4:h=j[c[5]];break;default:h=j[" GMT"]}c[5]=h,a._i=c.splice(1).join(""),g=" ZZ",a._f=d+e+f+g,lb(a),n(a).rfc2822=!0}else a._isValid=!1}function gb(b){var c=Me.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(eb(b),void(b._isValid===!1&&(delete b._isValid,fb(b),b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b)))))}function hb(a,b,c){return null!=a?a:null!=b?b:c}function ib(b){var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}function jb(a){var b,c,d,e,f=[];if(!a._d){for(d=ib(a),a._w&&null==a._a[ge]&&null==a._a[fe]&&kb(a),null!=a._dayOfYear&&(e=hb(a._a[ee],d[ee]),(a._dayOfYear>pa(e)||0===a._dayOfYear)&&(n(a)._overflowDayOfYear=!0),c=ta(e,0,a._dayOfYear),a._a[fe]=c.getUTCMonth(),a._a[ge]=c.getUTCDate()),b=0;b<3&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;b<7;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[he]&&0===a._a[ie]&&0===a._a[je]&&0===a._a[ke]&&(a._nextDay=!0,a._a[he]=0),a._d=(a._useUTC?ta:sa).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[he]=24)}}function kb(a){var b,c,d,e,f,g,h,i;if(b=a._w,null!=b.GG||null!=b.W||null!=b.E)f=1,g=4,c=hb(b.GG,a._a[ee],wa(tb(),1,4).year),d=hb(b.W,1),e=hb(b.E,1),(e<1||e>7)&&(i=!0);else{f=a._locale._week.dow,g=a._locale._week.doy;var j=wa(tb(),f,g);c=hb(b.gg,a._a[ee],j.year),d=hb(b.w,j.week),null!=b.d?(e=b.d,(e<0||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f}d<1||d>xa(c,f,g)?n(a)._overflowWeeks=!0:null!=i?n(a)._overflowWeekday=!0:(h=va(c,d,e,f,g),a._a[ee]=h.year,a._dayOfYear=h.dayOfYear)}function lb(b){if(b._f===a.ISO_8601)return void eb(b);if(b._f===a.RFC_2822)return void fb(b);b._a=[],n(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,j=0;for(e=Y(b._f,b._locale).match(Jd)||[],c=0;c0&&n(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),j+=d.length),Md[f]?(d?n(b).empty=!1:n(b).unusedTokens.push(f),da(f,d,b)):b._strict&&!d&&n(b).unusedTokens.push(f);n(b).charsLeftOver=i-j,h.length>0&&n(b).unusedInput.push(h),b._a[he]<=12&&n(b).bigHour===!0&&b._a[he]>0&&(n(b).bigHour=void 0),n(b).parsedDateParts=b._a.slice(0),n(b).meridiem=b._meridiem,b._a[he]=mb(b._locale,b._a[he],b._meridiem),jb(b),db(b)}function mb(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&b<12&&(b+=12),d||12!==b||(b=0),b):b}function nb(a){var b,c,d,e,f;if(0===a._f.length)return n(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;ethis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Ob(){if(!f(this._isDSTShifted))return this._isDSTShifted;var a={};if(q(a,this),a=qb(a),a._a){var b=a._isUTC?l(a._a):tb(a._a);this._isDSTShifted=this.isValid()&&v(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Pb(){return!!this.isValid()&&!this._isUTC}function Qb(){return!!this.isValid()&&this._isUTC}function Rb(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function Sb(a,b){var c,d,e,f=a,h=null;return Bb(a)?f={ms:a._milliseconds,d:a._days,M:a._months}:g(a)?(f={},b?f[b]=a:f.milliseconds=a):(h=Te.exec(a))?(c="-"===h[1]?-1:1,f={y:0,d:u(h[ge])*c,h:u(h[he])*c,m:u(h[ie])*c,s:u(h[je])*c,ms:u(Cb(1e3*h[ke]))*c}):(h=Ue.exec(a))?(c="-"===h[1]?-1:1,f={y:Tb(h[2],c),M:Tb(h[3],c),w:Tb(h[4],c),d:Tb(h[5],c),h:Tb(h[6],c),m:Tb(h[7],c),s:Tb(h[8],c)}):null==f?f={}:"object"==typeof f&&("from"in f||"to"in f)&&(e=Vb(tb(f.from),tb(f.to)),f={},f.ms=e.milliseconds,f.M=e.months),d=new Ab(f),Bb(a)&&j(a,"_locale")&&(d._locale=a._locale),d}function Tb(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function Ub(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function Vb(a,b){var c;return a.isValid()&&b.isValid()?(b=Fb(b,a),a.isBefore(b)?c=Ub(a,b):(c=Ub(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}function Wb(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(y(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=Sb(c,d),Xb(this,e,a),this}}function Xb(b,c,d,e){var f=c._milliseconds,g=Cb(c._days),h=Cb(c._months);b.isValid()&&(e=null==e||e,f&&b._d.setTime(b._d.valueOf()+f*d),g&&Q(b,"Date",P(b,"Date")+g*d),h&&ja(b,P(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function Yb(a,b){var c=a.diff(b,"days",!0);return c<-6?"sameElse":c<-1?"lastWeek":c<0?"lastDay":c<1?"sameDay":c<2?"nextDay":c<7?"nextWeek":"sameElse"}function Zb(b,c){var d=b||tb(),e=Fb(d,this).startOf("day"),f=a.calendarFormat(this,e)||"sameElse",g=c&&(z(c[f])?c[f].call(this,d):c[f]);return this.format(g||this.localeData().calendar(f,this,tb(d)))}function $b(){return new r(this)}function _b(a,b){var c=s(a)?a:tb(a);return!(!this.isValid()||!c.isValid())&&(b=K(f(b)?"millisecond":b),"millisecond"===b?this.valueOf()>c.valueOf():c.valueOf()9999?X(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):z(Date.prototype.toISOString)?this.toDate().toISOString():X(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function jc(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var a="moment",b="";this.isLocal()||(a=0===this.utcOffset()?"moment.utc":"moment.parseZone",b="Z");var c="["+a+'("]',d=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",e="-MM-DD[T]HH:mm:ss.SSS",f=b+'[")]';return this.format(c+d+e+f)}function kc(b){b||(b=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var c=X(this,b);return this.localeData().postformat(c)}function lc(a,b){return this.isValid()&&(s(a)&&a.isValid()||tb(a).isValid())?Sb({to:this,from:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function mc(a){return this.from(tb(),a)}function nc(a,b){return this.isValid()&&(s(a)&&a.isValid()||tb(a).isValid())?Sb({from:this,to:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function oc(a){return this.to(tb(),a)}function pc(a){var b;return void 0===a?this._locale._abbr:(b=bb(a),null!=b&&(this._locale=b),this)}function qc(){return this._locale}function rc(a){switch(a=K(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a&&this.weekday(0),"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this}function sc(a){return a=K(a),void 0===a||"millisecond"===a?this:("date"===a&&(a="day"),this.startOf(a).add(1,"isoWeek"===a?"week":a).subtract(1,"ms"))}function tc(){return this._d.valueOf()-6e4*(this._offset||0)}function uc(){return Math.floor(this.valueOf()/1e3)}function vc(){return new Date(this.valueOf())}function wc(){var a=this;return[a.year(),a.month(),a.date(),a.hour(),a.minute(),a.second(),a.millisecond()]}function xc(){var a=this;return{years:a.year(),months:a.month(),date:a.date(),hours:a.hours(),minutes:a.minutes(),seconds:a.seconds(),milliseconds:a.milliseconds()}}function yc(){return this.isValid()?this.toISOString():null}function zc(){return o(this)}function Ac(){ +return k({},n(this))}function Bc(){return n(this).overflow}function Cc(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Dc(a,b){U(0,[a,a.length],0,b)}function Ec(a){return Ic.call(this,a,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function Fc(a){return Ic.call(this,a,this.isoWeek(),this.isoWeekday(),1,4)}function Gc(){return xa(this.year(),1,4)}function Hc(){var a=this.localeData()._week;return xa(this.year(),a.dow,a.doy)}function Ic(a,b,c,d,e){var f;return null==a?wa(this,d,e).year:(f=xa(a,d,e),b>f&&(b=f),Jc.call(this,a,b,c,d,e))}function Jc(a,b,c,d,e){var f=va(a,b,c,d,e),g=ta(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}function Kc(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Lc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function Mc(a,b){b[ke]=u(1e3*("0."+a))}function Nc(){return this._isUTC?"UTC":""}function Oc(){return this._isUTC?"Coordinated Universal Time":""}function Pc(a){return tb(1e3*a)}function Qc(){return tb.apply(null,arguments).parseZone()}function Rc(a){return a}function Sc(a,b,c,d){var e=bb(),f=l().set(d,b);return e[c](f,a)}function Tc(a,b,c){if(g(a)&&(b=a,a=void 0),a=a||"",null!=b)return Sc(a,b,c,"month");var d,e=[];for(d=0;d<12;d++)e[d]=Sc(a,d,c,"month");return e}function Uc(a,b,c,d){"boolean"==typeof a?(g(b)&&(c=b,b=void 0),b=b||""):(b=a,c=b,a=!1,g(b)&&(c=b,b=void 0),b=b||"");var e=bb(),f=a?e._week.dow:0;if(null!=c)return Sc(b,(c+f)%7,d,"day");var h,i=[];for(h=0;h<7;h++)i[h]=Sc(b,(h+f)%7,d,"day");return i}function Vc(a,b){return Tc(a,b,"months")}function Wc(a,b){return Tc(a,b,"monthsShort")}function Xc(a,b,c){return Uc(a,b,c,"weekdays")}function Yc(a,b,c){return Uc(a,b,c,"weekdaysShort")}function Zc(a,b,c){return Uc(a,b,c,"weekdaysMin")}function $c(){var a=this._data;return this._milliseconds=df(this._milliseconds),this._days=df(this._days),this._months=df(this._months),a.milliseconds=df(a.milliseconds),a.seconds=df(a.seconds),a.minutes=df(a.minutes),a.hours=df(a.hours),a.months=df(a.months),a.years=df(a.years),this}function _c(a,b,c,d){var e=Sb(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function ad(a,b){return _c(this,a,b,1)}function bd(a,b){return _c(this,a,b,-1)}function cd(a){return a<0?Math.floor(a):Math.ceil(a)}function dd(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||f<=0&&g<=0&&h<=0||(f+=864e5*cd(fd(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=t(f/1e3),i.seconds=a%60,b=t(a/60),i.minutes=b%60,c=t(b/60),i.hours=c%24,g+=t(c/24),e=t(ed(g)),h+=e,g-=cd(fd(e)),d=t(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function ed(a){return 4800*a/146097}function fd(a){return 146097*a/4800}function gd(a){if(!this.isValid())return NaN;var b,c,d=this._milliseconds;if(a=K(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+ed(b),"month"===a?c:c/12;switch(b=this._days+Math.round(fd(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function hd(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*u(this._months/12):NaN}function id(a){return function(){return this.as(a)}}function jd(a){return a=K(a),this.isValid()?this[a+"s"]():NaN}function kd(a){return function(){return this.isValid()?this._data[a]:NaN}}function ld(){return t(this.days()/7)}function md(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function nd(a,b,c){var d=Sb(a).abs(),e=uf(d.as("s")),f=uf(d.as("m")),g=uf(d.as("h")),h=uf(d.as("d")),i=uf(d.as("M")),j=uf(d.as("y")),k=e<=vf.ss&&["s",e]||e0,k[4]=c,md.apply(null,k)}function od(a){return void 0===a?uf:"function"==typeof a&&(uf=a,!0)}function pd(a,b){return void 0!==vf[a]&&(void 0===b?vf[a]:(vf[a]=b,"s"===a&&(vf.ss=b-1),!0))}function qd(a){if(!this.isValid())return this.localeData().invalidDate();var b=this.localeData(),c=nd(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function rd(){if(!this.isValid())return this.localeData().invalidDate();var a,b,c,d=wf(this._milliseconds)/1e3,e=wf(this._days),f=wf(this._months);a=t(d/60),b=t(a/60),d%=60,a%=60,c=t(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(m<0?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var sd,td;td=Array.prototype.some?Array.prototype.some:function(a){for(var b=Object(this),c=b.length>>>0,d=0;d68?1900:2e3)};var te=O("FullYear",!0);U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),J("week","w"),J("isoWeek","W"),M("week",5),M("isoWeek",5),Z("w",Sd),Z("ww",Sd,Od),Z("W",Sd),Z("WW",Sd,Od),ca(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=u(a)});var ue={dow:0,doy:6};U("d",0,"do","day"),U("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),U("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),U("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),J("day","d"),J("weekday","e"),J("isoWeekday","E"),M("day",11),M("weekday",11),M("isoWeekday",11),Z("d",Sd),Z("e",Sd),Z("E",Sd),Z("dd",function(a,b){return b.weekdaysMinRegex(a)}),Z("ddd",function(a,b){return b.weekdaysShortRegex(a)}),Z("dddd",function(a,b){return b.weekdaysRegex(a)}),ca(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);null!=e?b.d=e:n(c).invalidWeekday=a}),ca(["d","e","E"],function(a,b,c,d){b[d]=u(a)});var ve="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),we="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),xe="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ye=be,ze=be,Ae=be;U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Ra),U("k",["kk",2],0,Sa),U("hmm",0,0,function(){return""+Ra.apply(this)+T(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Ra.apply(this)+T(this.minutes(),2)+T(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+T(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+T(this.minutes(),2)+T(this.seconds(),2)}),Ta("a",!0),Ta("A",!1),J("hour","h"),M("hour",13),Z("a",Ua),Z("A",Ua),Z("H",Sd),Z("h",Sd),Z("k",Sd),Z("HH",Sd,Od),Z("hh",Sd,Od),Z("kk",Sd,Od),Z("hmm",Td),Z("hmmss",Ud),Z("Hmm",Td),Z("Hmmss",Ud),ba(["H","HH"],he),ba(["k","kk"],function(a,b,c){var d=u(a);b[he]=24===d?0:d}),ba(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),ba(["h","hh"],function(a,b,c){b[he]=u(a),n(c).bigHour=!0}),ba("hmm",function(a,b,c){var d=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d)),n(c).bigHour=!0}),ba("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d,2)),b[je]=u(a.substr(e)),n(c).bigHour=!0}),ba("Hmm",function(a,b,c){var d=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d))}),ba("Hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d,2)),b[je]=u(a.substr(e))});var Be,Ce=/[ap]\.?m?\.?/i,De=O("Hours",!0),Ee={calendar:Bd,longDateFormat:Cd,invalidDate:Dd,ordinal:Ed,dayOfMonthOrdinalParse:Fd,relativeTime:Gd,months:pe,monthsShort:qe,week:ue,weekdays:ve,weekdaysMin:xe,weekdaysShort:we,meridiemParse:Ce},Fe={},Ge={},He=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Ie=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Je=/Z|[+-]\d\d(?::?\d\d)?/,Ke=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Le=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Me=/^\/?Date\((\-?\d+)/i,Ne=/^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/;a.createFromInputFallback=x("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),a.ISO_8601=function(){},a.RFC_2822=function(){};var Oe=x("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var a=tb.apply(null,arguments);return this.isValid()&&a.isValid()?athis?this:a:p()}),Qe=function(){return Date.now?Date.now():+new Date},Re=["year","quarter","month","week","day","hour","minute","second","millisecond"];Db("Z",":"),Db("ZZ",""),Z("Z",_d),Z("ZZ",_d),ba(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=Eb(_d,a)});var Se=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var Te=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Ue=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;Sb.fn=Ab.prototype,Sb.invalid=zb;var Ve=Wb(1,"add"),We=Wb(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Xe=x("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});U(0,["gg",2],0,function(){return this.weekYear()%100}),U(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Dc("gggg","weekYear"),Dc("ggggg","weekYear"),Dc("GGGG","isoWeekYear"),Dc("GGGGG","isoWeekYear"),J("weekYear","gg"),J("isoWeekYear","GG"),M("weekYear",1),M("isoWeekYear",1),Z("G",Zd),Z("g",Zd),Z("GG",Sd,Od),Z("gg",Sd,Od),Z("GGGG",Wd,Qd),Z("gggg",Wd,Qd),Z("GGGGG",Xd,Rd),Z("ggggg",Xd,Rd),ca(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=u(a)}),ca(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),U("Q",0,"Qo","quarter"),J("quarter","Q"),M("quarter",7),Z("Q",Nd),ba("Q",function(a,b){b[fe]=3*(u(a)-1)}),U("D",["DD",2],"Do","date"),J("date","D"),M("date",9),Z("D",Sd),Z("DD",Sd,Od),Z("Do",function(a,b){return a?b._dayOfMonthOrdinalParse||b._ordinalParse:b._dayOfMonthOrdinalParseLenient}),ba(["D","DD"],ge),ba("Do",function(a,b){b[ge]=u(a.match(Sd)[0],10)});var Ye=O("Date",!0);U("DDD",["DDDD",3],"DDDo","dayOfYear"),J("dayOfYear","DDD"),M("dayOfYear",4),Z("DDD",Vd),Z("DDDD",Pd),ba(["DDD","DDDD"],function(a,b,c){c._dayOfYear=u(a)}),U("m",["mm",2],0,"minute"),J("minute","m"),M("minute",14),Z("m",Sd),Z("mm",Sd,Od),ba(["m","mm"],ie);var Ze=O("Minutes",!1);U("s",["ss",2],0,"second"),J("second","s"),M("second",15),Z("s",Sd),Z("ss",Sd,Od),ba(["s","ss"],je);var $e=O("Seconds",!1);U("S",0,0,function(){return~~(this.millisecond()/100)}),U(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),U(0,["SSS",3],0,"millisecond"),U(0,["SSSS",4],0,function(){return 10*this.millisecond()}),U(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),U(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),U(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),U(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),U(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),J("millisecond","ms"),M("millisecond",16),Z("S",Vd,Nd),Z("SS",Vd,Od),Z("SSS",Vd,Pd);var _e;for(_e="SSSS";_e.length<=9;_e+="S")Z(_e,Yd);for(_e="S";_e.length<=9;_e+="S")ba(_e,Mc);var af=O("Milliseconds",!1);U("z",0,0,"zoneAbbr"),U("zz",0,0,"zoneName");var bf=r.prototype;bf.add=Ve,bf.calendar=Zb,bf.clone=$b,bf.diff=fc,bf.endOf=sc,bf.format=kc,bf.from=lc,bf.fromNow=mc,bf.to=nc,bf.toNow=oc,bf.get=R,bf.invalidAt=Bc,bf.isAfter=_b,bf.isBefore=ac,bf.isBetween=bc,bf.isSame=cc,bf.isSameOrAfter=dc,bf.isSameOrBefore=ec,bf.isValid=zc,bf.lang=Xe,bf.locale=pc,bf.localeData=qc,bf.max=Pe,bf.min=Oe,bf.parsingFlags=Ac,bf.set=S,bf.startOf=rc,bf.subtract=We,bf.toArray=wc,bf.toObject=xc,bf.toDate=vc,bf.toISOString=ic,bf.inspect=jc,bf.toJSON=yc,bf.toString=hc,bf.unix=uc,bf.valueOf=tc,bf.creationData=Cc,bf.year=te,bf.isLeapYear=ra,bf.weekYear=Ec,bf.isoWeekYear=Fc,bf.quarter=bf.quarters=Kc,bf.month=ka,bf.daysInMonth=la,bf.week=bf.weeks=Ba,bf.isoWeek=bf.isoWeeks=Ca,bf.weeksInYear=Hc,bf.isoWeeksInYear=Gc,bf.date=Ye,bf.day=bf.days=Ka,bf.weekday=La,bf.isoWeekday=Ma,bf.dayOfYear=Lc,bf.hour=bf.hours=De,bf.minute=bf.minutes=Ze,bf.second=bf.seconds=$e,bf.millisecond=bf.milliseconds=af,bf.utcOffset=Hb,bf.utc=Jb,bf.local=Kb,bf.parseZone=Lb,bf.hasAlignedHourOffset=Mb,bf.isDST=Nb,bf.isLocal=Pb,bf.isUtcOffset=Qb,bf.isUtc=Rb,bf.isUTC=Rb,bf.zoneAbbr=Nc,bf.zoneName=Oc,bf.dates=x("dates accessor is deprecated. Use date instead.",Ye),bf.months=x("months accessor is deprecated. Use month instead",ka),bf.years=x("years accessor is deprecated. Use year instead",te),bf.zone=x("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",Ib),bf.isDSTShifted=x("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",Ob);var cf=C.prototype;cf.calendar=D,cf.longDateFormat=E,cf.invalidDate=F,cf.ordinal=G,cf.preparse=Rc,cf.postformat=Rc,cf.relativeTime=H,cf.pastFuture=I,cf.set=A,cf.months=fa,cf.monthsShort=ga,cf.monthsParse=ia,cf.monthsRegex=na,cf.monthsShortRegex=ma,cf.week=ya,cf.firstDayOfYear=Aa,cf.firstDayOfWeek=za,cf.weekdays=Fa,cf.weekdaysMin=Ha,cf.weekdaysShort=Ga,cf.weekdaysParse=Ja,cf.weekdaysRegex=Na,cf.weekdaysShortRegex=Oa,cf.weekdaysMinRegex=Pa,cf.isPM=Va,cf.meridiem=Wa,$a("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===u(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=x("moment.lang is deprecated. Use moment.locale instead.",$a),a.langData=x("moment.langData is deprecated. Use moment.localeData instead.",bb);var df=Math.abs,ef=id("ms"),ff=id("s"),gf=id("m"),hf=id("h"),jf=id("d"),kf=id("w"),lf=id("M"),mf=id("y"),nf=kd("milliseconds"),of=kd("seconds"),pf=kd("minutes"),qf=kd("hours"),rf=kd("days"),sf=kd("months"),tf=kd("years"),uf=Math.round,vf={ss:44,s:45,m:45,h:22,d:26,M:11},wf=Math.abs,xf=Ab.prototype;return xf.isValid=yb,xf.abs=$c,xf.add=ad,xf.subtract=bd,xf.as=gd,xf.asMilliseconds=ef,xf.asSeconds=ff,xf.asMinutes=gf,xf.asHours=hf,xf.asDays=jf,xf.asWeeks=kf,xf.asMonths=lf,xf.asYears=mf,xf.valueOf=hd,xf._bubble=dd,xf.get=jd,xf.milliseconds=nf,xf.seconds=of,xf.minutes=pf,xf.hours=qf,xf.days=rf,xf.weeks=ld,xf.months=sf,xf.years=tf,xf.humanize=qd,xf.toISOString=rd,xf.toString=rd,xf.toJSON=rd,xf.locale=pc,xf.localeData=qc,xf.toIsoString=x("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",rd),xf.lang=Xe,U("X",0,0,"unix"),U("x",0,0,"valueOf"),Z("x",Zd),Z("X",ae),ba("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),ba("x",function(a,b,c){c._d=new Date(u(a))}),a.version="2.18.1",b(tb),a.fn=bf,a.min=vb,a.max=wb,a.now=Qe,a.utc=l,a.unix=Pc,a.months=Vc,a.isDate=h,a.locale=$a,a.invalid=p,a.duration=Sb,a.isMoment=s,a.weekdays=Xc,a.parseZone=Qc,a.localeData=bb,a.isDuration=Bb,a.monthsShort=Wc,a.weekdaysMin=Zc,a.defineLocale=_a,a.updateLocale=ab,a.locales=cb,a.weekdaysShort=Yc,a.normalizeUnits=K,a.relativeTimeRounding=od,a.relativeTimeThreshold=pd,a.calendarFormat=Yb,a.prototype=bf,a}); \ No newline at end of file diff --git a/wpsbuilder/assets/css/animate-custom.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/animate-custom.css similarity index 100% rename from wpsbuilder/assets/css/animate-custom.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/animate-custom.css diff --git a/wpsbuilder/assets/css/bootstrap.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/bootstrap.css similarity index 100% rename from wpsbuilder/assets/css/bootstrap.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/bootstrap.css diff --git a/wpsbuilder/assets/css/icomoon.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon.css similarity index 100% rename from wpsbuilder/assets/css/icomoon.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon.css diff --git a/wpsbuilder/assets/css/icomoon/icomoon-.eot b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon/icomoon-.eot similarity index 100% rename from wpsbuilder/assets/css/icomoon/icomoon-.eot rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon/icomoon-.eot diff --git a/wpsbuilder/assets/css/icomoon/icomoon.eot b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon/icomoon.eot similarity index 100% rename from wpsbuilder/assets/css/icomoon/icomoon.eot rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon/icomoon.eot diff --git a/wpsbuilder/assets/css/icomoon/icomoon.svg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon/icomoon.svg similarity index 100% rename from wpsbuilder/assets/css/icomoon/icomoon.svg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon/icomoon.svg diff --git a/wpsbuilder/assets/css/icomoon/icomoon.ttf b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon/icomoon.ttf similarity index 100% rename from wpsbuilder/assets/css/icomoon/icomoon.ttf rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon/icomoon.ttf diff --git a/wpsbuilder/assets/css/icomoon/icomoon.woff b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon/icomoon.woff similarity index 100% rename from wpsbuilder/assets/css/icomoon/icomoon.woff rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/icomoon/icomoon.woff diff --git a/wpsbuilder/assets/css/main.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/main.css similarity index 100% rename from wpsbuilder/assets/css/main.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/css/main.css diff --git a/wpsbuilder/assets/fonts/glyphicons-halflings-regular.eot b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from wpsbuilder/assets/fonts/glyphicons-halflings-regular.eot rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/fonts/glyphicons-halflings-regular.eot diff --git a/wpsbuilder/assets/fonts/glyphicons-halflings-regular.svg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from wpsbuilder/assets/fonts/glyphicons-halflings-regular.svg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/fonts/glyphicons-halflings-regular.svg diff --git a/wpsbuilder/assets/fonts/glyphicons-halflings-regular.ttf b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from wpsbuilder/assets/fonts/glyphicons-halflings-regular.ttf rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/fonts/glyphicons-halflings-regular.ttf diff --git a/wpsbuilder/assets/fonts/glyphicons-halflings-regular.woff b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from wpsbuilder/assets/fonts/glyphicons-halflings-regular.woff rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/fonts/glyphicons-halflings-regular.woff diff --git a/wpsbuilder/assets/img/bg/divider1.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/bg/divider1.jpg similarity index 100% rename from wpsbuilder/assets/img/bg/divider1.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/bg/divider1.jpg diff --git a/wpsbuilder/assets/img/bg/divider3.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/bg/divider3.jpg similarity index 100% rename from wpsbuilder/assets/img/bg/divider3.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/bg/divider3.jpg diff --git a/wpsbuilder/assets/img/bg/divider6.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/bg/divider6.jpg similarity index 100% rename from wpsbuilder/assets/img/bg/divider6.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/bg/divider6.jpg diff --git a/wpsbuilder/assets/img/header_bg.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/header_bg.jpg similarity index 100% rename from wpsbuilder/assets/img/header_bg.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/header_bg.jpg diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/logo_noisemap_alone_small.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/logo_noisemap_alone_small.png new file mode 100644 index 000000000..e0585baa3 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/logo_noisemap_alone_small.png differ diff --git a/wpsbuilder/assets/img/logo_noismap_cercle.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/logo_noismap_cercle.png similarity index 100% rename from wpsbuilder/assets/img/logo_noismap_cercle.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/logo_noismap_cercle.png diff --git a/wpsbuilder/assets/img/logo_orbisgis.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/logo_orbisgis.png similarity index 100% rename from wpsbuilder/assets/img/logo_orbisgis.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/logo_orbisgis.png diff --git a/wpsbuilder/assets/img/noisemap_architecture.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/noisemap_architecture.jpg similarity index 100% rename from wpsbuilder/assets/img/noisemap_architecture.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/noisemap_architecture.jpg diff --git a/wpsbuilder/assets/img/portfolio/CellMeshDirectSound.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/CellMeshDirectSound.png similarity index 100% rename from wpsbuilder/assets/img/portfolio/CellMeshDirectSound.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/CellMeshDirectSound.png diff --git a/wpsbuilder/assets/img/portfolio/CellMeshFirstRefl.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/CellMeshFirstRefl.png similarity index 100% rename from wpsbuilder/assets/img/portfolio/CellMeshFirstRefl.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/CellMeshFirstRefl.png diff --git a/wpsbuilder/assets/img/portfolio/CellMeshReceivers.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/CellMeshReceivers.jpg similarity index 100% rename from wpsbuilder/assets/img/portfolio/CellMeshReceivers.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/CellMeshReceivers.jpg diff --git a/wpsbuilder/assets/img/portfolio/LDEN_2002_Routier_CUnantes.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/LDEN_2002_Routier_CUnantes.jpg similarity index 100% rename from wpsbuilder/assets/img/portfolio/LDEN_2002_Routier_CUnantes.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/LDEN_2002_Routier_CUnantes.jpg diff --git a/wpsbuilder/assets/img/portfolio/LDEN_population.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/LDEN_population.jpg similarity index 100% rename from wpsbuilder/assets/img/portfolio/LDEN_population.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/LDEN_population.jpg diff --git a/wpsbuilder/assets/img/portfolio/NantesSubdivWithObj.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/NantesSubdivWithObj.jpg similarity index 100% rename from wpsbuilder/assets/img/portfolio/NantesSubdivWithObj.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/NantesSubdivWithObj.jpg diff --git a/wpsbuilder/assets/img/portfolio/noisemap_3d.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/noisemap_3d.png similarity index 100% rename from wpsbuilder/assets/img/portfolio/noisemap_3d.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/portfolio/noisemap_3d.png diff --git a/wpsbuilder/assets/img/schema_future.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/schema_future.jpg similarity index 100% rename from wpsbuilder/assets/img/schema_future.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/schema_future.jpg diff --git a/wpsbuilder/assets/img/screen4_final.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/screen4_final.jpg similarity index 100% rename from wpsbuilder/assets/img/screen4_final.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/screen4_final.jpg diff --git a/wpsbuilder/assets/img/team/Ifsttar_origine.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/team/Ifsttar_origine.jpg similarity index 100% rename from wpsbuilder/assets/img/team/Ifsttar_origine.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/team/Ifsttar_origine.jpg diff --git a/wpsbuilder/assets/img/team/irstv.svg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/team/irstv.svg similarity index 100% rename from wpsbuilder/assets/img/team/irstv.svg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/team/irstv.svg diff --git a/wpsbuilder/assets/img/team/team01.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/team/team01.jpg similarity index 100% rename from wpsbuilder/assets/img/team/team01.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/team/team01.jpg diff --git a/wpsbuilder/assets/img/team/team02.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/team/team02.jpg similarity index 100% rename from wpsbuilder/assets/img/team/team02.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/img/team/team02.jpg diff --git a/wpsbuilder/assets/js/bootstrap.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/bootstrap.js similarity index 100% rename from wpsbuilder/assets/js/bootstrap.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/bootstrap.js diff --git a/wpsbuilder/assets/js/bootstrap.min.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/bootstrap.min.js similarity index 100% rename from wpsbuilder/assets/js/bootstrap.min.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/bootstrap.min.js diff --git a/wpsbuilder/assets/js/interact.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/interact.js similarity index 100% rename from wpsbuilder/assets/js/interact.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/interact.js diff --git a/wpsbuilder/assets/js/jquery-func.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/jquery-func.js similarity index 100% rename from wpsbuilder/assets/js/jquery-func.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/jquery-func.js diff --git a/wpsbuilder/assets/js/jquery.easing.1.3.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/jquery.easing.1.3.js similarity index 100% rename from wpsbuilder/assets/js/jquery.easing.1.3.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/jquery.easing.1.3.js diff --git a/wpsbuilder/assets/js/jquery.min.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/jquery.min.js similarity index 100% rename from wpsbuilder/assets/js/jquery.min.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/jquery.min.js diff --git a/wpsbuilder/assets/js/modernizr.custom.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/modernizr.custom.js similarity index 100% rename from wpsbuilder/assets/js/modernizr.custom.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/modernizr.custom.js diff --git a/wpsbuilder/assets/js/retina.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/retina.js similarity index 100% rename from wpsbuilder/assets/js/retina.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/retina.js diff --git a/wpsbuilder/assets/js/smoothscroll.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/smoothscroll.js similarity index 100% rename from wpsbuilder/assets/js/smoothscroll.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/assets/js/smoothscroll.js diff --git a/wpsbuilder/components/bootstrap/dist/css/bootstrap.min.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/bootstrap/dist/css/bootstrap.min.css similarity index 100% rename from wpsbuilder/components/bootstrap/dist/css/bootstrap.min.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/bootstrap/dist/css/bootstrap.min.css diff --git a/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot diff --git a/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg diff --git a/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf diff --git a/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/css/all.min.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/css/all.min.css new file mode 100644 index 000000000..b2da17dcf --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/css/all.min.css @@ -0,0 +1,9 @@ +/*! + * Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2026 Fonticons, Inc. + */ +.fa,.fa-brands,.fa-classic,.fa-regular,.fa-solid,.fab,.far,.fas{--_fa-family:var(--fa-family,var(--fa-style-family,"Font Awesome 7 Free"));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:var(--fa-display,inline-block);font-family:var(--_fa-family);font-feature-settings:normal;font-style:normal;font-synthesis:none;font-variant:normal;font-weight:var(--fa-style,900);line-height:1;text-align:center;text-rendering:auto;width:var(--fa-width,1.25em)}:is(.fas,.far,.fab,.fa-solid,.fa-regular,.fa-brands,.fa-classic,.fa):before{content:var(--fa)/""}@supports not (content:""/""){:is(.fas,.far,.fab,.fa-solid,.fa-regular,.fa-brands,.fa-classic,.fa):before{content:var(--fa)}}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-width-auto{--fa-width:auto}.fa-fw,.fa-width-fixed{--fa-width:1.25em}.fa-ul{list-style-type:none;margin-inline-start:var(--fa-li-margin,2.5em);padding-inline-start:0}.fa-ul>li{position:relative}.fa-li{inset-inline-start:calc(var(--fa-li-width, 2em)*-1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-radius:var(--fa-border-radius,.1em);border:var(--fa-border-width,.0625em) var(--fa-border-style,solid) var(--fa-border-color,#eee);box-sizing:var(--fa-border-box-sizing,content-box);padding:var(--fa-border-padding,.1875em .25em)}.fa-pull-left,.fa-pull-start{float:inline-start;margin-inline-end:var(--fa-pull-margin,.3em)}.fa-pull-end,.fa-pull-right{float:inline-end;margin-inline-start:var(--fa-pull-margin,.3em)}.fa-beat{animation-name:fa-beat;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{animation-name:fa-bounce;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{animation-name:fa-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s)}.fa-beat-fade{animation-name:fa-beat-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{animation-name:fa-flip;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{animation-name:fa-shake;animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-shake,.fa-spin{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal)}.fa-spin{animation-name:fa-spin;animation-duration:var(--fa-animation-duration,2s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{animation-name:fa-spin;animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{animation:none!important;transition:none!important}}@keyframes fa-beat{0%,90%{transform:scale(1)}45%{transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-bounce{0%{transform:scale(1) translateY(0)}10%{transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{transform:scale(1) translateY(0)}to{transform:scale(1) translateY(0)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);transform:scale(1)}50%{opacity:1;transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-flip{50%{transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-shake{0%{transform:rotate(-15deg)}4%{transform:rotate(15deg)}8%,24%{transform:rotate(-18deg)}12%,28%{transform:rotate(18deg)}16%{transform:rotate(-22deg)}20%{transform:rotate(22deg)}32%{transform:rotate(-12deg)}36%{transform:rotate(12deg)}40%,to{transform:rotate(0deg)}}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{transform:rotate(90deg)}.fa-rotate-180{transform:rotate(180deg)}.fa-rotate-270{transform:rotate(270deg)}.fa-flip-horizontal{transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}.fa-rotate-by{transform:rotate(var(--fa-rotate-angle,0))}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{--fa-width:100%;inset:0;position:absolute;text-align:center;width:var(--fa-width);z-index:var(--fa-stack-z-index,auto)}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:var(--fa-inverse,#fff)} + +.fa-0{--fa:"\30 "}.fa-1{--fa:"\31 "}.fa-2{--fa:"\32 "}.fa-3{--fa:"\33 "}.fa-4{--fa:"\34 "}.fa-5{--fa:"\35 "}.fa-6{--fa:"\36 "}.fa-7{--fa:"\37 "}.fa-8{--fa:"\38 "}.fa-9{--fa:"\39 "}.fa-exclamation{--fa:"\!"}.fa-hashtag{--fa:"\#"}.fa-dollar,.fa-dollar-sign,.fa-usd{--fa:"\$"}.fa-percent,.fa-percentage{--fa:"\%"}.fa-asterisk{--fa:"\*"}.fa-add,.fa-plus{--fa:"\+"}.fa-less-than{--fa:"\<"}.fa-equals{--fa:"\="}.fa-greater-than{--fa:"\>"}.fa-question{--fa:"\?"}.fa-at{--fa:"\@"}.fa-a{--fa:"A"}.fa-b{--fa:"B"}.fa-c{--fa:"C"}.fa-d{--fa:"D"}.fa-e{--fa:"E"}.fa-f{--fa:"F"}.fa-g{--fa:"G"}.fa-h{--fa:"H"}.fa-i{--fa:"I"}.fa-j{--fa:"J"}.fa-k{--fa:"K"}.fa-l{--fa:"L"}.fa-m{--fa:"M"}.fa-n{--fa:"N"}.fa-o{--fa:"O"}.fa-p{--fa:"P"}.fa-q{--fa:"Q"}.fa-r{--fa:"R"}.fa-s{--fa:"S"}.fa-t{--fa:"T"}.fa-u{--fa:"U"}.fa-v{--fa:"V"}.fa-w{--fa:"W"}.fa-x{--fa:"X"}.fa-y{--fa:"Y"}.fa-z{--fa:"Z"}.fa-faucet{--fa:"\e005"}.fa-faucet-drip{--fa:"\e006"}.fa-house-chimney-window{--fa:"\e00d"}.fa-house-signal{--fa:"\e012"}.fa-temperature-arrow-down,.fa-temperature-down{--fa:"\e03f"}.fa-temperature-arrow-up,.fa-temperature-up{--fa:"\e040"}.fa-trailer{--fa:"\e041"}.fa-bacteria{--fa:"\e059"}.fa-bacterium{--fa:"\e05a"}.fa-box-tissue{--fa:"\e05b"}.fa-hand-holding-medical{--fa:"\e05c"}.fa-hand-sparkles{--fa:"\e05d"}.fa-hands-bubbles,.fa-hands-wash{--fa:"\e05e"}.fa-handshake-alt-slash,.fa-handshake-simple-slash,.fa-handshake-slash{--fa:"\e060"}.fa-head-side-cough{--fa:"\e061"}.fa-head-side-cough-slash{--fa:"\e062"}.fa-head-side-mask{--fa:"\e063"}.fa-head-side-virus{--fa:"\e064"}.fa-house-chimney-user{--fa:"\e065"}.fa-house-laptop,.fa-laptop-house{--fa:"\e066"}.fa-lungs-virus{--fa:"\e067"}.fa-people-arrows,.fa-people-arrows-left-right{--fa:"\e068"}.fa-plane-slash{--fa:"\e069"}.fa-pump-medical{--fa:"\e06a"}.fa-pump-soap{--fa:"\e06b"}.fa-shield-virus{--fa:"\e06c"}.fa-sink{--fa:"\e06d"}.fa-soap{--fa:"\e06e"}.fa-stopwatch-20{--fa:"\e06f"}.fa-shop-slash,.fa-store-alt-slash{--fa:"\e070"}.fa-store-slash{--fa:"\e071"}.fa-toilet-paper-slash{--fa:"\e072"}.fa-users-slash{--fa:"\e073"}.fa-virus{--fa:"\e074"}.fa-virus-slash{--fa:"\e075"}.fa-viruses{--fa:"\e076"}.fa-vest{--fa:"\e085"}.fa-vest-patches{--fa:"\e086"}.fa-arrow-trend-down{--fa:"\e097"}.fa-arrow-trend-up{--fa:"\e098"}.fa-arrow-up-from-bracket{--fa:"\e09a"}.fa-austral-sign{--fa:"\e0a9"}.fa-baht-sign{--fa:"\e0ac"}.fa-bitcoin-sign{--fa:"\e0b4"}.fa-bolt-lightning{--fa:"\e0b7"}.fa-book-bookmark{--fa:"\e0bb"}.fa-camera-rotate{--fa:"\e0d8"}.fa-cedi-sign{--fa:"\e0df"}.fa-chart-column{--fa:"\e0e3"}.fa-chart-gantt{--fa:"\e0e4"}.fa-clapperboard{--fa:"\e131"}.fa-closed-captioning-slash{--fa:"\e135"}.fa-clover{--fa:"\e139"}.fa-code-compare{--fa:"\e13a"}.fa-code-fork{--fa:"\e13b"}.fa-code-pull-request{--fa:"\e13c"}.fa-colon-sign{--fa:"\e140"}.fa-cruzeiro-sign{--fa:"\e152"}.fa-display{--fa:"\e163"}.fa-dong-sign{--fa:"\e169"}.fa-elevator{--fa:"\e16d"}.fa-filter-circle-xmark{--fa:"\e17b"}.fa-florin-sign{--fa:"\e184"}.fa-folder-closed{--fa:"\e185"}.fa-franc-sign{--fa:"\e18f"}.fa-guarani-sign{--fa:"\e19a"}.fa-gun{--fa:"\e19b"}.fa-hands-clapping{--fa:"\e1a8"}.fa-home-user,.fa-house-user{--fa:"\e1b0"}.fa-indian-rupee,.fa-indian-rupee-sign,.fa-inr{--fa:"\e1bc"}.fa-kip-sign{--fa:"\e1c4"}.fa-lari-sign{--fa:"\e1c8"}.fa-litecoin-sign{--fa:"\e1d3"}.fa-manat-sign{--fa:"\e1d5"}.fa-mask-face{--fa:"\e1d7"}.fa-mill-sign{--fa:"\e1ed"}.fa-money-bills{--fa:"\e1f3"}.fa-naira-sign{--fa:"\e1f6"}.fa-notdef{--fa:"\e1fe"}.fa-panorama{--fa:"\e209"}.fa-peseta-sign{--fa:"\e221"}.fa-peso-sign{--fa:"\e222"}.fa-plane-up{--fa:"\e22d"}.fa-rupiah-sign{--fa:"\e23d"}.fa-stairs{--fa:"\e289"}.fa-timeline{--fa:"\e29c"}.fa-truck-front{--fa:"\e2b7"}.fa-try,.fa-turkish-lira,.fa-turkish-lira-sign{--fa:"\e2bb"}.fa-vault{--fa:"\e2c5"}.fa-magic-wand-sparkles,.fa-wand-magic-sparkles{--fa:"\e2ca"}.fa-wheat-alt,.fa-wheat-awn{--fa:"\e2cd"}.fa-wheelchair-alt,.fa-wheelchair-move{--fa:"\e2ce"}.fa-bangladeshi-taka-sign{--fa:"\e2e6"}.fa-bowl-rice{--fa:"\e2eb"}.fa-person-pregnant{--fa:"\e31e"}.fa-home-lg,.fa-house-chimney{--fa:"\e3af"}.fa-house-crack{--fa:"\e3b1"}.fa-house-medical{--fa:"\e3b2"}.fa-cent-sign{--fa:"\e3f5"}.fa-plus-minus{--fa:"\e43c"}.fa-sailboat{--fa:"\e445"}.fa-section{--fa:"\e447"}.fa-shrimp{--fa:"\e448"}.fa-brazilian-real-sign{--fa:"\e46c"}.fa-chart-simple{--fa:"\e473"}.fa-diagram-next{--fa:"\e476"}.fa-diagram-predecessor{--fa:"\e477"}.fa-diagram-successor{--fa:"\e47a"}.fa-earth-oceania,.fa-globe-oceania{--fa:"\e47b"}.fa-bug-slash{--fa:"\e490"}.fa-file-circle-plus{--fa:"\e494"}.fa-shop-lock{--fa:"\e4a5"}.fa-virus-covid{--fa:"\e4a8"}.fa-virus-covid-slash{--fa:"\e4a9"}.fa-anchor-circle-check{--fa:"\e4aa"}.fa-anchor-circle-exclamation{--fa:"\e4ab"}.fa-anchor-circle-xmark{--fa:"\e4ac"}.fa-anchor-lock{--fa:"\e4ad"}.fa-arrow-down-up-across-line{--fa:"\e4af"}.fa-arrow-down-up-lock{--fa:"\e4b0"}.fa-arrow-right-to-city{--fa:"\e4b3"}.fa-arrow-up-from-ground-water{--fa:"\e4b5"}.fa-arrow-up-from-water-pump{--fa:"\e4b6"}.fa-arrow-up-right-dots{--fa:"\e4b7"}.fa-arrows-down-to-line{--fa:"\e4b8"}.fa-arrows-down-to-people{--fa:"\e4b9"}.fa-arrows-left-right-to-line{--fa:"\e4ba"}.fa-arrows-spin{--fa:"\e4bb"}.fa-arrows-split-up-and-left{--fa:"\e4bc"}.fa-arrows-to-circle{--fa:"\e4bd"}.fa-arrows-to-dot{--fa:"\e4be"}.fa-arrows-to-eye{--fa:"\e4bf"}.fa-arrows-turn-right{--fa:"\e4c0"}.fa-arrows-turn-to-dots{--fa:"\e4c1"}.fa-arrows-up-to-line{--fa:"\e4c2"}.fa-bore-hole{--fa:"\e4c3"}.fa-bottle-droplet{--fa:"\e4c4"}.fa-bottle-water{--fa:"\e4c5"}.fa-bowl-food{--fa:"\e4c6"}.fa-boxes-packing{--fa:"\e4c7"}.fa-bridge{--fa:"\e4c8"}.fa-bridge-circle-check{--fa:"\e4c9"}.fa-bridge-circle-exclamation{--fa:"\e4ca"}.fa-bridge-circle-xmark{--fa:"\e4cb"}.fa-bridge-lock{--fa:"\e4cc"}.fa-bridge-water{--fa:"\e4ce"}.fa-bucket{--fa:"\e4cf"}.fa-bugs{--fa:"\e4d0"}.fa-building-circle-arrow-right{--fa:"\e4d1"}.fa-building-circle-check{--fa:"\e4d2"}.fa-building-circle-exclamation{--fa:"\e4d3"}.fa-building-circle-xmark{--fa:"\e4d4"}.fa-building-flag{--fa:"\e4d5"}.fa-building-lock{--fa:"\e4d6"}.fa-building-ngo{--fa:"\e4d7"}.fa-building-shield{--fa:"\e4d8"}.fa-building-un{--fa:"\e4d9"}.fa-building-user{--fa:"\e4da"}.fa-building-wheat{--fa:"\e4db"}.fa-burst{--fa:"\e4dc"}.fa-car-on{--fa:"\e4dd"}.fa-car-tunnel{--fa:"\e4de"}.fa-child-combatant,.fa-child-rifle{--fa:"\e4e0"}.fa-children{--fa:"\e4e1"}.fa-circle-nodes{--fa:"\e4e2"}.fa-clipboard-question{--fa:"\e4e3"}.fa-cloud-showers-water{--fa:"\e4e4"}.fa-computer{--fa:"\e4e5"}.fa-cubes-stacked{--fa:"\e4e6"}.fa-envelope-circle-check{--fa:"\e4e8"}.fa-explosion{--fa:"\e4e9"}.fa-ferry{--fa:"\e4ea"}.fa-file-circle-exclamation{--fa:"\e4eb"}.fa-file-circle-minus{--fa:"\e4ed"}.fa-file-circle-question{--fa:"\e4ef"}.fa-file-shield{--fa:"\e4f0"}.fa-fire-burner{--fa:"\e4f1"}.fa-fish-fins{--fa:"\e4f2"}.fa-flask-vial{--fa:"\e4f3"}.fa-glass-water{--fa:"\e4f4"}.fa-glass-water-droplet{--fa:"\e4f5"}.fa-group-arrows-rotate{--fa:"\e4f6"}.fa-hand-holding-hand{--fa:"\e4f7"}.fa-handcuffs{--fa:"\e4f8"}.fa-hands-bound{--fa:"\e4f9"}.fa-hands-holding-child{--fa:"\e4fa"}.fa-hands-holding-circle{--fa:"\e4fb"}.fa-heart-circle-bolt{--fa:"\e4fc"}.fa-heart-circle-check{--fa:"\e4fd"}.fa-heart-circle-exclamation{--fa:"\e4fe"}.fa-heart-circle-minus{--fa:"\e4ff"}.fa-heart-circle-plus{--fa:"\e500"}.fa-heart-circle-xmark{--fa:"\e501"}.fa-helicopter-symbol{--fa:"\e502"}.fa-helmet-un{--fa:"\e503"}.fa-hill-avalanche{--fa:"\e507"}.fa-hill-rockslide{--fa:"\e508"}.fa-house-circle-check{--fa:"\e509"}.fa-house-circle-exclamation{--fa:"\e50a"}.fa-house-circle-xmark{--fa:"\e50b"}.fa-house-fire{--fa:"\e50c"}.fa-house-flag{--fa:"\e50d"}.fa-house-flood-water{--fa:"\e50e"}.fa-house-flood-water-circle-arrow-right{--fa:"\e50f"}.fa-house-lock{--fa:"\e510"}.fa-house-medical-circle-check{--fa:"\e511"}.fa-house-medical-circle-exclamation{--fa:"\e512"}.fa-house-medical-circle-xmark{--fa:"\e513"}.fa-house-medical-flag{--fa:"\e514"}.fa-house-tsunami{--fa:"\e515"}.fa-jar{--fa:"\e516"}.fa-jar-wheat{--fa:"\e517"}.fa-jet-fighter-up{--fa:"\e518"}.fa-jug-detergent{--fa:"\e519"}.fa-kitchen-set{--fa:"\e51a"}.fa-land-mine-on{--fa:"\e51b"}.fa-landmark-flag{--fa:"\e51c"}.fa-laptop-file{--fa:"\e51d"}.fa-lines-leaning{--fa:"\e51e"}.fa-location-pin-lock{--fa:"\e51f"}.fa-locust{--fa:"\e520"}.fa-magnifying-glass-arrow-right{--fa:"\e521"}.fa-magnifying-glass-chart{--fa:"\e522"}.fa-mars-and-venus-burst{--fa:"\e523"}.fa-mask-ventilator{--fa:"\e524"}.fa-mattress-pillow{--fa:"\e525"}.fa-mobile-retro{--fa:"\e527"}.fa-money-bill-transfer{--fa:"\e528"}.fa-money-bill-trend-up{--fa:"\e529"}.fa-money-bill-wheat{--fa:"\e52a"}.fa-mosquito{--fa:"\e52b"}.fa-mosquito-net{--fa:"\e52c"}.fa-mound{--fa:"\e52d"}.fa-mountain-city{--fa:"\e52e"}.fa-mountain-sun{--fa:"\e52f"}.fa-oil-well{--fa:"\e532"}.fa-people-group{--fa:"\e533"}.fa-people-line{--fa:"\e534"}.fa-people-pulling{--fa:"\e535"}.fa-people-robbery{--fa:"\e536"}.fa-people-roof{--fa:"\e537"}.fa-person-arrow-down-to-line{--fa:"\e538"}.fa-person-arrow-up-from-line{--fa:"\e539"}.fa-person-breastfeeding{--fa:"\e53a"}.fa-person-burst{--fa:"\e53b"}.fa-person-cane{--fa:"\e53c"}.fa-person-chalkboard{--fa:"\e53d"}.fa-person-circle-check{--fa:"\e53e"}.fa-person-circle-exclamation{--fa:"\e53f"}.fa-person-circle-minus{--fa:"\e540"}.fa-person-circle-plus{--fa:"\e541"}.fa-person-circle-question{--fa:"\e542"}.fa-person-circle-xmark{--fa:"\e543"}.fa-person-dress-burst{--fa:"\e544"}.fa-person-drowning{--fa:"\e545"}.fa-person-falling{--fa:"\e546"}.fa-person-falling-burst{--fa:"\e547"}.fa-person-half-dress{--fa:"\e548"}.fa-person-harassing{--fa:"\e549"}.fa-person-military-pointing{--fa:"\e54a"}.fa-person-military-rifle{--fa:"\e54b"}.fa-person-military-to-person{--fa:"\e54c"}.fa-person-rays{--fa:"\e54d"}.fa-person-rifle{--fa:"\e54e"}.fa-person-shelter{--fa:"\e54f"}.fa-person-walking-arrow-loop-left{--fa:"\e551"}.fa-person-walking-arrow-right{--fa:"\e552"}.fa-person-walking-dashed-line-arrow-right{--fa:"\e553"}.fa-person-walking-luggage{--fa:"\e554"}.fa-plane-circle-check{--fa:"\e555"}.fa-plane-circle-exclamation{--fa:"\e556"}.fa-plane-circle-xmark{--fa:"\e557"}.fa-plane-lock{--fa:"\e558"}.fa-plate-wheat{--fa:"\e55a"}.fa-plug-circle-bolt{--fa:"\e55b"}.fa-plug-circle-check{--fa:"\e55c"}.fa-plug-circle-exclamation{--fa:"\e55d"}.fa-plug-circle-minus{--fa:"\e55e"}.fa-plug-circle-plus{--fa:"\e55f"}.fa-plug-circle-xmark{--fa:"\e560"}.fa-ranking-star{--fa:"\e561"}.fa-road-barrier{--fa:"\e562"}.fa-road-bridge{--fa:"\e563"}.fa-road-circle-check{--fa:"\e564"}.fa-road-circle-exclamation{--fa:"\e565"}.fa-road-circle-xmark{--fa:"\e566"}.fa-road-lock{--fa:"\e567"}.fa-road-spikes{--fa:"\e568"}.fa-rug{--fa:"\e569"}.fa-sack-xmark{--fa:"\e56a"}.fa-school-circle-check{--fa:"\e56b"}.fa-school-circle-exclamation{--fa:"\e56c"}.fa-school-circle-xmark{--fa:"\e56d"}.fa-school-flag{--fa:"\e56e"}.fa-school-lock{--fa:"\e56f"}.fa-sheet-plastic{--fa:"\e571"}.fa-shield-cat{--fa:"\e572"}.fa-shield-dog{--fa:"\e573"}.fa-shield-heart{--fa:"\e574"}.fa-square-nfi{--fa:"\e576"}.fa-square-person-confined{--fa:"\e577"}.fa-square-virus{--fa:"\e578"}.fa-rod-asclepius,.fa-rod-snake,.fa-staff-aesculapius,.fa-staff-snake{--fa:"\e579"}.fa-sun-plant-wilt{--fa:"\e57a"}.fa-tarp{--fa:"\e57b"}.fa-tarp-droplet{--fa:"\e57c"}.fa-tent{--fa:"\e57d"}.fa-tent-arrow-down-to-line{--fa:"\e57e"}.fa-tent-arrow-left-right{--fa:"\e57f"}.fa-tent-arrow-turn-left{--fa:"\e580"}.fa-tent-arrows-down{--fa:"\e581"}.fa-tents{--fa:"\e582"}.fa-toilet-portable{--fa:"\e583"}.fa-toilets-portable{--fa:"\e584"}.fa-tower-cell{--fa:"\e585"}.fa-tower-observation{--fa:"\e586"}.fa-tree-city{--fa:"\e587"}.fa-trowel{--fa:"\e589"}.fa-trowel-bricks{--fa:"\e58a"}.fa-truck-arrow-right{--fa:"\e58b"}.fa-truck-droplet{--fa:"\e58c"}.fa-truck-field{--fa:"\e58d"}.fa-truck-field-un{--fa:"\e58e"}.fa-truck-plane{--fa:"\e58f"}.fa-users-between-lines{--fa:"\e591"}.fa-users-line{--fa:"\e592"}.fa-users-rays{--fa:"\e593"}.fa-users-rectangle{--fa:"\e594"}.fa-users-viewfinder{--fa:"\e595"}.fa-vial-circle-check{--fa:"\e596"}.fa-vial-virus{--fa:"\e597"}.fa-wheat-awn-circle-exclamation{--fa:"\e598"}.fa-worm{--fa:"\e599"}.fa-xmarks-lines{--fa:"\e59a"}.fa-child-dress{--fa:"\e59c"}.fa-child-reaching{--fa:"\e59d"}.fa-file-circle-check{--fa:"\e5a0"}.fa-file-circle-xmark{--fa:"\e5a1"}.fa-person-through-window{--fa:"\e5a9"}.fa-plant-wilt{--fa:"\e5aa"}.fa-stapler{--fa:"\e5af"}.fa-train-tram{--fa:"\e5b4"}.fa-table-cells-column-lock{--fa:"\e678"}.fa-table-cells-row-lock{--fa:"\e67a"}.fa-thumb-tack-slash,.fa-thumbtack-slash{--fa:"\e68f"}.fa-table-cells-row-unlock{--fa:"\e691"}.fa-chart-diagram{--fa:"\e695"}.fa-comment-nodes{--fa:"\e696"}.fa-file-fragment{--fa:"\e697"}.fa-file-half-dashed{--fa:"\e698"}.fa-hexagon-nodes{--fa:"\e699"}.fa-hexagon-nodes-bolt{--fa:"\e69a"}.fa-square-binary{--fa:"\e69b"}.fa-pentagon{--fa:"\e790"}.fa-non-binary{--fa:"\e807"}.fa-spiral{--fa:"\e80a"}.fa-picture-in-picture{--fa:"\e80b"}.fa-mobile-vibrate{--fa:"\e816"}.fa-single-quote-left{--fa:"\e81b"}.fa-single-quote-right{--fa:"\e81c"}.fa-bus-side{--fa:"\e81d"}.fa-heptagon,.fa-septagon{--fa:"\e820"}.fa-aquarius{--fa:"\e845"}.fa-aries{--fa:"\e846"}.fa-cancer{--fa:"\e847"}.fa-capricorn{--fa:"\e848"}.fa-gemini{--fa:"\e849"}.fa-leo{--fa:"\e84a"}.fa-libra{--fa:"\e84b"}.fa-pisces{--fa:"\e84c"}.fa-sagittarius{--fa:"\e84d"}.fa-scorpio{--fa:"\e84e"}.fa-taurus{--fa:"\e84f"}.fa-virgo{--fa:"\e850"}.fa-glass-martini,.fa-martini-glass-empty{--fa:"\f000"}.fa-music{--fa:"\f001"}.fa-magnifying-glass,.fa-search{--fa:"\f002"}.fa-heart{--fa:"\f004"}.fa-star{--fa:"\f005"}.fa-user,.fa-user-alt,.fa-user-large{--fa:"\f007"}.fa-film,.fa-film-alt,.fa-film-simple{--fa:"\f008"}.fa-table-cells-large,.fa-th-large{--fa:"\f009"}.fa-table-cells,.fa-th{--fa:"\f00a"}.fa-table-list,.fa-th-list{--fa:"\f00b"}.fa-check{--fa:"\f00c"}.fa-close,.fa-multiply,.fa-remove,.fa-times,.fa-xmark{--fa:"\f00d"}.fa-magnifying-glass-plus,.fa-search-plus{--fa:"\f00e"}.fa-magnifying-glass-minus,.fa-search-minus{--fa:"\f010"}.fa-power-off{--fa:"\f011"}.fa-signal,.fa-signal-5,.fa-signal-perfect{--fa:"\f012"}.fa-cog,.fa-gear{--fa:"\f013"}.fa-home,.fa-home-alt,.fa-home-lg-alt,.fa-house{--fa:"\f015"}.fa-clock,.fa-clock-four{--fa:"\f017"}.fa-road{--fa:"\f018"}.fa-download{--fa:"\f019"}.fa-inbox{--fa:"\f01c"}.fa-arrow-right-rotate,.fa-arrow-rotate-forward,.fa-arrow-rotate-right,.fa-redo{--fa:"\f01e"}.fa-arrows-rotate,.fa-refresh,.fa-sync{--fa:"\f021"}.fa-list-alt,.fa-rectangle-list{--fa:"\f022"}.fa-lock{--fa:"\f023"}.fa-flag{--fa:"\f024"}.fa-headphones,.fa-headphones-alt,.fa-headphones-simple{--fa:"\f025"}.fa-volume-off{--fa:"\f026"}.fa-volume-down,.fa-volume-low{--fa:"\f027"}.fa-volume-high,.fa-volume-up{--fa:"\f028"}.fa-qrcode{--fa:"\f029"}.fa-barcode{--fa:"\f02a"}.fa-tag{--fa:"\f02b"}.fa-tags{--fa:"\f02c"}.fa-book{--fa:"\f02d"}.fa-bookmark{--fa:"\f02e"}.fa-print{--fa:"\f02f"}.fa-camera,.fa-camera-alt{--fa:"\f030"}.fa-font{--fa:"\f031"}.fa-bold{--fa:"\f032"}.fa-italic{--fa:"\f033"}.fa-text-height{--fa:"\f034"}.fa-text-width{--fa:"\f035"}.fa-align-left{--fa:"\f036"}.fa-align-center{--fa:"\f037"}.fa-align-right{--fa:"\f038"}.fa-align-justify{--fa:"\f039"}.fa-list,.fa-list-squares{--fa:"\f03a"}.fa-dedent,.fa-outdent{--fa:"\f03b"}.fa-indent{--fa:"\f03c"}.fa-video,.fa-video-camera{--fa:"\f03d"}.fa-image{--fa:"\f03e"}.fa-location-pin,.fa-map-marker{--fa:"\f041"}.fa-adjust,.fa-circle-half-stroke{--fa:"\f042"}.fa-droplet,.fa-tint{--fa:"\f043"}.fa-edit,.fa-pen-to-square{--fa:"\f044"}.fa-arrows,.fa-arrows-up-down-left-right{--fa:"\f047"}.fa-backward-step,.fa-step-backward{--fa:"\f048"}.fa-backward-fast,.fa-fast-backward{--fa:"\f049"}.fa-backward{--fa:"\f04a"}.fa-play{--fa:"\f04b"}.fa-pause{--fa:"\f04c"}.fa-stop{--fa:"\f04d"}.fa-forward{--fa:"\f04e"}.fa-fast-forward,.fa-forward-fast{--fa:"\f050"}.fa-forward-step,.fa-step-forward{--fa:"\f051"}.fa-eject{--fa:"\f052"}.fa-chevron-left{--fa:"\f053"}.fa-chevron-right{--fa:"\f054"}.fa-circle-plus,.fa-plus-circle{--fa:"\f055"}.fa-circle-minus,.fa-minus-circle{--fa:"\f056"}.fa-circle-xmark,.fa-times-circle,.fa-xmark-circle{--fa:"\f057"}.fa-check-circle,.fa-circle-check{--fa:"\f058"}.fa-circle-question,.fa-question-circle{--fa:"\f059"}.fa-circle-info,.fa-info-circle{--fa:"\f05a"}.fa-crosshairs{--fa:"\f05b"}.fa-ban,.fa-cancel{--fa:"\f05e"}.fa-arrow-left{--fa:"\f060"}.fa-arrow-right{--fa:"\f061"}.fa-arrow-up{--fa:"\f062"}.fa-arrow-down{--fa:"\f063"}.fa-mail-forward,.fa-share{--fa:"\f064"}.fa-expand{--fa:"\f065"}.fa-compress{--fa:"\f066"}.fa-minus,.fa-subtract{--fa:"\f068"}.fa-circle-exclamation,.fa-exclamation-circle{--fa:"\f06a"}.fa-gift{--fa:"\f06b"}.fa-leaf{--fa:"\f06c"}.fa-fire{--fa:"\f06d"}.fa-eye{--fa:"\f06e"}.fa-eye-slash{--fa:"\f070"}.fa-exclamation-triangle,.fa-triangle-exclamation,.fa-warning{--fa:"\f071"}.fa-plane{--fa:"\f072"}.fa-calendar-alt,.fa-calendar-days{--fa:"\f073"}.fa-random,.fa-shuffle{--fa:"\f074"}.fa-comment{--fa:"\f075"}.fa-magnet{--fa:"\f076"}.fa-chevron-up{--fa:"\f077"}.fa-chevron-down{--fa:"\f078"}.fa-retweet{--fa:"\f079"}.fa-cart-shopping,.fa-shopping-cart{--fa:"\f07a"}.fa-folder,.fa-folder-blank{--fa:"\f07b"}.fa-folder-open{--fa:"\f07c"}.fa-arrows-up-down,.fa-arrows-v{--fa:"\f07d"}.fa-arrows-h,.fa-arrows-left-right{--fa:"\f07e"}.fa-bar-chart,.fa-chart-bar{--fa:"\f080"}.fa-camera-retro{--fa:"\f083"}.fa-key{--fa:"\f084"}.fa-cogs,.fa-gears{--fa:"\f085"}.fa-comments{--fa:"\f086"}.fa-star-half{--fa:"\f089"}.fa-arrow-right-from-bracket,.fa-sign-out{--fa:"\f08b"}.fa-thumb-tack,.fa-thumbtack{--fa:"\f08d"}.fa-arrow-up-right-from-square,.fa-external-link{--fa:"\f08e"}.fa-arrow-right-to-bracket,.fa-sign-in{--fa:"\f090"}.fa-trophy{--fa:"\f091"}.fa-upload{--fa:"\f093"}.fa-lemon{--fa:"\f094"}.fa-phone{--fa:"\f095"}.fa-phone-square,.fa-square-phone{--fa:"\f098"}.fa-unlock{--fa:"\f09c"}.fa-credit-card,.fa-credit-card-alt{--fa:"\f09d"}.fa-feed,.fa-rss{--fa:"\f09e"}.fa-hard-drive,.fa-hdd{--fa:"\f0a0"}.fa-bullhorn{--fa:"\f0a1"}.fa-certificate{--fa:"\f0a3"}.fa-hand-point-right{--fa:"\f0a4"}.fa-hand-point-left{--fa:"\f0a5"}.fa-hand-point-up{--fa:"\f0a6"}.fa-hand-point-down{--fa:"\f0a7"}.fa-arrow-circle-left,.fa-circle-arrow-left{--fa:"\f0a8"}.fa-arrow-circle-right,.fa-circle-arrow-right{--fa:"\f0a9"}.fa-arrow-circle-up,.fa-circle-arrow-up{--fa:"\f0aa"}.fa-arrow-circle-down,.fa-circle-arrow-down{--fa:"\f0ab"}.fa-globe{--fa:"\f0ac"}.fa-wrench{--fa:"\f0ad"}.fa-list-check,.fa-tasks{--fa:"\f0ae"}.fa-filter{--fa:"\f0b0"}.fa-briefcase{--fa:"\f0b1"}.fa-arrows-alt,.fa-up-down-left-right{--fa:"\f0b2"}.fa-users{--fa:"\f0c0"}.fa-chain,.fa-link{--fa:"\f0c1"}.fa-cloud{--fa:"\f0c2"}.fa-flask{--fa:"\f0c3"}.fa-cut,.fa-scissors{--fa:"\f0c4"}.fa-copy{--fa:"\f0c5"}.fa-paperclip{--fa:"\f0c6"}.fa-floppy-disk,.fa-save{--fa:"\f0c7"}.fa-square{--fa:"\f0c8"}.fa-bars,.fa-navicon{--fa:"\f0c9"}.fa-list-dots,.fa-list-ul{--fa:"\f0ca"}.fa-list-1-2,.fa-list-numeric,.fa-list-ol{--fa:"\f0cb"}.fa-strikethrough{--fa:"\f0cc"}.fa-underline{--fa:"\f0cd"}.fa-table{--fa:"\f0ce"}.fa-magic,.fa-wand-magic{--fa:"\f0d0"}.fa-truck{--fa:"\f0d1"}.fa-money-bill{--fa:"\f0d6"}.fa-caret-down{--fa:"\f0d7"}.fa-caret-up{--fa:"\f0d8"}.fa-caret-left{--fa:"\f0d9"}.fa-caret-right{--fa:"\f0da"}.fa-columns,.fa-table-columns{--fa:"\f0db"}.fa-sort,.fa-unsorted{--fa:"\f0dc"}.fa-sort-desc,.fa-sort-down{--fa:"\f0dd"}.fa-sort-asc,.fa-sort-up{--fa:"\f0de"}.fa-envelope{--fa:"\f0e0"}.fa-arrow-left-rotate,.fa-arrow-rotate-back,.fa-arrow-rotate-backward,.fa-arrow-rotate-left,.fa-undo{--fa:"\f0e2"}.fa-gavel,.fa-legal{--fa:"\f0e3"}.fa-bolt,.fa-zap{--fa:"\f0e7"}.fa-sitemap{--fa:"\f0e8"}.fa-umbrella{--fa:"\f0e9"}.fa-file-clipboard,.fa-paste{--fa:"\f0ea"}.fa-lightbulb{--fa:"\f0eb"}.fa-arrow-right-arrow-left,.fa-exchange{--fa:"\f0ec"}.fa-cloud-arrow-down,.fa-cloud-download,.fa-cloud-download-alt{--fa:"\f0ed"}.fa-cloud-arrow-up,.fa-cloud-upload,.fa-cloud-upload-alt{--fa:"\f0ee"}.fa-user-doctor,.fa-user-md{--fa:"\f0f0"}.fa-stethoscope{--fa:"\f0f1"}.fa-suitcase{--fa:"\f0f2"}.fa-bell{--fa:"\f0f3"}.fa-coffee,.fa-mug-saucer{--fa:"\f0f4"}.fa-hospital,.fa-hospital-alt,.fa-hospital-wide{--fa:"\f0f8"}.fa-ambulance,.fa-truck-medical{--fa:"\f0f9"}.fa-medkit,.fa-suitcase-medical{--fa:"\f0fa"}.fa-fighter-jet,.fa-jet-fighter{--fa:"\f0fb"}.fa-beer,.fa-beer-mug-empty{--fa:"\f0fc"}.fa-h-square,.fa-square-h{--fa:"\f0fd"}.fa-plus-square,.fa-square-plus{--fa:"\f0fe"}.fa-angle-double-left,.fa-angles-left{--fa:"\f100"}.fa-angle-double-right,.fa-angles-right{--fa:"\f101"}.fa-angle-double-up,.fa-angles-up{--fa:"\f102"}.fa-angle-double-down,.fa-angles-down{--fa:"\f103"}.fa-angle-left{--fa:"\f104"}.fa-angle-right{--fa:"\f105"}.fa-angle-up{--fa:"\f106"}.fa-angle-down{--fa:"\f107"}.fa-laptop{--fa:"\f109"}.fa-tablet-button{--fa:"\f10a"}.fa-mobile-button{--fa:"\f10b"}.fa-quote-left,.fa-quote-left-alt{--fa:"\f10d"}.fa-quote-right,.fa-quote-right-alt{--fa:"\f10e"}.fa-spinner{--fa:"\f110"}.fa-circle{--fa:"\f111"}.fa-face-smile,.fa-smile{--fa:"\f118"}.fa-face-frown,.fa-frown{--fa:"\f119"}.fa-face-meh,.fa-meh{--fa:"\f11a"}.fa-gamepad{--fa:"\f11b"}.fa-keyboard{--fa:"\f11c"}.fa-flag-checkered{--fa:"\f11e"}.fa-terminal{--fa:"\f120"}.fa-code{--fa:"\f121"}.fa-mail-reply-all,.fa-reply-all{--fa:"\f122"}.fa-location-arrow{--fa:"\f124"}.fa-crop{--fa:"\f125"}.fa-code-branch{--fa:"\f126"}.fa-chain-broken,.fa-chain-slash,.fa-link-slash,.fa-unlink{--fa:"\f127"}.fa-info{--fa:"\f129"}.fa-superscript{--fa:"\f12b"}.fa-subscript{--fa:"\f12c"}.fa-eraser{--fa:"\f12d"}.fa-puzzle-piece{--fa:"\f12e"}.fa-microphone{--fa:"\f130"}.fa-microphone-slash{--fa:"\f131"}.fa-shield,.fa-shield-blank{--fa:"\f132"}.fa-calendar{--fa:"\f133"}.fa-fire-extinguisher{--fa:"\f134"}.fa-rocket{--fa:"\f135"}.fa-chevron-circle-left,.fa-circle-chevron-left{--fa:"\f137"}.fa-chevron-circle-right,.fa-circle-chevron-right{--fa:"\f138"}.fa-chevron-circle-up,.fa-circle-chevron-up{--fa:"\f139"}.fa-chevron-circle-down,.fa-circle-chevron-down{--fa:"\f13a"}.fa-anchor{--fa:"\f13d"}.fa-unlock-alt,.fa-unlock-keyhole{--fa:"\f13e"}.fa-bullseye{--fa:"\f140"}.fa-ellipsis,.fa-ellipsis-h{--fa:"\f141"}.fa-ellipsis-v,.fa-ellipsis-vertical{--fa:"\f142"}.fa-rss-square,.fa-square-rss{--fa:"\f143"}.fa-circle-play,.fa-play-circle{--fa:"\f144"}.fa-ticket{--fa:"\f145"}.fa-minus-square,.fa-square-minus{--fa:"\f146"}.fa-arrow-turn-up,.fa-level-up{--fa:"\f148"}.fa-arrow-turn-down,.fa-level-down{--fa:"\f149"}.fa-check-square,.fa-square-check{--fa:"\f14a"}.fa-pen-square,.fa-pencil-square,.fa-square-pen{--fa:"\f14b"}.fa-external-link-square,.fa-square-arrow-up-right{--fa:"\f14c"}.fa-share-from-square,.fa-share-square{--fa:"\f14d"}.fa-compass{--fa:"\f14e"}.fa-caret-square-down,.fa-square-caret-down{--fa:"\f150"}.fa-caret-square-up,.fa-square-caret-up{--fa:"\f151"}.fa-caret-square-right,.fa-square-caret-right{--fa:"\f152"}.fa-eur,.fa-euro,.fa-euro-sign{--fa:"\f153"}.fa-gbp,.fa-pound-sign,.fa-sterling-sign{--fa:"\f154"}.fa-rupee,.fa-rupee-sign{--fa:"\f156"}.fa-cny,.fa-jpy,.fa-rmb,.fa-yen,.fa-yen-sign{--fa:"\f157"}.fa-rouble,.fa-rub,.fa-ruble,.fa-ruble-sign{--fa:"\f158"}.fa-krw,.fa-won,.fa-won-sign{--fa:"\f159"}.fa-file{--fa:"\f15b"}.fa-file-alt,.fa-file-lines,.fa-file-text{--fa:"\f15c"}.fa-arrow-down-a-z,.fa-sort-alpha-asc,.fa-sort-alpha-down{--fa:"\f15d"}.fa-arrow-up-a-z,.fa-sort-alpha-up{--fa:"\f15e"}.fa-arrow-down-wide-short,.fa-sort-amount-asc,.fa-sort-amount-down{--fa:"\f160"}.fa-arrow-up-wide-short,.fa-sort-amount-up{--fa:"\f161"}.fa-arrow-down-1-9,.fa-sort-numeric-asc,.fa-sort-numeric-down{--fa:"\f162"}.fa-arrow-up-1-9,.fa-sort-numeric-up{--fa:"\f163"}.fa-thumbs-up{--fa:"\f164"}.fa-thumbs-down{--fa:"\f165"}.fa-arrow-down-long,.fa-long-arrow-down{--fa:"\f175"}.fa-arrow-up-long,.fa-long-arrow-up{--fa:"\f176"}.fa-arrow-left-long,.fa-long-arrow-left{--fa:"\f177"}.fa-arrow-right-long,.fa-long-arrow-right{--fa:"\f178"}.fa-female,.fa-person-dress{--fa:"\f182"}.fa-male,.fa-person{--fa:"\f183"}.fa-sun{--fa:"\f185"}.fa-moon{--fa:"\f186"}.fa-archive,.fa-box-archive{--fa:"\f187"}.fa-bug{--fa:"\f188"}.fa-caret-square-left,.fa-square-caret-left{--fa:"\f191"}.fa-circle-dot,.fa-dot-circle{--fa:"\f192"}.fa-wheelchair{--fa:"\f193"}.fa-lira-sign{--fa:"\f195"}.fa-shuttle-space,.fa-space-shuttle{--fa:"\f197"}.fa-envelope-square,.fa-square-envelope{--fa:"\f199"}.fa-bank,.fa-building-columns,.fa-institution,.fa-museum,.fa-university{--fa:"\f19c"}.fa-graduation-cap,.fa-mortar-board{--fa:"\f19d"}.fa-language{--fa:"\f1ab"}.fa-fax{--fa:"\f1ac"}.fa-building{--fa:"\f1ad"}.fa-child{--fa:"\f1ae"}.fa-paw{--fa:"\f1b0"}.fa-cube{--fa:"\f1b2"}.fa-cubes{--fa:"\f1b3"}.fa-recycle{--fa:"\f1b8"}.fa-automobile,.fa-car{--fa:"\f1b9"}.fa-cab,.fa-taxi{--fa:"\f1ba"}.fa-tree{--fa:"\f1bb"}.fa-database{--fa:"\f1c0"}.fa-file-pdf{--fa:"\f1c1"}.fa-file-word{--fa:"\f1c2"}.fa-file-excel{--fa:"\f1c3"}.fa-file-powerpoint{--fa:"\f1c4"}.fa-file-image{--fa:"\f1c5"}.fa-file-archive,.fa-file-zipper{--fa:"\f1c6"}.fa-file-audio{--fa:"\f1c7"}.fa-file-video{--fa:"\f1c8"}.fa-file-code{--fa:"\f1c9"}.fa-life-ring{--fa:"\f1cd"}.fa-circle-notch{--fa:"\f1ce"}.fa-paper-plane{--fa:"\f1d8"}.fa-clock-rotate-left,.fa-history{--fa:"\f1da"}.fa-header,.fa-heading{--fa:"\f1dc"}.fa-paragraph{--fa:"\f1dd"}.fa-sliders,.fa-sliders-h{--fa:"\f1de"}.fa-share-alt,.fa-share-nodes{--fa:"\f1e0"}.fa-share-alt-square,.fa-square-share-nodes{--fa:"\f1e1"}.fa-bomb{--fa:"\f1e2"}.fa-futbol,.fa-futbol-ball,.fa-soccer-ball{--fa:"\f1e3"}.fa-teletype,.fa-tty{--fa:"\f1e4"}.fa-binoculars{--fa:"\f1e5"}.fa-plug{--fa:"\f1e6"}.fa-newspaper{--fa:"\f1ea"}.fa-wifi,.fa-wifi-3,.fa-wifi-strong{--fa:"\f1eb"}.fa-calculator{--fa:"\f1ec"}.fa-bell-slash{--fa:"\f1f6"}.fa-trash{--fa:"\f1f8"}.fa-copyright{--fa:"\f1f9"}.fa-eye-dropper,.fa-eye-dropper-empty,.fa-eyedropper{--fa:"\f1fb"}.fa-paint-brush,.fa-paintbrush{--fa:"\f1fc"}.fa-birthday-cake,.fa-cake,.fa-cake-candles{--fa:"\f1fd"}.fa-area-chart,.fa-chart-area{--fa:"\f1fe"}.fa-chart-pie,.fa-pie-chart{--fa:"\f200"}.fa-chart-line,.fa-line-chart{--fa:"\f201"}.fa-toggle-off{--fa:"\f204"}.fa-toggle-on{--fa:"\f205"}.fa-bicycle{--fa:"\f206"}.fa-bus{--fa:"\f207"}.fa-closed-captioning{--fa:"\f20a"}.fa-ils,.fa-shekel,.fa-shekel-sign,.fa-sheqel,.fa-sheqel-sign{--fa:"\f20b"}.fa-cart-plus{--fa:"\f217"}.fa-cart-arrow-down{--fa:"\f218"}.fa-diamond{--fa:"\f219"}.fa-ship{--fa:"\f21a"}.fa-user-secret{--fa:"\f21b"}.fa-motorcycle{--fa:"\f21c"}.fa-street-view{--fa:"\f21d"}.fa-heart-pulse,.fa-heartbeat{--fa:"\f21e"}.fa-venus{--fa:"\f221"}.fa-mars{--fa:"\f222"}.fa-mercury{--fa:"\f223"}.fa-mars-and-venus{--fa:"\f224"}.fa-transgender,.fa-transgender-alt{--fa:"\f225"}.fa-venus-double{--fa:"\f226"}.fa-mars-double{--fa:"\f227"}.fa-venus-mars{--fa:"\f228"}.fa-mars-stroke{--fa:"\f229"}.fa-mars-stroke-up,.fa-mars-stroke-v{--fa:"\f22a"}.fa-mars-stroke-h,.fa-mars-stroke-right{--fa:"\f22b"}.fa-neuter{--fa:"\f22c"}.fa-genderless{--fa:"\f22d"}.fa-server{--fa:"\f233"}.fa-user-plus{--fa:"\f234"}.fa-user-times,.fa-user-xmark{--fa:"\f235"}.fa-bed{--fa:"\f236"}.fa-train{--fa:"\f238"}.fa-subway,.fa-train-subway{--fa:"\f239"}.fa-battery,.fa-battery-5,.fa-battery-full{--fa:"\f240"}.fa-battery-4,.fa-battery-three-quarters{--fa:"\f241"}.fa-battery-3,.fa-battery-half{--fa:"\f242"}.fa-battery-2,.fa-battery-quarter{--fa:"\f243"}.fa-battery-0,.fa-battery-empty{--fa:"\f244"}.fa-arrow-pointer,.fa-mouse-pointer{--fa:"\f245"}.fa-i-cursor{--fa:"\f246"}.fa-object-group{--fa:"\f247"}.fa-object-ungroup{--fa:"\f248"}.fa-note-sticky,.fa-sticky-note{--fa:"\f249"}.fa-clone{--fa:"\f24d"}.fa-balance-scale,.fa-scale-balanced{--fa:"\f24e"}.fa-hourglass-1,.fa-hourglass-start{--fa:"\f251"}.fa-hourglass-2,.fa-hourglass-half{--fa:"\f252"}.fa-hourglass-3,.fa-hourglass-end{--fa:"\f253"}.fa-hourglass,.fa-hourglass-empty{--fa:"\f254"}.fa-hand-back-fist,.fa-hand-rock{--fa:"\f255"}.fa-hand,.fa-hand-paper{--fa:"\f256"}.fa-hand-scissors{--fa:"\f257"}.fa-hand-lizard{--fa:"\f258"}.fa-hand-spock{--fa:"\f259"}.fa-hand-pointer{--fa:"\f25a"}.fa-hand-peace{--fa:"\f25b"}.fa-trademark{--fa:"\f25c"}.fa-registered{--fa:"\f25d"}.fa-television,.fa-tv,.fa-tv-alt{--fa:"\f26c"}.fa-calendar-plus{--fa:"\f271"}.fa-calendar-minus{--fa:"\f272"}.fa-calendar-times,.fa-calendar-xmark{--fa:"\f273"}.fa-calendar-check{--fa:"\f274"}.fa-industry{--fa:"\f275"}.fa-map-pin{--fa:"\f276"}.fa-map-signs,.fa-signs-post{--fa:"\f277"}.fa-map{--fa:"\f279"}.fa-comment-alt,.fa-message{--fa:"\f27a"}.fa-circle-pause,.fa-pause-circle{--fa:"\f28b"}.fa-circle-stop,.fa-stop-circle{--fa:"\f28d"}.fa-bag-shopping,.fa-shopping-bag{--fa:"\f290"}.fa-basket-shopping,.fa-shopping-basket{--fa:"\f291"}.fa-universal-access{--fa:"\f29a"}.fa-blind,.fa-person-walking-with-cane{--fa:"\f29d"}.fa-audio-description{--fa:"\f29e"}.fa-phone-volume,.fa-volume-control-phone{--fa:"\f2a0"}.fa-braille{--fa:"\f2a1"}.fa-assistive-listening-systems,.fa-ear-listen{--fa:"\f2a2"}.fa-american-sign-language-interpreting,.fa-asl-interpreting,.fa-hands-american-sign-language-interpreting,.fa-hands-asl-interpreting{--fa:"\f2a3"}.fa-deaf,.fa-deafness,.fa-ear-deaf,.fa-hard-of-hearing{--fa:"\f2a4"}.fa-hands,.fa-sign-language,.fa-signing{--fa:"\f2a7"}.fa-eye-low-vision,.fa-low-vision{--fa:"\f2a8"}.fa-handshake,.fa-handshake-alt,.fa-handshake-simple{--fa:"\f2b5"}.fa-envelope-open{--fa:"\f2b6"}.fa-address-book,.fa-contact-book{--fa:"\f2b9"}.fa-address-card,.fa-contact-card,.fa-vcard{--fa:"\f2bb"}.fa-circle-user,.fa-user-circle{--fa:"\f2bd"}.fa-id-badge{--fa:"\f2c1"}.fa-drivers-license,.fa-id-card{--fa:"\f2c2"}.fa-temperature-4,.fa-temperature-full,.fa-thermometer-4,.fa-thermometer-full{--fa:"\f2c7"}.fa-temperature-3,.fa-temperature-three-quarters,.fa-thermometer-3,.fa-thermometer-three-quarters{--fa:"\f2c8"}.fa-temperature-2,.fa-temperature-half,.fa-thermometer-2,.fa-thermometer-half{--fa:"\f2c9"}.fa-temperature-1,.fa-temperature-quarter,.fa-thermometer-1,.fa-thermometer-quarter{--fa:"\f2ca"}.fa-temperature-0,.fa-temperature-empty,.fa-thermometer-0,.fa-thermometer-empty{--fa:"\f2cb"}.fa-shower{--fa:"\f2cc"}.fa-bath,.fa-bathtub{--fa:"\f2cd"}.fa-podcast{--fa:"\f2ce"}.fa-window-maximize{--fa:"\f2d0"}.fa-window-minimize{--fa:"\f2d1"}.fa-window-restore{--fa:"\f2d2"}.fa-square-xmark,.fa-times-square,.fa-xmark-square{--fa:"\f2d3"}.fa-microchip{--fa:"\f2db"}.fa-snowflake{--fa:"\f2dc"}.fa-spoon,.fa-utensil-spoon{--fa:"\f2e5"}.fa-cutlery,.fa-utensils{--fa:"\f2e7"}.fa-rotate-back,.fa-rotate-backward,.fa-rotate-left,.fa-undo-alt{--fa:"\f2ea"}.fa-trash-alt,.fa-trash-can{--fa:"\f2ed"}.fa-rotate,.fa-sync-alt{--fa:"\f2f1"}.fa-stopwatch{--fa:"\f2f2"}.fa-right-from-bracket,.fa-sign-out-alt{--fa:"\f2f5"}.fa-right-to-bracket,.fa-sign-in-alt{--fa:"\f2f6"}.fa-redo-alt,.fa-rotate-forward,.fa-rotate-right{--fa:"\f2f9"}.fa-poo{--fa:"\f2fe"}.fa-images{--fa:"\f302"}.fa-pencil,.fa-pencil-alt{--fa:"\f303"}.fa-pen{--fa:"\f304"}.fa-pen-alt,.fa-pen-clip{--fa:"\f305"}.fa-octagon{--fa:"\f306"}.fa-down-long,.fa-long-arrow-alt-down{--fa:"\f309"}.fa-left-long,.fa-long-arrow-alt-left{--fa:"\f30a"}.fa-long-arrow-alt-right,.fa-right-long{--fa:"\f30b"}.fa-long-arrow-alt-up,.fa-up-long{--fa:"\f30c"}.fa-hexagon{--fa:"\f312"}.fa-file-edit,.fa-file-pen{--fa:"\f31c"}.fa-expand-arrows-alt,.fa-maximize{--fa:"\f31e"}.fa-clipboard{--fa:"\f328"}.fa-arrows-alt-h,.fa-left-right{--fa:"\f337"}.fa-arrows-alt-v,.fa-up-down{--fa:"\f338"}.fa-alarm-clock{--fa:"\f34e"}.fa-arrow-alt-circle-down,.fa-circle-down{--fa:"\f358"}.fa-arrow-alt-circle-left,.fa-circle-left{--fa:"\f359"}.fa-arrow-alt-circle-right,.fa-circle-right{--fa:"\f35a"}.fa-arrow-alt-circle-up,.fa-circle-up{--fa:"\f35b"}.fa-external-link-alt,.fa-up-right-from-square{--fa:"\f35d"}.fa-external-link-square-alt,.fa-square-up-right{--fa:"\f360"}.fa-exchange-alt,.fa-right-left{--fa:"\f362"}.fa-repeat{--fa:"\f363"}.fa-code-commit{--fa:"\f386"}.fa-code-merge{--fa:"\f387"}.fa-desktop,.fa-desktop-alt{--fa:"\f390"}.fa-gem{--fa:"\f3a5"}.fa-level-down-alt,.fa-turn-down{--fa:"\f3be"}.fa-level-up-alt,.fa-turn-up{--fa:"\f3bf"}.fa-lock-open{--fa:"\f3c1"}.fa-location-dot,.fa-map-marker-alt{--fa:"\f3c5"}.fa-microphone-alt,.fa-microphone-lines{--fa:"\f3c9"}.fa-mobile-alt,.fa-mobile-screen-button{--fa:"\f3cd"}.fa-mobile,.fa-mobile-android,.fa-mobile-phone{--fa:"\f3ce"}.fa-mobile-android-alt,.fa-mobile-screen{--fa:"\f3cf"}.fa-money-bill-1,.fa-money-bill-alt{--fa:"\f3d1"}.fa-phone-slash{--fa:"\f3dd"}.fa-image-portrait,.fa-portrait{--fa:"\f3e0"}.fa-mail-reply,.fa-reply{--fa:"\f3e5"}.fa-shield-alt,.fa-shield-halved{--fa:"\f3ed"}.fa-tablet-alt,.fa-tablet-screen-button{--fa:"\f3fa"}.fa-tablet,.fa-tablet-android{--fa:"\f3fb"}.fa-ticket-alt,.fa-ticket-simple{--fa:"\f3ff"}.fa-rectangle-times,.fa-rectangle-xmark,.fa-times-rectangle,.fa-window-close{--fa:"\f410"}.fa-compress-alt,.fa-down-left-and-up-right-to-center{--fa:"\f422"}.fa-expand-alt,.fa-up-right-and-down-left-from-center{--fa:"\f424"}.fa-baseball-bat-ball{--fa:"\f432"}.fa-baseball,.fa-baseball-ball{--fa:"\f433"}.fa-basketball,.fa-basketball-ball{--fa:"\f434"}.fa-bowling-ball{--fa:"\f436"}.fa-chess{--fa:"\f439"}.fa-chess-bishop{--fa:"\f43a"}.fa-chess-board{--fa:"\f43c"}.fa-chess-king{--fa:"\f43f"}.fa-chess-knight{--fa:"\f441"}.fa-chess-pawn{--fa:"\f443"}.fa-chess-queen{--fa:"\f445"}.fa-chess-rook{--fa:"\f447"}.fa-dumbbell{--fa:"\f44b"}.fa-football,.fa-football-ball{--fa:"\f44e"}.fa-golf-ball,.fa-golf-ball-tee{--fa:"\f450"}.fa-hockey-puck{--fa:"\f453"}.fa-broom-ball,.fa-quidditch,.fa-quidditch-broom-ball{--fa:"\f458"}.fa-square-full{--fa:"\f45c"}.fa-ping-pong-paddle-ball,.fa-table-tennis,.fa-table-tennis-paddle-ball{--fa:"\f45d"}.fa-volleyball,.fa-volleyball-ball{--fa:"\f45f"}.fa-allergies,.fa-hand-dots{--fa:"\f461"}.fa-band-aid,.fa-bandage{--fa:"\f462"}.fa-box{--fa:"\f466"}.fa-boxes,.fa-boxes-alt,.fa-boxes-stacked{--fa:"\f468"}.fa-briefcase-medical{--fa:"\f469"}.fa-burn,.fa-fire-flame-simple{--fa:"\f46a"}.fa-capsules{--fa:"\f46b"}.fa-clipboard-check{--fa:"\f46c"}.fa-clipboard-list{--fa:"\f46d"}.fa-diagnoses,.fa-person-dots-from-line{--fa:"\f470"}.fa-dna{--fa:"\f471"}.fa-dolly,.fa-dolly-box{--fa:"\f472"}.fa-cart-flatbed,.fa-dolly-flatbed{--fa:"\f474"}.fa-file-medical{--fa:"\f477"}.fa-file-medical-alt,.fa-file-waveform{--fa:"\f478"}.fa-first-aid,.fa-kit-medical{--fa:"\f479"}.fa-circle-h,.fa-hospital-symbol{--fa:"\f47e"}.fa-id-card-alt,.fa-id-card-clip{--fa:"\f47f"}.fa-notes-medical{--fa:"\f481"}.fa-pallet{--fa:"\f482"}.fa-pills{--fa:"\f484"}.fa-prescription-bottle{--fa:"\f485"}.fa-prescription-bottle-alt,.fa-prescription-bottle-medical{--fa:"\f486"}.fa-bed-pulse,.fa-procedures{--fa:"\f487"}.fa-shipping-fast,.fa-truck-fast{--fa:"\f48b"}.fa-smoking{--fa:"\f48d"}.fa-syringe{--fa:"\f48e"}.fa-tablets{--fa:"\f490"}.fa-thermometer{--fa:"\f491"}.fa-vial{--fa:"\f492"}.fa-vials{--fa:"\f493"}.fa-warehouse{--fa:"\f494"}.fa-weight,.fa-weight-scale{--fa:"\f496"}.fa-x-ray{--fa:"\f497"}.fa-box-open{--fa:"\f49e"}.fa-comment-dots,.fa-commenting{--fa:"\f4ad"}.fa-comment-slash{--fa:"\f4b3"}.fa-couch{--fa:"\f4b8"}.fa-circle-dollar-to-slot,.fa-donate{--fa:"\f4b9"}.fa-dove{--fa:"\f4ba"}.fa-hand-holding{--fa:"\f4bd"}.fa-hand-holding-heart{--fa:"\f4be"}.fa-hand-holding-dollar,.fa-hand-holding-usd{--fa:"\f4c0"}.fa-hand-holding-droplet,.fa-hand-holding-water{--fa:"\f4c1"}.fa-hands-holding{--fa:"\f4c2"}.fa-hands-helping,.fa-handshake-angle{--fa:"\f4c4"}.fa-parachute-box{--fa:"\f4cd"}.fa-people-carry,.fa-people-carry-box{--fa:"\f4ce"}.fa-piggy-bank{--fa:"\f4d3"}.fa-ribbon{--fa:"\f4d6"}.fa-route{--fa:"\f4d7"}.fa-seedling,.fa-sprout{--fa:"\f4d8"}.fa-sign,.fa-sign-hanging{--fa:"\f4d9"}.fa-face-smile-wink,.fa-smile-wink{--fa:"\f4da"}.fa-tape{--fa:"\f4db"}.fa-truck-loading,.fa-truck-ramp-box{--fa:"\f4de"}.fa-truck-moving{--fa:"\f4df"}.fa-video-slash{--fa:"\f4e2"}.fa-wine-glass{--fa:"\f4e3"}.fa-user-astronaut{--fa:"\f4fb"}.fa-user-check{--fa:"\f4fc"}.fa-user-clock{--fa:"\f4fd"}.fa-user-cog,.fa-user-gear{--fa:"\f4fe"}.fa-user-edit,.fa-user-pen{--fa:"\f4ff"}.fa-user-friends,.fa-user-group{--fa:"\f500"}.fa-user-graduate{--fa:"\f501"}.fa-user-lock{--fa:"\f502"}.fa-user-minus{--fa:"\f503"}.fa-user-ninja{--fa:"\f504"}.fa-user-shield{--fa:"\f505"}.fa-user-alt-slash,.fa-user-large-slash,.fa-user-slash{--fa:"\f506"}.fa-user-tag{--fa:"\f507"}.fa-user-tie{--fa:"\f508"}.fa-users-cog,.fa-users-gear{--fa:"\f509"}.fa-balance-scale-left,.fa-scale-unbalanced{--fa:"\f515"}.fa-balance-scale-right,.fa-scale-unbalanced-flip{--fa:"\f516"}.fa-blender{--fa:"\f517"}.fa-book-open{--fa:"\f518"}.fa-broadcast-tower,.fa-tower-broadcast{--fa:"\f519"}.fa-broom{--fa:"\f51a"}.fa-blackboard,.fa-chalkboard{--fa:"\f51b"}.fa-chalkboard-teacher,.fa-chalkboard-user{--fa:"\f51c"}.fa-church{--fa:"\f51d"}.fa-coins{--fa:"\f51e"}.fa-compact-disc{--fa:"\f51f"}.fa-crow{--fa:"\f520"}.fa-crown{--fa:"\f521"}.fa-dice{--fa:"\f522"}.fa-dice-five{--fa:"\f523"}.fa-dice-four{--fa:"\f524"}.fa-dice-one{--fa:"\f525"}.fa-dice-six{--fa:"\f526"}.fa-dice-three{--fa:"\f527"}.fa-dice-two{--fa:"\f528"}.fa-divide{--fa:"\f529"}.fa-door-closed{--fa:"\f52a"}.fa-door-open{--fa:"\f52b"}.fa-feather{--fa:"\f52d"}.fa-frog{--fa:"\f52e"}.fa-gas-pump{--fa:"\f52f"}.fa-glasses{--fa:"\f530"}.fa-greater-than-equal{--fa:"\f532"}.fa-helicopter{--fa:"\f533"}.fa-infinity{--fa:"\f534"}.fa-kiwi-bird{--fa:"\f535"}.fa-less-than-equal{--fa:"\f537"}.fa-memory{--fa:"\f538"}.fa-microphone-alt-slash,.fa-microphone-lines-slash{--fa:"\f539"}.fa-money-bill-wave{--fa:"\f53a"}.fa-money-bill-1-wave,.fa-money-bill-wave-alt{--fa:"\f53b"}.fa-money-check{--fa:"\f53c"}.fa-money-check-alt,.fa-money-check-dollar{--fa:"\f53d"}.fa-not-equal{--fa:"\f53e"}.fa-palette{--fa:"\f53f"}.fa-parking,.fa-square-parking{--fa:"\f540"}.fa-diagram-project,.fa-project-diagram{--fa:"\f542"}.fa-receipt{--fa:"\f543"}.fa-robot{--fa:"\f544"}.fa-ruler{--fa:"\f545"}.fa-ruler-combined{--fa:"\f546"}.fa-ruler-horizontal{--fa:"\f547"}.fa-ruler-vertical{--fa:"\f548"}.fa-school{--fa:"\f549"}.fa-screwdriver{--fa:"\f54a"}.fa-shoe-prints{--fa:"\f54b"}.fa-skull{--fa:"\f54c"}.fa-ban-smoking,.fa-smoking-ban{--fa:"\f54d"}.fa-store{--fa:"\f54e"}.fa-shop,.fa-store-alt{--fa:"\f54f"}.fa-bars-staggered,.fa-reorder,.fa-stream{--fa:"\f550"}.fa-stroopwafel{--fa:"\f551"}.fa-toolbox{--fa:"\f552"}.fa-shirt,.fa-t-shirt,.fa-tshirt{--fa:"\f553"}.fa-person-walking,.fa-walking{--fa:"\f554"}.fa-wallet{--fa:"\f555"}.fa-angry,.fa-face-angry{--fa:"\f556"}.fa-archway{--fa:"\f557"}.fa-atlas,.fa-book-atlas{--fa:"\f558"}.fa-award{--fa:"\f559"}.fa-backspace,.fa-delete-left{--fa:"\f55a"}.fa-bezier-curve{--fa:"\f55b"}.fa-bong{--fa:"\f55c"}.fa-brush{--fa:"\f55d"}.fa-bus-alt,.fa-bus-simple{--fa:"\f55e"}.fa-cannabis{--fa:"\f55f"}.fa-check-double{--fa:"\f560"}.fa-cocktail,.fa-martini-glass-citrus{--fa:"\f561"}.fa-bell-concierge,.fa-concierge-bell{--fa:"\f562"}.fa-cookie{--fa:"\f563"}.fa-cookie-bite{--fa:"\f564"}.fa-crop-alt,.fa-crop-simple{--fa:"\f565"}.fa-digital-tachograph,.fa-tachograph-digital{--fa:"\f566"}.fa-dizzy,.fa-face-dizzy{--fa:"\f567"}.fa-compass-drafting,.fa-drafting-compass{--fa:"\f568"}.fa-drum{--fa:"\f569"}.fa-drum-steelpan{--fa:"\f56a"}.fa-feather-alt,.fa-feather-pointed{--fa:"\f56b"}.fa-file-contract{--fa:"\f56c"}.fa-file-arrow-down,.fa-file-download{--fa:"\f56d"}.fa-arrow-right-from-file,.fa-file-export{--fa:"\f56e"}.fa-arrow-right-to-file,.fa-file-import{--fa:"\f56f"}.fa-file-invoice{--fa:"\f570"}.fa-file-invoice-dollar{--fa:"\f571"}.fa-file-prescription{--fa:"\f572"}.fa-file-signature{--fa:"\f573"}.fa-file-arrow-up,.fa-file-upload{--fa:"\f574"}.fa-fill{--fa:"\f575"}.fa-fill-drip{--fa:"\f576"}.fa-fingerprint{--fa:"\f577"}.fa-fish{--fa:"\f578"}.fa-face-flushed,.fa-flushed{--fa:"\f579"}.fa-face-frown-open,.fa-frown-open{--fa:"\f57a"}.fa-glass-martini-alt,.fa-martini-glass{--fa:"\f57b"}.fa-earth-africa,.fa-globe-africa{--fa:"\f57c"}.fa-earth,.fa-earth-america,.fa-earth-americas,.fa-globe-americas{--fa:"\f57d"}.fa-earth-asia,.fa-globe-asia{--fa:"\f57e"}.fa-face-grimace,.fa-grimace{--fa:"\f57f"}.fa-face-grin,.fa-grin{--fa:"\f580"}.fa-face-grin-wide,.fa-grin-alt{--fa:"\f581"}.fa-face-grin-beam,.fa-grin-beam{--fa:"\f582"}.fa-face-grin-beam-sweat,.fa-grin-beam-sweat{--fa:"\f583"}.fa-face-grin-hearts,.fa-grin-hearts{--fa:"\f584"}.fa-face-grin-squint,.fa-grin-squint{--fa:"\f585"}.fa-face-grin-squint-tears,.fa-grin-squint-tears{--fa:"\f586"}.fa-face-grin-stars,.fa-grin-stars{--fa:"\f587"}.fa-face-grin-tears,.fa-grin-tears{--fa:"\f588"}.fa-face-grin-tongue,.fa-grin-tongue{--fa:"\f589"}.fa-face-grin-tongue-squint,.fa-grin-tongue-squint{--fa:"\f58a"}.fa-face-grin-tongue-wink,.fa-grin-tongue-wink{--fa:"\f58b"}.fa-face-grin-wink,.fa-grin-wink{--fa:"\f58c"}.fa-grid-horizontal,.fa-grip,.fa-grip-horizontal{--fa:"\f58d"}.fa-grid-vertical,.fa-grip-vertical{--fa:"\f58e"}.fa-headset{--fa:"\f590"}.fa-highlighter{--fa:"\f591"}.fa-hot-tub,.fa-hot-tub-person{--fa:"\f593"}.fa-hotel{--fa:"\f594"}.fa-joint{--fa:"\f595"}.fa-face-kiss,.fa-kiss{--fa:"\f596"}.fa-face-kiss-beam,.fa-kiss-beam{--fa:"\f597"}.fa-face-kiss-wink-heart,.fa-kiss-wink-heart{--fa:"\f598"}.fa-face-laugh,.fa-laugh{--fa:"\f599"}.fa-face-laugh-beam,.fa-laugh-beam{--fa:"\f59a"}.fa-face-laugh-squint,.fa-laugh-squint{--fa:"\f59b"}.fa-face-laugh-wink,.fa-laugh-wink{--fa:"\f59c"}.fa-cart-flatbed-suitcase,.fa-luggage-cart{--fa:"\f59d"}.fa-map-location,.fa-map-marked{--fa:"\f59f"}.fa-map-location-dot,.fa-map-marked-alt{--fa:"\f5a0"}.fa-marker{--fa:"\f5a1"}.fa-medal{--fa:"\f5a2"}.fa-face-meh-blank,.fa-meh-blank{--fa:"\f5a4"}.fa-face-rolling-eyes,.fa-meh-rolling-eyes{--fa:"\f5a5"}.fa-monument{--fa:"\f5a6"}.fa-mortar-pestle{--fa:"\f5a7"}.fa-paint-roller{--fa:"\f5aa"}.fa-passport{--fa:"\f5ab"}.fa-pen-fancy{--fa:"\f5ac"}.fa-pen-nib{--fa:"\f5ad"}.fa-pen-ruler,.fa-pencil-ruler{--fa:"\f5ae"}.fa-plane-arrival{--fa:"\f5af"}.fa-plane-departure{--fa:"\f5b0"}.fa-prescription{--fa:"\f5b1"}.fa-face-sad-cry,.fa-sad-cry{--fa:"\f5b3"}.fa-face-sad-tear,.fa-sad-tear{--fa:"\f5b4"}.fa-shuttle-van,.fa-van-shuttle{--fa:"\f5b6"}.fa-signature{--fa:"\f5b7"}.fa-face-smile-beam,.fa-smile-beam{--fa:"\f5b8"}.fa-solar-panel{--fa:"\f5ba"}.fa-spa{--fa:"\f5bb"}.fa-splotch{--fa:"\f5bc"}.fa-spray-can{--fa:"\f5bd"}.fa-stamp{--fa:"\f5bf"}.fa-star-half-alt,.fa-star-half-stroke{--fa:"\f5c0"}.fa-suitcase-rolling{--fa:"\f5c1"}.fa-face-surprise,.fa-surprise{--fa:"\f5c2"}.fa-swatchbook{--fa:"\f5c3"}.fa-person-swimming,.fa-swimmer{--fa:"\f5c4"}.fa-ladder-water,.fa-swimming-pool,.fa-water-ladder{--fa:"\f5c5"}.fa-droplet-slash,.fa-tint-slash{--fa:"\f5c7"}.fa-face-tired,.fa-tired{--fa:"\f5c8"}.fa-tooth{--fa:"\f5c9"}.fa-umbrella-beach{--fa:"\f5ca"}.fa-weight-hanging{--fa:"\f5cd"}.fa-wine-glass-alt,.fa-wine-glass-empty{--fa:"\f5ce"}.fa-air-freshener,.fa-spray-can-sparkles{--fa:"\f5d0"}.fa-apple-alt,.fa-apple-whole{--fa:"\f5d1"}.fa-atom{--fa:"\f5d2"}.fa-bone{--fa:"\f5d7"}.fa-book-open-reader,.fa-book-reader{--fa:"\f5da"}.fa-brain{--fa:"\f5dc"}.fa-car-alt,.fa-car-rear{--fa:"\f5de"}.fa-battery-car,.fa-car-battery{--fa:"\f5df"}.fa-car-burst,.fa-car-crash{--fa:"\f5e1"}.fa-car-side{--fa:"\f5e4"}.fa-charging-station{--fa:"\f5e7"}.fa-diamond-turn-right,.fa-directions{--fa:"\f5eb"}.fa-draw-polygon,.fa-vector-polygon{--fa:"\f5ee"}.fa-laptop-code{--fa:"\f5fc"}.fa-layer-group{--fa:"\f5fd"}.fa-location,.fa-location-crosshairs{--fa:"\f601"}.fa-lungs{--fa:"\f604"}.fa-microscope{--fa:"\f610"}.fa-oil-can{--fa:"\f613"}.fa-poop{--fa:"\f619"}.fa-shapes,.fa-triangle-circle-square{--fa:"\f61f"}.fa-star-of-life{--fa:"\f621"}.fa-dashboard,.fa-gauge,.fa-gauge-med,.fa-tachometer-alt-average{--fa:"\f624"}.fa-gauge-high,.fa-tachometer-alt,.fa-tachometer-alt-fast{--fa:"\f625"}.fa-gauge-simple,.fa-gauge-simple-med,.fa-tachometer-average{--fa:"\f629"}.fa-gauge-simple-high,.fa-tachometer,.fa-tachometer-fast{--fa:"\f62a"}.fa-teeth{--fa:"\f62e"}.fa-teeth-open{--fa:"\f62f"}.fa-masks-theater,.fa-theater-masks{--fa:"\f630"}.fa-traffic-light{--fa:"\f637"}.fa-truck-monster{--fa:"\f63b"}.fa-truck-pickup{--fa:"\f63c"}.fa-ad,.fa-rectangle-ad{--fa:"\f641"}.fa-ankh{--fa:"\f644"}.fa-bible,.fa-book-bible{--fa:"\f647"}.fa-briefcase-clock,.fa-business-time{--fa:"\f64a"}.fa-city{--fa:"\f64f"}.fa-comment-dollar{--fa:"\f651"}.fa-comments-dollar{--fa:"\f653"}.fa-cross{--fa:"\f654"}.fa-dharmachakra{--fa:"\f655"}.fa-envelope-open-text{--fa:"\f658"}.fa-folder-minus{--fa:"\f65d"}.fa-folder-plus{--fa:"\f65e"}.fa-filter-circle-dollar,.fa-funnel-dollar{--fa:"\f662"}.fa-gopuram{--fa:"\f664"}.fa-hamsa{--fa:"\f665"}.fa-bahai,.fa-haykal{--fa:"\f666"}.fa-jedi{--fa:"\f669"}.fa-book-journal-whills,.fa-journal-whills{--fa:"\f66a"}.fa-kaaba{--fa:"\f66b"}.fa-khanda{--fa:"\f66d"}.fa-landmark{--fa:"\f66f"}.fa-envelopes-bulk,.fa-mail-bulk{--fa:"\f674"}.fa-menorah{--fa:"\f676"}.fa-mosque{--fa:"\f678"}.fa-om{--fa:"\f679"}.fa-pastafarianism,.fa-spaghetti-monster-flying{--fa:"\f67b"}.fa-peace{--fa:"\f67c"}.fa-place-of-worship{--fa:"\f67f"}.fa-poll,.fa-square-poll-vertical{--fa:"\f681"}.fa-poll-h,.fa-square-poll-horizontal{--fa:"\f682"}.fa-person-praying,.fa-pray{--fa:"\f683"}.fa-hands-praying,.fa-praying-hands{--fa:"\f684"}.fa-book-quran,.fa-quran{--fa:"\f687"}.fa-magnifying-glass-dollar,.fa-search-dollar{--fa:"\f688"}.fa-magnifying-glass-location,.fa-search-location{--fa:"\f689"}.fa-socks{--fa:"\f696"}.fa-square-root-alt,.fa-square-root-variable{--fa:"\f698"}.fa-star-and-crescent{--fa:"\f699"}.fa-star-of-david{--fa:"\f69a"}.fa-synagogue{--fa:"\f69b"}.fa-scroll-torah,.fa-torah{--fa:"\f6a0"}.fa-torii-gate{--fa:"\f6a1"}.fa-vihara{--fa:"\f6a7"}.fa-volume,.fa-volume-medium{--fa:"\f6a8"}.fa-volume-mute,.fa-volume-times,.fa-volume-xmark{--fa:"\f6a9"}.fa-yin-yang{--fa:"\f6ad"}.fa-blender-phone{--fa:"\f6b6"}.fa-book-dead,.fa-book-skull{--fa:"\f6b7"}.fa-campground{--fa:"\f6bb"}.fa-cat{--fa:"\f6be"}.fa-chair{--fa:"\f6c0"}.fa-cloud-moon{--fa:"\f6c3"}.fa-cloud-sun{--fa:"\f6c4"}.fa-cow{--fa:"\f6c8"}.fa-dice-d20{--fa:"\f6cf"}.fa-dice-d6{--fa:"\f6d1"}.fa-dog{--fa:"\f6d3"}.fa-dragon{--fa:"\f6d5"}.fa-drumstick-bite{--fa:"\f6d7"}.fa-dungeon{--fa:"\f6d9"}.fa-file-csv{--fa:"\f6dd"}.fa-fist-raised,.fa-hand-fist{--fa:"\f6de"}.fa-ghost{--fa:"\f6e2"}.fa-hammer{--fa:"\f6e3"}.fa-hanukiah{--fa:"\f6e6"}.fa-hat-wizard{--fa:"\f6e8"}.fa-hiking,.fa-person-hiking{--fa:"\f6ec"}.fa-hippo{--fa:"\f6ed"}.fa-horse{--fa:"\f6f0"}.fa-house-chimney-crack,.fa-house-damage{--fa:"\f6f1"}.fa-hryvnia,.fa-hryvnia-sign{--fa:"\f6f2"}.fa-mask{--fa:"\f6fa"}.fa-mountain{--fa:"\f6fc"}.fa-network-wired{--fa:"\f6ff"}.fa-otter{--fa:"\f700"}.fa-ring{--fa:"\f70b"}.fa-person-running,.fa-running{--fa:"\f70c"}.fa-scroll{--fa:"\f70e"}.fa-skull-crossbones{--fa:"\f714"}.fa-slash{--fa:"\f715"}.fa-spider{--fa:"\f717"}.fa-toilet-paper,.fa-toilet-paper-alt,.fa-toilet-paper-blank{--fa:"\f71e"}.fa-tractor{--fa:"\f722"}.fa-user-injured{--fa:"\f728"}.fa-vr-cardboard{--fa:"\f729"}.fa-wand-sparkles{--fa:"\f72b"}.fa-wind{--fa:"\f72e"}.fa-wine-bottle{--fa:"\f72f"}.fa-cloud-meatball{--fa:"\f73b"}.fa-cloud-moon-rain{--fa:"\f73c"}.fa-cloud-rain{--fa:"\f73d"}.fa-cloud-showers-heavy{--fa:"\f740"}.fa-cloud-sun-rain{--fa:"\f743"}.fa-democrat{--fa:"\f747"}.fa-flag-usa{--fa:"\f74d"}.fa-hurricane{--fa:"\f751"}.fa-landmark-alt,.fa-landmark-dome{--fa:"\f752"}.fa-meteor{--fa:"\f753"}.fa-person-booth{--fa:"\f756"}.fa-poo-bolt,.fa-poo-storm{--fa:"\f75a"}.fa-rainbow{--fa:"\f75b"}.fa-republican{--fa:"\f75e"}.fa-smog{--fa:"\f75f"}.fa-temperature-high{--fa:"\f769"}.fa-temperature-low{--fa:"\f76b"}.fa-cloud-bolt,.fa-thunderstorm{--fa:"\f76c"}.fa-tornado{--fa:"\f76f"}.fa-volcano{--fa:"\f770"}.fa-check-to-slot,.fa-vote-yea{--fa:"\f772"}.fa-water{--fa:"\f773"}.fa-baby{--fa:"\f77c"}.fa-baby-carriage,.fa-carriage-baby{--fa:"\f77d"}.fa-biohazard{--fa:"\f780"}.fa-blog{--fa:"\f781"}.fa-calendar-day{--fa:"\f783"}.fa-calendar-week{--fa:"\f784"}.fa-candy-cane{--fa:"\f786"}.fa-carrot{--fa:"\f787"}.fa-cash-register{--fa:"\f788"}.fa-compress-arrows-alt,.fa-minimize{--fa:"\f78c"}.fa-dumpster{--fa:"\f793"}.fa-dumpster-fire{--fa:"\f794"}.fa-ethernet{--fa:"\f796"}.fa-gifts{--fa:"\f79c"}.fa-champagne-glasses,.fa-glass-cheers{--fa:"\f79f"}.fa-glass-whiskey,.fa-whiskey-glass{--fa:"\f7a0"}.fa-earth-europe,.fa-globe-europe{--fa:"\f7a2"}.fa-grip-lines{--fa:"\f7a4"}.fa-grip-lines-vertical{--fa:"\f7a5"}.fa-guitar{--fa:"\f7a6"}.fa-heart-broken,.fa-heart-crack{--fa:"\f7a9"}.fa-holly-berry{--fa:"\f7aa"}.fa-horse-head{--fa:"\f7ab"}.fa-icicles{--fa:"\f7ad"}.fa-igloo{--fa:"\f7ae"}.fa-mitten{--fa:"\f7b5"}.fa-mug-hot{--fa:"\f7b6"}.fa-radiation{--fa:"\f7b9"}.fa-circle-radiation,.fa-radiation-alt{--fa:"\f7ba"}.fa-restroom{--fa:"\f7bd"}.fa-satellite{--fa:"\f7bf"}.fa-satellite-dish{--fa:"\f7c0"}.fa-sd-card{--fa:"\f7c2"}.fa-sim-card{--fa:"\f7c4"}.fa-person-skating,.fa-skating{--fa:"\f7c5"}.fa-person-skiing,.fa-skiing{--fa:"\f7c9"}.fa-person-skiing-nordic,.fa-skiing-nordic{--fa:"\f7ca"}.fa-sleigh{--fa:"\f7cc"}.fa-comment-sms,.fa-sms{--fa:"\f7cd"}.fa-person-snowboarding,.fa-snowboarding{--fa:"\f7ce"}.fa-snowman{--fa:"\f7d0"}.fa-snowplow{--fa:"\f7d2"}.fa-tenge,.fa-tenge-sign{--fa:"\f7d7"}.fa-toilet{--fa:"\f7d8"}.fa-screwdriver-wrench,.fa-tools{--fa:"\f7d9"}.fa-cable-car,.fa-tram{--fa:"\f7da"}.fa-fire-alt,.fa-fire-flame-curved{--fa:"\f7e4"}.fa-bacon{--fa:"\f7e5"}.fa-book-medical{--fa:"\f7e6"}.fa-bread-slice{--fa:"\f7ec"}.fa-cheese{--fa:"\f7ef"}.fa-clinic-medical,.fa-house-chimney-medical{--fa:"\f7f2"}.fa-clipboard-user{--fa:"\f7f3"}.fa-comment-medical{--fa:"\f7f5"}.fa-crutch{--fa:"\f7f7"}.fa-disease{--fa:"\f7fa"}.fa-egg{--fa:"\f7fb"}.fa-folder-tree{--fa:"\f802"}.fa-burger,.fa-hamburger{--fa:"\f805"}.fa-hand-middle-finger{--fa:"\f806"}.fa-hard-hat,.fa-hat-hard,.fa-helmet-safety{--fa:"\f807"}.fa-hospital-user{--fa:"\f80d"}.fa-hotdog{--fa:"\f80f"}.fa-ice-cream{--fa:"\f810"}.fa-laptop-medical{--fa:"\f812"}.fa-pager{--fa:"\f815"}.fa-pepper-hot{--fa:"\f816"}.fa-pizza-slice{--fa:"\f818"}.fa-sack-dollar{--fa:"\f81d"}.fa-book-tanakh,.fa-tanakh{--fa:"\f827"}.fa-bars-progress,.fa-tasks-alt{--fa:"\f828"}.fa-trash-arrow-up,.fa-trash-restore{--fa:"\f829"}.fa-trash-can-arrow-up,.fa-trash-restore-alt{--fa:"\f82a"}.fa-user-nurse{--fa:"\f82f"}.fa-wave-square{--fa:"\f83e"}.fa-biking,.fa-person-biking{--fa:"\f84a"}.fa-border-all{--fa:"\f84c"}.fa-border-none{--fa:"\f850"}.fa-border-style,.fa-border-top-left{--fa:"\f853"}.fa-digging,.fa-person-digging{--fa:"\f85e"}.fa-fan{--fa:"\f863"}.fa-heart-music-camera-bolt,.fa-icons{--fa:"\f86d"}.fa-phone-alt,.fa-phone-flip{--fa:"\f879"}.fa-phone-square-alt,.fa-square-phone-flip{--fa:"\f87b"}.fa-photo-film,.fa-photo-video{--fa:"\f87c"}.fa-remove-format,.fa-text-slash{--fa:"\f87d"}.fa-arrow-down-z-a,.fa-sort-alpha-desc,.fa-sort-alpha-down-alt{--fa:"\f881"}.fa-arrow-up-z-a,.fa-sort-alpha-up-alt{--fa:"\f882"}.fa-arrow-down-short-wide,.fa-sort-amount-desc,.fa-sort-amount-down-alt{--fa:"\f884"}.fa-arrow-up-short-wide,.fa-sort-amount-up-alt{--fa:"\f885"}.fa-arrow-down-9-1,.fa-sort-numeric-desc,.fa-sort-numeric-down-alt{--fa:"\f886"}.fa-arrow-up-9-1,.fa-sort-numeric-up-alt{--fa:"\f887"}.fa-spell-check{--fa:"\f891"}.fa-voicemail{--fa:"\f897"}.fa-hat-cowboy{--fa:"\f8c0"}.fa-hat-cowboy-side{--fa:"\f8c1"}.fa-computer-mouse,.fa-mouse{--fa:"\f8cc"}.fa-radio{--fa:"\f8d7"}.fa-record-vinyl{--fa:"\f8d9"}.fa-walkie-talkie{--fa:"\f8ef"}.fa-caravan{--fa:"\f8ff"} +:host,:root{--fa-family-brands:"Font Awesome 7 Brands";--fa-font-brands:normal 400 1em/1 var(--fa-family-brands)}@font-face{font-family:"Font Awesome 7 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.woff2)}.fa-brands,.fa-classic.fa-brands,.fab{--fa-family:var(--fa-family-brands);--fa-style:400}.fa-firefox-browser{--fa:"\e007"}.fa-ideal{--fa:"\e013"}.fa-microblog{--fa:"\e01a"}.fa-pied-piper-square,.fa-square-pied-piper{--fa:"\e01e"}.fa-unity{--fa:"\e049"}.fa-dailymotion{--fa:"\e052"}.fa-instagram-square,.fa-square-instagram{--fa:"\e055"}.fa-mixer{--fa:"\e056"}.fa-shopify{--fa:"\e057"}.fa-deezer{--fa:"\e077"}.fa-edge-legacy{--fa:"\e078"}.fa-google-pay{--fa:"\e079"}.fa-rust{--fa:"\e07a"}.fa-tiktok{--fa:"\e07b"}.fa-unsplash{--fa:"\e07c"}.fa-cloudflare{--fa:"\e07d"}.fa-guilded{--fa:"\e07e"}.fa-hive{--fa:"\e07f"}.fa-42-group,.fa-innosoft{--fa:"\e080"}.fa-instalod{--fa:"\e081"}.fa-octopus-deploy{--fa:"\e082"}.fa-perbyte{--fa:"\e083"}.fa-uncharted{--fa:"\e084"}.fa-watchman-monitoring{--fa:"\e087"}.fa-wodu{--fa:"\e088"}.fa-wirsindhandwerk,.fa-wsh{--fa:"\e2d0"}.fa-bots{--fa:"\e340"}.fa-cmplid{--fa:"\e360"}.fa-bilibili{--fa:"\e3d9"}.fa-golang{--fa:"\e40f"}.fa-pix{--fa:"\e43a"}.fa-sitrox{--fa:"\e44a"}.fa-hashnode{--fa:"\e499"}.fa-meta{--fa:"\e49b"}.fa-padlet{--fa:"\e4a0"}.fa-nfc-directional{--fa:"\e530"}.fa-nfc-symbol{--fa:"\e531"}.fa-screenpal{--fa:"\e570"}.fa-space-awesome{--fa:"\e5ac"}.fa-square-font-awesome{--fa:"\e5ad"}.fa-gitlab-square,.fa-square-gitlab{--fa:"\e5ae"}.fa-odysee{--fa:"\e5c6"}.fa-stubber{--fa:"\e5c7"}.fa-debian{--fa:"\e60b"}.fa-shoelace{--fa:"\e60c"}.fa-threads{--fa:"\e618"}.fa-square-threads{--fa:"\e619"}.fa-square-x-twitter{--fa:"\e61a"}.fa-x-twitter{--fa:"\e61b"}.fa-opensuse{--fa:"\e62b"}.fa-letterboxd{--fa:"\e62d"}.fa-square-letterboxd{--fa:"\e62e"}.fa-mintbit{--fa:"\e62f"}.fa-google-scholar{--fa:"\e63b"}.fa-brave{--fa:"\e63c"}.fa-brave-reverse{--fa:"\e63d"}.fa-pixiv{--fa:"\e640"}.fa-upwork{--fa:"\e641"}.fa-webflow{--fa:"\e65c"}.fa-signal-messenger{--fa:"\e663"}.fa-bluesky{--fa:"\e671"}.fa-jxl{--fa:"\e67b"}.fa-square-upwork{--fa:"\e67c"}.fa-web-awesome{--fa:"\e682"}.fa-square-web-awesome{--fa:"\e683"}.fa-square-web-awesome-stroke{--fa:"\e684"}.fa-dart-lang{--fa:"\e693"}.fa-flutter{--fa:"\e694"}.fa-files-pinwheel{--fa:"\e69f"}.fa-css{--fa:"\e6a2"}.fa-square-bluesky{--fa:"\e6a3"}.fa-openai{--fa:"\e7cf"}.fa-square-linkedin{--fa:"\e7d0"}.fa-cash-app{--fa:"\e7d4"}.fa-disqus{--fa:"\e7d5"}.fa-11ty,.fa-eleventy{--fa:"\e7d6"}.fa-kakao-talk{--fa:"\e7d7"}.fa-linktree{--fa:"\e7d8"}.fa-notion{--fa:"\e7d9"}.fa-pandora{--fa:"\e7da"}.fa-pixelfed{--fa:"\e7db"}.fa-tidal{--fa:"\e7dc"}.fa-vsco{--fa:"\e7dd"}.fa-w3c{--fa:"\e7de"}.fa-lumon{--fa:"\e7e2"}.fa-lumon-drop{--fa:"\e7e3"}.fa-square-figma{--fa:"\e7e4"}.fa-tex{--fa:"\e7ff"}.fa-duolingo{--fa:"\e812"}.fa-supportnow{--fa:"\e833"}.fa-tor-browser{--fa:"\e838"}.fa-typescript{--fa:"\e840"}.fa-square-deskpro{--fa:"\e844"}.fa-circle-zulip{--fa:"\e851"}.fa-julia{--fa:"\e852"}.fa-zulip{--fa:"\e853"}.fa-unison{--fa:"\e854"}.fa-bgg,.fa-board-game-geek{--fa:"\e855"}.fa-ko-fi{--fa:"\e856"}.fa-kubernetes{--fa:"\e857"}.fa-postgresql{--fa:"\e858"}.fa-scaleway{--fa:"\e859"}.fa-venmo{--fa:"\e85a"}.fa-venmo-v{--fa:"\e85b"}.fa-unreal-engine{--fa:"\e85c"}.fa-globaleaks{--fa:"\e85d"}.fa-solana{--fa:"\e85e"}.fa-threema{--fa:"\e85f"}.fa-forgejo{--fa:"\e860"}.fa-claude{--fa:"\e861"}.fa-gitee{--fa:"\e863"}.fa-xmpp{--fa:"\e864"}.fa-fediverse{--fa:"\e865"}.fa-tailwind-css{--fa:"\e866"}.fa-arch-linux{--fa:"\e867"}.fa-svelte{--fa:"\e868"}.fa-hugging-face{--fa:"\e869"}.fa-leetcode{--fa:"\e86a"}.fa-openstreetmap{--fa:"\e86b"}.fa-ultralytics{--fa:"\e86d"}.fa-ultralytics-hub{--fa:"\e86e"}.fa-ultralytics-yolo{--fa:"\e86f"}.fa-obsidian{--fa:"\e879"}.fa-zoom{--fa:"\e87b"}.fa-vim{--fa:"\e88a"}.fa-symfonycasts{--fa:"\e8ab"}.fa-square-twitter,.fa-twitter-square{--fa:"\f081"}.fa-facebook-square,.fa-square-facebook{--fa:"\f082"}.fa-linkedin{--fa:"\f08c"}.fa-github-square,.fa-square-github{--fa:"\f092"}.fa-twitter{--fa:"\f099"}.fa-facebook{--fa:"\f09a"}.fa-github{--fa:"\f09b"}.fa-pinterest{--fa:"\f0d2"}.fa-pinterest-square,.fa-square-pinterest{--fa:"\f0d3"}.fa-google-plus-square,.fa-square-google-plus{--fa:"\f0d4"}.fa-google-plus-g{--fa:"\f0d5"}.fa-linkedin-in{--fa:"\f0e1"}.fa-github-alt{--fa:"\f113"}.fa-maxcdn{--fa:"\f136"}.fa-html5{--fa:"\f13b"}.fa-css3{--fa:"\f13c"}.fa-btc{--fa:"\f15a"}.fa-youtube{--fa:"\f167"}.fa-xing{--fa:"\f168"}.fa-square-xing,.fa-xing-square{--fa:"\f169"}.fa-dropbox{--fa:"\f16b"}.fa-stack-overflow{--fa:"\f16c"}.fa-instagram{--fa:"\f16d"}.fa-flickr{--fa:"\f16e"}.fa-adn{--fa:"\f170"}.fa-bitbucket{--fa:"\f171"}.fa-tumblr{--fa:"\f173"}.fa-square-tumblr,.fa-tumblr-square{--fa:"\f174"}.fa-apple{--fa:"\f179"}.fa-windows{--fa:"\f17a"}.fa-android{--fa:"\f17b"}.fa-linux{--fa:"\f17c"}.fa-dribbble{--fa:"\f17d"}.fa-skype{--fa:"\f17e"}.fa-foursquare{--fa:"\f180"}.fa-trello{--fa:"\f181"}.fa-gratipay{--fa:"\f184"}.fa-vk{--fa:"\f189"}.fa-weibo{--fa:"\f18a"}.fa-renren{--fa:"\f18b"}.fa-pagelines{--fa:"\f18c"}.fa-stack-exchange{--fa:"\f18d"}.fa-square-vimeo,.fa-vimeo-square{--fa:"\f194"}.fa-slack,.fa-slack-hash{--fa:"\f198"}.fa-wordpress{--fa:"\f19a"}.fa-openid{--fa:"\f19b"}.fa-yahoo{--fa:"\f19e"}.fa-google{--fa:"\f1a0"}.fa-reddit{--fa:"\f1a1"}.fa-reddit-square,.fa-square-reddit{--fa:"\f1a2"}.fa-stumbleupon-circle{--fa:"\f1a3"}.fa-stumbleupon{--fa:"\f1a4"}.fa-delicious{--fa:"\f1a5"}.fa-digg{--fa:"\f1a6"}.fa-pied-piper-pp{--fa:"\f1a7"}.fa-pied-piper-alt{--fa:"\f1a8"}.fa-drupal{--fa:"\f1a9"}.fa-joomla{--fa:"\f1aa"}.fa-behance{--fa:"\f1b4"}.fa-behance-square,.fa-square-behance{--fa:"\f1b5"}.fa-steam{--fa:"\f1b6"}.fa-square-steam,.fa-steam-square{--fa:"\f1b7"}.fa-spotify{--fa:"\f1bc"}.fa-deviantart{--fa:"\f1bd"}.fa-soundcloud{--fa:"\f1be"}.fa-vine{--fa:"\f1ca"}.fa-codepen{--fa:"\f1cb"}.fa-jsfiddle{--fa:"\f1cc"}.fa-rebel{--fa:"\f1d0"}.fa-empire{--fa:"\f1d1"}.fa-git-square,.fa-square-git{--fa:"\f1d2"}.fa-git{--fa:"\f1d3"}.fa-hacker-news{--fa:"\f1d4"}.fa-tencent-weibo{--fa:"\f1d5"}.fa-qq{--fa:"\f1d6"}.fa-weixin{--fa:"\f1d7"}.fa-slideshare{--fa:"\f1e7"}.fa-twitch{--fa:"\f1e8"}.fa-yelp{--fa:"\f1e9"}.fa-paypal{--fa:"\f1ed"}.fa-google-wallet{--fa:"\f1ee"}.fa-cc-visa{--fa:"\f1f0"}.fa-cc-mastercard{--fa:"\f1f1"}.fa-cc-discover{--fa:"\f1f2"}.fa-cc-amex{--fa:"\f1f3"}.fa-cc-paypal{--fa:"\f1f4"}.fa-cc-stripe{--fa:"\f1f5"}.fa-lastfm{--fa:"\f202"}.fa-lastfm-square,.fa-square-lastfm{--fa:"\f203"}.fa-ioxhost{--fa:"\f208"}.fa-angellist{--fa:"\f209"}.fa-buysellads{--fa:"\f20d"}.fa-connectdevelop{--fa:"\f20e"}.fa-dashcube{--fa:"\f210"}.fa-forumbee{--fa:"\f211"}.fa-leanpub{--fa:"\f212"}.fa-sellsy{--fa:"\f213"}.fa-shirtsinbulk{--fa:"\f214"}.fa-simplybuilt{--fa:"\f215"}.fa-skyatlas{--fa:"\f216"}.fa-pinterest-p{--fa:"\f231"}.fa-whatsapp{--fa:"\f232"}.fa-viacoin{--fa:"\f237"}.fa-medium,.fa-medium-m{--fa:"\f23a"}.fa-y-combinator{--fa:"\f23b"}.fa-optin-monster{--fa:"\f23c"}.fa-opencart{--fa:"\f23d"}.fa-expeditedssl{--fa:"\f23e"}.fa-cc-jcb{--fa:"\f24b"}.fa-cc-diners-club{--fa:"\f24c"}.fa-creative-commons{--fa:"\f25e"}.fa-gg{--fa:"\f260"}.fa-gg-circle{--fa:"\f261"}.fa-odnoklassniki{--fa:"\f263"}.fa-odnoklassniki-square,.fa-square-odnoklassniki{--fa:"\f264"}.fa-get-pocket{--fa:"\f265"}.fa-wikipedia-w{--fa:"\f266"}.fa-safari{--fa:"\f267"}.fa-chrome{--fa:"\f268"}.fa-firefox{--fa:"\f269"}.fa-opera{--fa:"\f26a"}.fa-internet-explorer{--fa:"\f26b"}.fa-contao{--fa:"\f26d"}.fa-500px{--fa:"\f26e"}.fa-amazon{--fa:"\f270"}.fa-houzz{--fa:"\f27c"}.fa-vimeo-v{--fa:"\f27d"}.fa-black-tie{--fa:"\f27e"}.fa-fonticons{--fa:"\f280"}.fa-reddit-alien{--fa:"\f281"}.fa-edge{--fa:"\f282"}.fa-codiepie{--fa:"\f284"}.fa-modx{--fa:"\f285"}.fa-fort-awesome{--fa:"\f286"}.fa-usb{--fa:"\f287"}.fa-product-hunt{--fa:"\f288"}.fa-mixcloud{--fa:"\f289"}.fa-scribd{--fa:"\f28a"}.fa-bluetooth{--fa:"\f293"}.fa-bluetooth-b{--fa:"\f294"}.fa-gitlab{--fa:"\f296"}.fa-wpbeginner{--fa:"\f297"}.fa-wpforms{--fa:"\f298"}.fa-envira{--fa:"\f299"}.fa-glide{--fa:"\f2a5"}.fa-glide-g{--fa:"\f2a6"}.fa-viadeo{--fa:"\f2a9"}.fa-square-viadeo,.fa-viadeo-square{--fa:"\f2aa"}.fa-snapchat,.fa-snapchat-ghost{--fa:"\f2ab"}.fa-snapchat-square,.fa-square-snapchat{--fa:"\f2ad"}.fa-pied-piper{--fa:"\f2ae"}.fa-first-order{--fa:"\f2b0"}.fa-yoast{--fa:"\f2b1"}.fa-themeisle{--fa:"\f2b2"}.fa-google-plus{--fa:"\f2b3"}.fa-font-awesome,.fa-font-awesome-flag,.fa-font-awesome-logo-full{--fa:"\f2b4"}.fa-linode{--fa:"\f2b8"}.fa-quora{--fa:"\f2c4"}.fa-free-code-camp{--fa:"\f2c5"}.fa-telegram,.fa-telegram-plane{--fa:"\f2c6"}.fa-bandcamp{--fa:"\f2d5"}.fa-grav{--fa:"\f2d6"}.fa-etsy{--fa:"\f2d7"}.fa-imdb{--fa:"\f2d8"}.fa-ravelry{--fa:"\f2d9"}.fa-sellcast{--fa:"\f2da"}.fa-superpowers{--fa:"\f2dd"}.fa-wpexplorer{--fa:"\f2de"}.fa-meetup{--fa:"\f2e0"}.fa-font-awesome-alt,.fa-square-font-awesome-stroke{--fa:"\f35c"}.fa-accessible-icon{--fa:"\f368"}.fa-accusoft{--fa:"\f369"}.fa-adversal{--fa:"\f36a"}.fa-affiliatetheme{--fa:"\f36b"}.fa-algolia{--fa:"\f36c"}.fa-amilia{--fa:"\f36d"}.fa-angrycreative{--fa:"\f36e"}.fa-app-store{--fa:"\f36f"}.fa-app-store-ios{--fa:"\f370"}.fa-apper{--fa:"\f371"}.fa-asymmetrik{--fa:"\f372"}.fa-audible{--fa:"\f373"}.fa-avianex{--fa:"\f374"}.fa-aws{--fa:"\f375"}.fa-bimobject{--fa:"\f378"}.fa-bitcoin{--fa:"\f379"}.fa-bity{--fa:"\f37a"}.fa-blackberry{--fa:"\f37b"}.fa-blogger{--fa:"\f37c"}.fa-blogger-b{--fa:"\f37d"}.fa-buromobelexperte{--fa:"\f37f"}.fa-centercode{--fa:"\f380"}.fa-cloudscale{--fa:"\f383"}.fa-cloudsmith{--fa:"\f384"}.fa-cloudversify{--fa:"\f385"}.fa-cpanel{--fa:"\f388"}.fa-css3-alt{--fa:"\f38b"}.fa-cuttlefish{--fa:"\f38c"}.fa-d-and-d{--fa:"\f38d"}.fa-deploydog{--fa:"\f38e"}.fa-deskpro{--fa:"\f38f"}.fa-digital-ocean{--fa:"\f391"}.fa-discord{--fa:"\f392"}.fa-discourse{--fa:"\f393"}.fa-dochub{--fa:"\f394"}.fa-docker{--fa:"\f395"}.fa-draft2digital{--fa:"\f396"}.fa-dribbble-square,.fa-square-dribbble{--fa:"\f397"}.fa-dyalog{--fa:"\f399"}.fa-earlybirds{--fa:"\f39a"}.fa-erlang{--fa:"\f39d"}.fa-facebook-f{--fa:"\f39e"}.fa-facebook-messenger{--fa:"\f39f"}.fa-firstdraft{--fa:"\f3a1"}.fa-fonticons-fi{--fa:"\f3a2"}.fa-fort-awesome-alt{--fa:"\f3a3"}.fa-freebsd{--fa:"\f3a4"}.fa-gitkraken{--fa:"\f3a6"}.fa-gofore{--fa:"\f3a7"}.fa-goodreads{--fa:"\f3a8"}.fa-goodreads-g{--fa:"\f3a9"}.fa-google-drive{--fa:"\f3aa"}.fa-google-play{--fa:"\f3ab"}.fa-gripfire{--fa:"\f3ac"}.fa-grunt{--fa:"\f3ad"}.fa-gulp{--fa:"\f3ae"}.fa-hacker-news-square,.fa-square-hacker-news{--fa:"\f3af"}.fa-hire-a-helper{--fa:"\f3b0"}.fa-hotjar{--fa:"\f3b1"}.fa-hubspot{--fa:"\f3b2"}.fa-itunes{--fa:"\f3b4"}.fa-itunes-note{--fa:"\f3b5"}.fa-jenkins{--fa:"\f3b6"}.fa-joget{--fa:"\f3b7"}.fa-js{--fa:"\f3b8"}.fa-js-square,.fa-square-js{--fa:"\f3b9"}.fa-keycdn{--fa:"\f3ba"}.fa-kickstarter,.fa-square-kickstarter{--fa:"\f3bb"}.fa-kickstarter-k{--fa:"\f3bc"}.fa-laravel{--fa:"\f3bd"}.fa-line{--fa:"\f3c0"}.fa-lyft{--fa:"\f3c3"}.fa-magento{--fa:"\f3c4"}.fa-medapps{--fa:"\f3c6"}.fa-medrt{--fa:"\f3c8"}.fa-microsoft{--fa:"\f3ca"}.fa-mix{--fa:"\f3cb"}.fa-mizuni{--fa:"\f3cc"}.fa-monero{--fa:"\f3d0"}.fa-napster{--fa:"\f3d2"}.fa-node-js{--fa:"\f3d3"}.fa-npm{--fa:"\f3d4"}.fa-ns8{--fa:"\f3d5"}.fa-nutritionix{--fa:"\f3d6"}.fa-page4{--fa:"\f3d7"}.fa-palfed{--fa:"\f3d8"}.fa-patreon{--fa:"\f3d9"}.fa-periscope{--fa:"\f3da"}.fa-phabricator{--fa:"\f3db"}.fa-phoenix-framework{--fa:"\f3dc"}.fa-playstation{--fa:"\f3df"}.fa-pushed{--fa:"\f3e1"}.fa-python{--fa:"\f3e2"}.fa-red-river{--fa:"\f3e3"}.fa-rendact,.fa-wpressr{--fa:"\f3e4"}.fa-replyd{--fa:"\f3e6"}.fa-resolving{--fa:"\f3e7"}.fa-rocketchat{--fa:"\f3e8"}.fa-rockrms{--fa:"\f3e9"}.fa-schlix{--fa:"\f3ea"}.fa-searchengin{--fa:"\f3eb"}.fa-servicestack{--fa:"\f3ec"}.fa-sistrix{--fa:"\f3ee"}.fa-speakap{--fa:"\f3f3"}.fa-staylinked{--fa:"\f3f5"}.fa-steam-symbol{--fa:"\f3f6"}.fa-sticker-mule{--fa:"\f3f7"}.fa-studiovinari{--fa:"\f3f8"}.fa-supple{--fa:"\f3f9"}.fa-uber{--fa:"\f402"}.fa-uikit{--fa:"\f403"}.fa-uniregistry{--fa:"\f404"}.fa-untappd{--fa:"\f405"}.fa-ussunnah{--fa:"\f407"}.fa-vaadin{--fa:"\f408"}.fa-viber{--fa:"\f409"}.fa-vimeo{--fa:"\f40a"}.fa-vnv{--fa:"\f40b"}.fa-square-whatsapp,.fa-whatsapp-square{--fa:"\f40c"}.fa-whmcs{--fa:"\f40d"}.fa-wordpress-simple{--fa:"\f411"}.fa-xbox{--fa:"\f412"}.fa-yandex{--fa:"\f413"}.fa-yandex-international{--fa:"\f414"}.fa-apple-pay{--fa:"\f415"}.fa-cc-apple-pay{--fa:"\f416"}.fa-fly{--fa:"\f417"}.fa-node{--fa:"\f419"}.fa-osi{--fa:"\f41a"}.fa-react{--fa:"\f41b"}.fa-autoprefixer{--fa:"\f41c"}.fa-less{--fa:"\f41d"}.fa-sass{--fa:"\f41e"}.fa-vuejs{--fa:"\f41f"}.fa-angular{--fa:"\f420"}.fa-aviato{--fa:"\f421"}.fa-ember{--fa:"\f423"}.fa-gitter{--fa:"\f426"}.fa-hooli{--fa:"\f427"}.fa-strava{--fa:"\f428"}.fa-stripe{--fa:"\f429"}.fa-stripe-s{--fa:"\f42a"}.fa-typo3{--fa:"\f42b"}.fa-amazon-pay{--fa:"\f42c"}.fa-cc-amazon-pay{--fa:"\f42d"}.fa-ethereum{--fa:"\f42e"}.fa-korvue{--fa:"\f42f"}.fa-elementor{--fa:"\f430"}.fa-square-youtube,.fa-youtube-square{--fa:"\f431"}.fa-flipboard{--fa:"\f44d"}.fa-hips{--fa:"\f452"}.fa-php{--fa:"\f457"}.fa-quinscape{--fa:"\f459"}.fa-readme{--fa:"\f4d5"}.fa-java{--fa:"\f4e4"}.fa-pied-piper-hat{--fa:"\f4e5"}.fa-creative-commons-by{--fa:"\f4e7"}.fa-creative-commons-nc{--fa:"\f4e8"}.fa-creative-commons-nc-eu{--fa:"\f4e9"}.fa-creative-commons-nc-jp{--fa:"\f4ea"}.fa-creative-commons-nd{--fa:"\f4eb"}.fa-creative-commons-pd{--fa:"\f4ec"}.fa-creative-commons-pd-alt{--fa:"\f4ed"}.fa-creative-commons-remix{--fa:"\f4ee"}.fa-creative-commons-sa{--fa:"\f4ef"}.fa-creative-commons-sampling{--fa:"\f4f0"}.fa-creative-commons-sampling-plus{--fa:"\f4f1"}.fa-creative-commons-share{--fa:"\f4f2"}.fa-creative-commons-zero{--fa:"\f4f3"}.fa-ebay{--fa:"\f4f4"}.fa-keybase{--fa:"\f4f5"}.fa-mastodon{--fa:"\f4f6"}.fa-r-project{--fa:"\f4f7"}.fa-researchgate{--fa:"\f4f8"}.fa-teamspeak{--fa:"\f4f9"}.fa-first-order-alt{--fa:"\f50a"}.fa-fulcrum{--fa:"\f50b"}.fa-galactic-republic{--fa:"\f50c"}.fa-galactic-senate{--fa:"\f50d"}.fa-jedi-order{--fa:"\f50e"}.fa-mandalorian{--fa:"\f50f"}.fa-old-republic{--fa:"\f510"}.fa-phoenix-squadron{--fa:"\f511"}.fa-sith{--fa:"\f512"}.fa-trade-federation{--fa:"\f513"}.fa-wolf-pack-battalion{--fa:"\f514"}.fa-hornbill{--fa:"\f592"}.fa-mailchimp{--fa:"\f59e"}.fa-megaport{--fa:"\f5a3"}.fa-nimblr{--fa:"\f5a8"}.fa-rev{--fa:"\f5b2"}.fa-shopware{--fa:"\f5b5"}.fa-squarespace{--fa:"\f5be"}.fa-themeco{--fa:"\f5c6"}.fa-weebly{--fa:"\f5cc"}.fa-wix{--fa:"\f5cf"}.fa-ello{--fa:"\f5f1"}.fa-hackerrank{--fa:"\f5f7"}.fa-kaggle{--fa:"\f5fa"}.fa-markdown{--fa:"\f60f"}.fa-neos{--fa:"\f612"}.fa-zhihu{--fa:"\f63f"}.fa-alipay{--fa:"\f642"}.fa-the-red-yeti{--fa:"\f69d"}.fa-critical-role{--fa:"\f6c9"}.fa-d-and-d-beyond{--fa:"\f6ca"}.fa-dev{--fa:"\f6cc"}.fa-fantasy-flight-games{--fa:"\f6dc"}.fa-wizards-of-the-coast{--fa:"\f730"}.fa-think-peaks{--fa:"\f731"}.fa-reacteurope{--fa:"\f75d"}.fa-artstation{--fa:"\f77a"}.fa-atlassian{--fa:"\f77b"}.fa-canadian-maple-leaf{--fa:"\f785"}.fa-centos{--fa:"\f789"}.fa-confluence{--fa:"\f78d"}.fa-dhl{--fa:"\f790"}.fa-diaspora{--fa:"\f791"}.fa-fedex{--fa:"\f797"}.fa-fedora{--fa:"\f798"}.fa-figma{--fa:"\f799"}.fa-intercom{--fa:"\f7af"}.fa-invision{--fa:"\f7b0"}.fa-jira{--fa:"\f7b1"}.fa-mendeley{--fa:"\f7b3"}.fa-raspberry-pi{--fa:"\f7bb"}.fa-redhat{--fa:"\f7bc"}.fa-sketch{--fa:"\f7c6"}.fa-sourcetree{--fa:"\f7d3"}.fa-suse{--fa:"\f7d6"}.fa-ubuntu{--fa:"\f7df"}.fa-ups{--fa:"\f7e0"}.fa-usps{--fa:"\f7e1"}.fa-yarn{--fa:"\f7e3"}.fa-airbnb{--fa:"\f834"}.fa-battle-net{--fa:"\f835"}.fa-bootstrap{--fa:"\f836"}.fa-buffer{--fa:"\f837"}.fa-chromecast{--fa:"\f838"}.fa-evernote{--fa:"\f839"}.fa-itch-io{--fa:"\f83a"}.fa-salesforce{--fa:"\f83b"}.fa-speaker-deck{--fa:"\f83c"}.fa-symfony{--fa:"\f83d"}.fa-waze{--fa:"\f83f"}.fa-yammer{--fa:"\f840"}.fa-git-alt{--fa:"\f841"}.fa-stackpath{--fa:"\f842"}.fa-cotton-bureau{--fa:"\f89e"}.fa-buy-n-large{--fa:"\f8a6"}.fa-mdb{--fa:"\f8ca"}.fa-orcid{--fa:"\f8d2"}.fa-swift{--fa:"\f8e1"}.fa-umbraco{--fa:"\f8e8"}:host,:root{--fa-font-regular:normal 400 1em/1 var(--fa-family-classic)}@font-face{font-family:"Font Awesome 7 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2)}.far{--fa-family:var(--fa-family-classic)}.fa-regular,.far{--fa-style:400}:host,:root{--fa-family-classic:"Font Awesome 7 Free";--fa-font-solid:normal 900 1em/1 var(--fa-family-classic);--fa-style-family-classic:var(--fa-family-classic)}@font-face{font-family:"Font Awesome 7 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2)}.fas{--fa-style:900}.fa-classic,.fas{--fa-family:var(--fa-family-classic)}.fa-solid{--fa-style:900}@font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/css/v4-shims.min.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/css/v4-shims.min.css new file mode 100644 index 000000000..bf8d904f6 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/css/v4-shims.min.css @@ -0,0 +1,6 @@ +/*! + * Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2026 Fonticons, Inc. + */ +.fa.fa-glass{--fa:"\f000"}.fa.fa-envelope-o{--fa:"\f0e0"}.fa.fa-envelope-o,.fa.fa-star-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-star-o{--fa:"\f005"}.fa.fa-close,.fa.fa-remove{--fa:"\f00d"}.fa.fa-gear{--fa:"\f013"}.fa.fa-trash-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f2ed"}.fa.fa-home{--fa:"\f015"}.fa.fa-file-o{--fa:"\f15b"}.fa.fa-clock-o,.fa.fa-file-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-clock-o{--fa:"\f017"}.fa.fa-arrow-circle-o-down{--fa:"\f358"}.fa.fa-arrow-circle-o-down,.fa.fa-arrow-circle-o-up{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-arrow-circle-o-up{--fa:"\f35b"}.fa.fa-play-circle-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f144"}.fa.fa-repeat,.fa.fa-rotate-right{--fa:"\f01e"}.fa.fa-refresh{--fa:"\f021"}.fa.fa-list-alt{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f022"}.fa.fa-dedent{--fa:"\f03b"}.fa.fa-video-camera{--fa:"\f03d"}.fa.fa-picture-o{--fa:"\f03e"}.fa.fa-photo,.fa.fa-picture-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-photo{--fa:"\f03e"}.fa.fa-image{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f03e"}.fa.fa-map-marker{--fa:"\f3c5"}.fa.fa-pencil-square-o{--fa:"\f044"}.fa.fa-edit,.fa.fa-pencil-square-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-edit{--fa:"\f044"}.fa.fa-share-square-o{--fa:"\f14d"}.fa.fa-check-square-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f14a"}.fa.fa-arrows{--fa:"\f0b2"}.fa.fa-times-circle-o{--fa:"\f057"}.fa.fa-check-circle-o,.fa.fa-times-circle-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-check-circle-o{--fa:"\f058"}.fa.fa-mail-forward{--fa:"\f064"}.fa.fa-expand{--fa:"\f424"}.fa.fa-compress{--fa:"\f422"}.fa.fa-eye,.fa.fa-eye-slash{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-warning{--fa:"\f071"}.fa.fa-calendar{--fa:"\f073"}.fa.fa-arrows-v{--fa:"\f338"}.fa.fa-arrows-h{--fa:"\f337"}.fa.fa-bar-chart,.fa.fa-bar-chart-o{--fa:"\e0e3"}.fa.fa-twitter-square{--fa:"\f081"}.fa.fa-facebook-square,.fa.fa-twitter-square{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-facebook-square{--fa:"\f082"}.fa.fa-gears{--fa:"\f085"}.fa.fa-thumbs-o-up{--fa:"\f164"}.fa.fa-thumbs-o-down,.fa.fa-thumbs-o-up{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-thumbs-o-down{--fa:"\f165"}.fa.fa-heart-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f004"}.fa.fa-sign-out{--fa:"\f2f5"}.fa.fa-linkedin-square{font-family:"Font Awesome 7 Brands";font-weight:400;--fa:"\f08c"}.fa.fa-thumb-tack{--fa:"\f08d"}.fa.fa-external-link{--fa:"\f35d"}.fa.fa-sign-in{--fa:"\f2f6"}.fa.fa-github-square{font-family:"Font Awesome 7 Brands";font-weight:400;--fa:"\f092"}.fa.fa-lemon-o{--fa:"\f094"}.fa.fa-lemon-o,.fa.fa-square-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-square-o{--fa:"\f0c8"}.fa.fa-bookmark-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f02e"}.fa.fa-facebook,.fa.fa-twitter{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-facebook{--fa:"\f39e"}.fa.fa-facebook-f{--fa:"\f39e"}.fa.fa-facebook-f,.fa.fa-github{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-credit-card{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-feed{--fa:"\f09e"}.fa.fa-hdd-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f0a0"}.fa.fa-hand-o-right{--fa:"\f0a4"}.fa.fa-hand-o-left,.fa.fa-hand-o-right{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-hand-o-left{--fa:"\f0a5"}.fa.fa-hand-o-up{--fa:"\f0a6"}.fa.fa-hand-o-down,.fa.fa-hand-o-up{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-hand-o-down{--fa:"\f0a7"}.fa.fa-globe{--fa:"\f57d"}.fa.fa-tasks{--fa:"\f828"}.fa.fa-arrows-alt{--fa:"\f31e"}.fa.fa-group{--fa:"\f0c0"}.fa.fa-chain{--fa:"\f0c1"}.fa.fa-cut{--fa:"\f0c4"}.fa.fa-files-o{--fa:"\f0c5"}.fa.fa-files-o,.fa.fa-floppy-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-floppy-o{--fa:"\f0c7"}.fa.fa-save{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f0c7"}.fa.fa-navicon,.fa.fa-reorder{--fa:"\f0c9"}.fa.fa-magic{--fa:"\e2ca"}.fa.fa-pinterest,.fa.fa-pinterest-square{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-pinterest-square{--fa:"\f0d3"}.fa.fa-google-plus-square{--fa:"\f0d4"}.fa.fa-google-plus,.fa.fa-google-plus-square{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-google-plus{--fa:"\f0d5"}.fa.fa-money{--fa:"\f3d1"}.fa.fa-unsorted{--fa:"\f0dc"}.fa.fa-sort-desc{--fa:"\f0dd"}.fa.fa-sort-asc{--fa:"\f0de"}.fa.fa-linkedin{font-family:"Font Awesome 7 Brands";font-weight:400;--fa:"\f0e1"}.fa.fa-rotate-left{--fa:"\f0e2"}.fa.fa-legal{--fa:"\f0e3"}.fa.fa-dashboard,.fa.fa-tachometer{--fa:"\f625"}.fa.fa-comment-o{--fa:"\f075"}.fa.fa-comment-o,.fa.fa-comments-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-comments-o{--fa:"\f086"}.fa.fa-flash{--fa:"\f0e7"}.fa.fa-clipboard{--fa:"\f0ea"}.fa.fa-lightbulb-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f0eb"}.fa.fa-exchange{--fa:"\f362"}.fa.fa-cloud-download{--fa:"\f0ed"}.fa.fa-cloud-upload{--fa:"\f0ee"}.fa.fa-bell-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f0f3"}.fa.fa-cutlery{--fa:"\f2e7"}.fa.fa-file-text-o{--fa:"\f15c"}.fa.fa-building-o,.fa.fa-file-text-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-building-o{--fa:"\f1ad"}.fa.fa-hospital-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f0f8"}.fa.fa-tablet{--fa:"\f3fa"}.fa.fa-mobile,.fa.fa-mobile-phone{--fa:"\f3cd"}.fa.fa-circle-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f111"}.fa.fa-mail-reply{--fa:"\f3e5"}.fa.fa-github-alt{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-folder-o{--fa:"\f07b"}.fa.fa-folder-o,.fa.fa-folder-open-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-folder-open-o{--fa:"\f07c"}.fa.fa-smile-o{--fa:"\f118"}.fa.fa-frown-o,.fa.fa-smile-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-frown-o{--fa:"\f119"}.fa.fa-meh-o{--fa:"\f11a"}.fa.fa-keyboard-o,.fa.fa-meh-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-keyboard-o{--fa:"\f11c"}.fa.fa-flag-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f024"}.fa.fa-mail-reply-all{--fa:"\f122"}.fa.fa-star-half-o{--fa:"\f5c0"}.fa.fa-star-half-empty,.fa.fa-star-half-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-star-half-empty{--fa:"\f5c0"}.fa.fa-star-half-full{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f5c0"}.fa.fa-code-fork{--fa:"\f126"}.fa.fa-chain-broken,.fa.fa-unlink{--fa:"\f127"}.fa.fa-calendar-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f133"}.fa.fa-css3,.fa.fa-html5,.fa.fa-maxcdn{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-unlock-alt{--fa:"\f09c"}.fa.fa-minus-square-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f146"}.fa.fa-level-up{--fa:"\f3bf"}.fa.fa-level-down{--fa:"\f3be"}.fa.fa-pencil-square{--fa:"\f14b"}.fa.fa-external-link-square{--fa:"\f360"}.fa.fa-compass{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-caret-square-o-down{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f150"}.fa.fa-toggle-down{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f150"}.fa.fa-caret-square-o-up{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f151"}.fa.fa-toggle-up{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f151"}.fa.fa-caret-square-o-right{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f152"}.fa.fa-toggle-right{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f152"}.fa.fa-eur,.fa.fa-euro{--fa:"\f153"}.fa.fa-gbp{--fa:"\f154"}.fa.fa-dollar,.fa.fa-usd{--fa:"\$"}.fa.fa-inr,.fa.fa-rupee{--fa:"\e1bc"}.fa.fa-cny,.fa.fa-jpy,.fa.fa-rmb,.fa.fa-yen{--fa:"\f157"}.fa.fa-rouble,.fa.fa-rub,.fa.fa-ruble{--fa:"\f158"}.fa.fa-krw,.fa.fa-won{--fa:"\f159"}.fa.fa-bitcoin,.fa.fa-btc{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-bitcoin{--fa:"\f15a"}.fa.fa-file-text{--fa:"\f15c"}.fa.fa-sort-alpha-asc{--fa:"\f15d"}.fa.fa-sort-alpha-desc{--fa:"\f881"}.fa.fa-sort-amount-asc{--fa:"\f884"}.fa.fa-sort-amount-desc{--fa:"\f160"}.fa.fa-sort-numeric-asc{--fa:"\f162"}.fa.fa-sort-numeric-desc{--fa:"\f886"}.fa.fa-youtube-square{--fa:"\f431"}.fa.fa-xing,.fa.fa-xing-square,.fa.fa-youtube,.fa.fa-youtube-square{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-xing-square{--fa:"\f169"}.fa.fa-youtube-play{--fa:"\f167"}.fa.fa-adn,.fa.fa-bitbucket,.fa.fa-bitbucket-square,.fa.fa-dropbox,.fa.fa-flickr,.fa.fa-instagram,.fa.fa-stack-overflow,.fa.fa-youtube-play{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-bitbucket-square{--fa:"\f171"}.fa.fa-tumblr,.fa.fa-tumblr-square{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-tumblr-square{--fa:"\f174"}.fa.fa-long-arrow-down{--fa:"\f309"}.fa.fa-long-arrow-up{--fa:"\f30c"}.fa.fa-long-arrow-left{--fa:"\f30a"}.fa.fa-long-arrow-right{--fa:"\f30b"}.fa.fa-android,.fa.fa-apple,.fa.fa-dribbble,.fa.fa-foursquare,.fa.fa-gittip,.fa.fa-gratipay,.fa.fa-linux,.fa.fa-skype,.fa.fa-trello,.fa.fa-windows{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-gittip{--fa:"\f184"}.fa.fa-sun-o{--fa:"\f185"}.fa.fa-moon-o,.fa.fa-sun-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-moon-o{--fa:"\f186"}.fa.fa-pagelines,.fa.fa-renren,.fa.fa-stack-exchange,.fa.fa-vk,.fa.fa-weibo{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-arrow-circle-o-right{--fa:"\f35a"}.fa.fa-arrow-circle-o-left,.fa.fa-arrow-circle-o-right{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-arrow-circle-o-left{--fa:"\f359"}.fa.fa-caret-square-o-left{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f191"}.fa.fa-toggle-left{--fa:"\f191"}.fa.fa-dot-circle-o,.fa.fa-toggle-left{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-dot-circle-o{--fa:"\f192"}.fa.fa-vimeo-square{font-family:"Font Awesome 7 Brands";font-weight:400;--fa:"\f194"}.fa.fa-try,.fa.fa-turkish-lira{--fa:"\e2bb"}.fa.fa-plus-square-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f0fe"}.fa.fa-openid,.fa.fa-slack,.fa.fa-wordpress{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-bank,.fa.fa-institution{--fa:"\f19c"}.fa.fa-mortar-board{--fa:"\f19d"}.fa.fa-google,.fa.fa-reddit,.fa.fa-reddit-square,.fa.fa-yahoo{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-reddit-square{--fa:"\f1a2"}.fa.fa-behance,.fa.fa-behance-square,.fa.fa-delicious,.fa.fa-digg,.fa.fa-drupal,.fa.fa-joomla,.fa.fa-pied-piper-alt,.fa.fa-pied-piper-pp,.fa.fa-stumbleupon,.fa.fa-stumbleupon-circle{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-behance-square{--fa:"\f1b5"}.fa.fa-steam,.fa.fa-steam-square{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-steam-square{--fa:"\f1b7"}.fa.fa-automobile{--fa:"\f1b9"}.fa.fa-cab{--fa:"\f1ba"}.fa.fa-deviantart,.fa.fa-soundcloud,.fa.fa-spotify{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-file-pdf-o{--fa:"\f1c1"}.fa.fa-file-pdf-o,.fa.fa-file-word-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-file-word-o{--fa:"\f1c2"}.fa.fa-file-excel-o{--fa:"\f1c3"}.fa.fa-file-excel-o,.fa.fa-file-powerpoint-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-file-powerpoint-o{--fa:"\f1c4"}.fa.fa-file-image-o{--fa:"\f1c5"}.fa.fa-file-image-o,.fa.fa-file-photo-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-file-photo-o{--fa:"\f1c5"}.fa.fa-file-picture-o{--fa:"\f1c5"}.fa.fa-file-archive-o,.fa.fa-file-picture-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-file-archive-o{--fa:"\f1c6"}.fa.fa-file-zip-o{--fa:"\f1c6"}.fa.fa-file-audio-o,.fa.fa-file-zip-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-file-audio-o{--fa:"\f1c7"}.fa.fa-file-sound-o{--fa:"\f1c7"}.fa.fa-file-sound-o,.fa.fa-file-video-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-file-video-o{--fa:"\f1c8"}.fa.fa-file-movie-o{--fa:"\f1c8"}.fa.fa-file-code-o,.fa.fa-file-movie-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-file-code-o{--fa:"\f1c9"}.fa.fa-codepen,.fa.fa-jsfiddle,.fa.fa-vine{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-life-bouy,.fa.fa-life-buoy,.fa.fa-life-saver,.fa.fa-support{--fa:"\f1cd"}.fa.fa-circle-o-notch{--fa:"\f1ce"}.fa.fa-ra,.fa.fa-rebel{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-ra{--fa:"\f1d0"}.fa.fa-resistance{--fa:"\f1d0"}.fa.fa-empire,.fa.fa-ge,.fa.fa-resistance{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-ge{--fa:"\f1d1"}.fa.fa-git-square{--fa:"\f1d2"}.fa.fa-git,.fa.fa-git-square,.fa.fa-hacker-news,.fa.fa-y-combinator-square{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-y-combinator-square{--fa:"\f1d4"}.fa.fa-yc-square{--fa:"\f1d4"}.fa.fa-qq,.fa.fa-tencent-weibo,.fa.fa-wechat,.fa.fa-weixin,.fa.fa-yc-square{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-wechat{--fa:"\f1d7"}.fa.fa-send{--fa:"\f1d8"}.fa.fa-paper-plane-o{--fa:"\f1d8"}.fa.fa-paper-plane-o,.fa.fa-send-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-send-o{--fa:"\f1d8"}.fa.fa-circle-thin{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f111"}.fa.fa-header{--fa:"\f1dc"}.fa.fa-futbol-o{--fa:"\f1e3"}.fa.fa-futbol-o,.fa.fa-soccer-ball-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-soccer-ball-o{--fa:"\f1e3"}.fa.fa-slideshare,.fa.fa-twitch,.fa.fa-yelp{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-newspaper-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f1ea"}.fa.fa-cc-amex,.fa.fa-cc-discover,.fa.fa-cc-mastercard,.fa.fa-cc-paypal,.fa.fa-cc-stripe,.fa.fa-cc-visa,.fa.fa-google-wallet,.fa.fa-paypal{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-bell-slash-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f1f6"}.fa.fa-trash{--fa:"\f2ed"}.fa.fa-copyright{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-eyedropper{--fa:"\f1fb"}.fa.fa-area-chart{--fa:"\f1fe"}.fa.fa-pie-chart{--fa:"\f200"}.fa.fa-line-chart{--fa:"\f201"}.fa.fa-lastfm,.fa.fa-lastfm-square{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-lastfm-square{--fa:"\f203"}.fa.fa-angellist,.fa.fa-ioxhost{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-cc{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f20a"}.fa.fa-ils,.fa.fa-shekel,.fa.fa-sheqel{--fa:"\f20b"}.fa.fa-buysellads,.fa.fa-connectdevelop,.fa.fa-dashcube,.fa.fa-forumbee,.fa.fa-leanpub,.fa.fa-sellsy,.fa.fa-shirtsinbulk,.fa.fa-simplybuilt,.fa.fa-skyatlas{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-diamond{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f3a5"}.fa.fa-intersex,.fa.fa-transgender{--fa:"\f224"}.fa.fa-transgender-alt{--fa:"\f225"}.fa.fa-facebook-official{--fa:"\f09a"}.fa.fa-facebook-official,.fa.fa-pinterest-p,.fa.fa-whatsapp{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-hotel{--fa:"\f236"}.fa.fa-medium,.fa.fa-viacoin,.fa.fa-y-combinator,.fa.fa-yc{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-yc{--fa:"\f23b"}.fa.fa-expeditedssl,.fa.fa-opencart,.fa.fa-optin-monster{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-battery,.fa.fa-battery-4{--fa:"\f240"}.fa.fa-battery-3{--fa:"\f241"}.fa.fa-battery-2{--fa:"\f242"}.fa.fa-battery-1{--fa:"\f243"}.fa.fa-battery-0{--fa:"\f244"}.fa.fa-object-group,.fa.fa-object-ungroup,.fa.fa-sticky-note-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-sticky-note-o{--fa:"\f249"}.fa.fa-cc-diners-club,.fa.fa-cc-jcb{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-clone{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-hourglass-o{--fa:"\f254"}.fa.fa-hourglass-1{--fa:"\f251"}.fa.fa-hourglass-2{--fa:"\f252"}.fa.fa-hourglass-3{--fa:"\f253"}.fa.fa-hand-rock-o{--fa:"\f255"}.fa.fa-hand-grab-o,.fa.fa-hand-rock-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-hand-grab-o{--fa:"\f255"}.fa.fa-hand-paper-o{--fa:"\f256"}.fa.fa-hand-paper-o,.fa.fa-hand-stop-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-hand-stop-o{--fa:"\f256"}.fa.fa-hand-scissors-o{--fa:"\f257"}.fa.fa-hand-lizard-o,.fa.fa-hand-scissors-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-hand-lizard-o{--fa:"\f258"}.fa.fa-hand-spock-o{--fa:"\f259"}.fa.fa-hand-pointer-o,.fa.fa-hand-spock-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-hand-pointer-o{--fa:"\f25a"}.fa.fa-hand-peace-o{--fa:"\f25b"}.fa.fa-hand-peace-o,.fa.fa-registered{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-creative-commons,.fa.fa-gg,.fa.fa-gg-circle,.fa.fa-odnoklassniki,.fa.fa-odnoklassniki-square{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-odnoklassniki-square{--fa:"\f264"}.fa.fa-chrome,.fa.fa-firefox,.fa.fa-get-pocket,.fa.fa-internet-explorer,.fa.fa-opera,.fa.fa-safari,.fa.fa-wikipedia-w{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-television{--fa:"\f26c"}.fa.fa-500px,.fa.fa-amazon,.fa.fa-contao{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-calendar-plus-o{--fa:"\f271"}.fa.fa-calendar-minus-o,.fa.fa-calendar-plus-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-calendar-minus-o{--fa:"\f272"}.fa.fa-calendar-times-o{--fa:"\f273"}.fa.fa-calendar-check-o,.fa.fa-calendar-times-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-calendar-check-o{--fa:"\f274"}.fa.fa-map-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f279"}.fa.fa-commenting{--fa:"\f4ad"}.fa.fa-commenting-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f4ad"}.fa.fa-houzz,.fa.fa-vimeo{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-vimeo{--fa:"\f27d"}.fa.fa-black-tie,.fa.fa-edge,.fa.fa-fonticons,.fa.fa-reddit-alien{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-credit-card-alt{--fa:"\f09d"}.fa.fa-codiepie,.fa.fa-fort-awesome,.fa.fa-mixcloud,.fa.fa-modx,.fa.fa-product-hunt,.fa.fa-scribd,.fa.fa-usb{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-pause-circle-o{--fa:"\f28b"}.fa.fa-pause-circle-o,.fa.fa-stop-circle-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-stop-circle-o{--fa:"\f28d"}.fa.fa-bluetooth,.fa.fa-bluetooth-b,.fa.fa-envira,.fa.fa-gitlab,.fa.fa-wheelchair-alt,.fa.fa-wpbeginner,.fa.fa-wpforms{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-wheelchair-alt{--fa:"\f368"}.fa.fa-question-circle-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f059"}.fa.fa-volume-control-phone{--fa:"\f2a0"}.fa.fa-asl-interpreting{--fa:"\f2a3"}.fa.fa-deafness,.fa.fa-hard-of-hearing{--fa:"\f2a4"}.fa.fa-glide,.fa.fa-glide-g{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-signing{--fa:"\f2a7"}.fa.fa-viadeo,.fa.fa-viadeo-square{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-viadeo-square{--fa:"\f2aa"}.fa.fa-snapchat,.fa.fa-snapchat-ghost{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-snapchat-ghost{--fa:"\f2ab"}.fa.fa-snapchat-square{--fa:"\f2ad"}.fa.fa-first-order,.fa.fa-google-plus-official,.fa.fa-pied-piper,.fa.fa-snapchat-square,.fa.fa-themeisle,.fa.fa-yoast{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-google-plus-official{--fa:"\f2b3"}.fa.fa-google-plus-circle{--fa:"\f2b3"}.fa.fa-fa,.fa.fa-font-awesome,.fa.fa-google-plus-circle{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-fa{--fa:"\f2b4"}.fa.fa-handshake-o{--fa:"\f2b5"}.fa.fa-envelope-open-o,.fa.fa-handshake-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-envelope-open-o{--fa:"\f2b6"}.fa.fa-linode{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-address-book-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f2b9"}.fa.fa-vcard{--fa:"\f2bb"}.fa.fa-address-card-o{--fa:"\f2bb"}.fa.fa-address-card-o,.fa.fa-vcard-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-vcard-o{--fa:"\f2bb"}.fa.fa-user-circle-o{--fa:"\f2bd"}.fa.fa-user-circle-o,.fa.fa-user-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-user-o{--fa:"\f007"}.fa.fa-id-badge{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-drivers-license{--fa:"\f2c2"}.fa.fa-id-card-o{--fa:"\f2c2"}.fa.fa-drivers-license-o,.fa.fa-id-card-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-drivers-license-o{--fa:"\f2c2"}.fa.fa-free-code-camp,.fa.fa-quora,.fa.fa-telegram{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-thermometer,.fa.fa-thermometer-4{--fa:"\f2c7"}.fa.fa-thermometer-3{--fa:"\f2c8"}.fa.fa-thermometer-2{--fa:"\f2c9"}.fa.fa-thermometer-1{--fa:"\f2ca"}.fa.fa-thermometer-0{--fa:"\f2cb"}.fa.fa-bathtub,.fa.fa-s15{--fa:"\f2cd"}.fa.fa-window-maximize,.fa.fa-window-restore{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-times-rectangle{--fa:"\f410"}.fa.fa-window-close-o{--fa:"\f410"}.fa.fa-times-rectangle-o,.fa.fa-window-close-o{font-family:"Font Awesome 7 Free";font-weight:400}.fa.fa-times-rectangle-o{--fa:"\f410"}.fa.fa-bandcamp,.fa.fa-eercast,.fa.fa-etsy,.fa.fa-grav,.fa.fa-imdb,.fa.fa-ravelry{font-family:"Font Awesome 7 Brands";font-weight:400}.fa.fa-eercast{--fa:"\f2da"}.fa.fa-snowflake-o{font-family:"Font Awesome 7 Free";font-weight:400;--fa:"\f2dc"}.fa.fa-meetup,.fa.fa-superpowers,.fa.fa-wpexplorer{font-family:"Font Awesome 7 Brands";font-weight:400} \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-brands-400.woff2 b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-brands-400.woff2 new file mode 100644 index 000000000..e8bd881bb Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-brands-400.woff2 differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-regular-400.woff2 b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-regular-400.woff2 new file mode 100644 index 000000000..344b101af Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-regular-400.woff2 differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-solid-900.woff2 b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-solid-900.woff2 new file mode 100644 index 000000000..ea09c935a Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-solid-900.woff2 differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-v4compatibility.woff2 b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-v4compatibility.woff2 new file mode 100644 index 000000000..9ea71671c Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/font-awesome/webfonts/fa-v4compatibility.woff2 differ diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/animated-overlay.gif b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/animated-overlay.gif similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/animated-overlay.gif rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/animated-overlay.gif diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_0_aaaaaa_40x100.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_0_aaaaaa_40x100.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_0_aaaaaa_40x100.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_0_aaaaaa_40x100.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_0_eeeeee_40x100.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_0_eeeeee_40x100.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_0_eeeeee_40x100.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_0_eeeeee_40x100.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_55_ffffff_40x100.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_55_ffffff_40x100.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_55_ffffff_40x100.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_55_ffffff_40x100.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_75_ffffff_40x100.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_75_ffffff_40x100.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_75_ffffff_40x100.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_flat_75_ffffff_40x100.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_glass_65_ffffff_1x400.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_glass_65_ffffff_1x400.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_glass_65_ffffff_1x400.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_glass_65_ffffff_1x400.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_0073ea_256x240.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_0073ea_256x240.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_0073ea_256x240.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_0073ea_256x240.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_454545_256x240.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_454545_256x240.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_454545_256x240.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_454545_256x240.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_666666_256x240.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_666666_256x240.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_666666_256x240.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_666666_256x240.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_ff0084_256x240.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_ff0084_256x240.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_ff0084_256x240.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_ff0084_256x240.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_ffffff_256x240.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_ffffff_256x240.png similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_ffffff_256x240.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/images/ui-icons_ffffff_256x240.png diff --git a/wpsbuilder/components/jquery-ui/themes/flick/jquery-ui.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/jquery-ui.css similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/jquery-ui.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/jquery-ui.css diff --git a/wpsbuilder/components/jquery-ui/themes/flick/jquery-ui.min.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/jquery-ui.min.css similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/jquery-ui.min.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/jquery-ui.min.css diff --git a/wpsbuilder/components/jquery-ui/themes/flick/theme.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/theme.css similarity index 100% rename from wpsbuilder/components/jquery-ui/themes/flick/theme.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jquery-ui/themes/flick/theme.css diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jszip/jszip.min.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jszip/jszip.min.js new file mode 100644 index 000000000..ff4cfd5e8 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/components/jszip/jszip.min.js @@ -0,0 +1,13 @@ +/*! + +JSZip v3.10.1 - A JavaScript class for generating and reading zip files + + +(c) 2009-2016 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/main/LICENSE +*/ + +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).JSZip=e()}}(function(){return function s(a,o,h){function u(r,e){if(!o[r]){if(!a[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(l)return l(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return u(t||e)},i,i.exports,s,a,o,h)}return o[r].exports}for(var l="function"==typeof require&&require,e=0;e>2,s=(3&t)<<4|r>>4,a=1>6:64,o=2>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),l[h++]=t,64!==s&&(l[h++]=r),64!==a&&(l[h++]=n);return l}},{"./support":30,"./utils":32}],2:[function(e,t,r){"use strict";var n=e("./external"),i=e("./stream/DataWorker"),s=e("./stream/Crc32Probe"),a=e("./stream/DataLengthProbe");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),t=this;return e.on("end",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a("uncompressedSize")).pipe(t.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",t)},t.exports=o},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(e,t,r){"use strict";var n=e("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(){return new n("STORE compression")},uncompressWorker:function(){return new n("STORE decompression")}},r.DEFLATE=e("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(e,t,r){"use strict";var n=e("./utils");var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t){return void 0!==e&&e.length?"string"!==n.getTypeOf(e)?function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}(0|t,e,e.length,0):function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t.charCodeAt(a))];return-1^e}(0|t,e,e.length,0):0}},{"./utils":32}],5:[function(e,t,r){"use strict";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(e,t,r){"use strict";var n=null;n="undefined"!=typeof Promise?Promise:e("lie"),t.exports={Promise:n}},{lie:37}],7:[function(e,t,r){"use strict";var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,i=e("pako"),s=e("./utils"),a=e("./stream/GenericWorker"),o=n?"uint8array":"array";function h(e,t){a.call(this,"FlateWorker/"+e),this._pako=null,this._pakoAction=e,this._pakoOptions=t,this.meta={}}r.magic="\b\0",s.inherits(h,a),h.prototype.processChunk=function(e){this.meta=e.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,e.data),!1)},h.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0)},h.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null},h.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var t=this;this._pako.onData=function(e){t.push({data:e,meta:t.meta})}},r.compressWorker=function(e){return new h("Deflate",e)},r.uncompressWorker=function(){return new h("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(e,t,r){"use strict";function A(e,t){var r,n="";for(r=0;r>>=8;return n}function n(e,t,r,n,i,s){var a,o,h=e.file,u=e.compression,l=s!==O.utf8encode,f=I.transformTo("string",s(h.name)),c=I.transformTo("string",O.utf8encode(h.name)),d=h.comment,p=I.transformTo("string",s(d)),m=I.transformTo("string",O.utf8encode(d)),_=c.length!==h.name.length,g=m.length!==d.length,b="",v="",y="",w=h.dir,k=h.date,x={crc32:0,compressedSize:0,uncompressedSize:0};t&&!r||(x.crc32=e.crc32,x.compressedSize=e.compressedSize,x.uncompressedSize=e.uncompressedSize);var S=0;t&&(S|=8),l||!_&&!g||(S|=2048);var z=0,C=0;w&&(z|=16),"UNIX"===i?(C=798,z|=function(e,t){var r=e;return e||(r=t?16893:33204),(65535&r)<<16}(h.unixPermissions,w)):(C=20,z|=function(e){return 63&(e||0)}(h.dosPermissions)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v=A(1,1)+A(B(f),4)+c,b+="up"+A(v.length,2)+v),g&&(y=A(1,1)+A(B(p),4)+m,b+="uc"+A(y.length,2)+y);var E="";return E+="\n\0",E+=A(S,2),E+=u.magic,E+=A(a,2),E+=A(o,2),E+=A(x.crc32,4),E+=A(x.compressedSize,4),E+=A(x.uncompressedSize,4),E+=A(f.length,2),E+=A(b.length,2),{fileRecord:R.LOCAL_FILE_HEADER+E+f+b,dirRecord:R.CENTRAL_FILE_HEADER+A(C,2)+E+A(p.length,2)+"\0\0\0\0"+A(z,4)+A(n,4)+f+b+p}}var I=e("../utils"),i=e("../stream/GenericWorker"),O=e("../utf8"),B=e("../crc32"),R=e("../signature");function s(e,t,r,n){i.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=t,this.zipPlatform=r,this.encodeFileName=n,this.streamFiles=e,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}I.inherits(s,i),s.prototype.push=function(e){var t=e.meta.percent||0,r=this.entriesCount,n=this._sources.length;this.accumulate?this.contentBuffer.push(e):(this.bytesWritten+=e.data.length,i.prototype.push.call(this,{data:e.data,meta:{currentFile:this.currentFile,percent:r?(t+100*(r-n-1))/r:100}}))},s.prototype.openedSource=function(e){this.currentSourceOffset=this.bytesWritten,this.currentFile=e.file.name;var t=this.streamFiles&&!e.file.dir;if(t){var r=n(e,t,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}})}else this.accumulate=!0},s.prototype.closedSource=function(e){this.accumulate=!1;var t=this.streamFiles&&!e.file.dir,r=n(e,t,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(r.dirRecord),t)this.push({data:function(e){return R.DATA_DESCRIPTOR+A(e.crc32,4)+A(e.compressedSize,4)+A(e.uncompressedSize,4)}(e),meta:{percent:100}});else for(this.push({data:r.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},s.prototype.flush=function(){for(var e=this.bytesWritten,t=0;t=this.index;t--)r=(r<<8)+this.byteAt(t);return this.index+=e,r},readString:function(e){return n.transformTo("string",this.readData(e))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var e=this.readInt(4);return new Date(Date.UTC(1980+(e>>25&127),(e>>21&15)-1,e>>16&31,e>>11&31,e>>5&63,(31&e)<<1))}},t.exports=i},{"../utils":32}],19:[function(e,t,r){"use strict";var n=e("./Uint8ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(e,t,r){"use strict";var n=e("./DataReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data.charCodeAt(this.zero+e)},i.prototype.lastIndexOfSignature=function(e){return this.data.lastIndexOf(e)-this.zero},i.prototype.readAndCheckSignature=function(e){return e===this.readData(4)},i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./DataReader":18}],21:[function(e,t,r){"use strict";var n=e("./ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return new Uint8Array(0);var t=this.data.subarray(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./ArrayReader":17}],22:[function(e,t,r){"use strict";var n=e("../utils"),i=e("../support"),s=e("./ArrayReader"),a=e("./StringReader"),o=e("./NodeBufferReader"),h=e("./Uint8ArrayReader");t.exports=function(e){var t=n.getTypeOf(e);return n.checkSupport(t),"string"!==t||i.uint8array?"nodebuffer"===t?new o(e):i.uint8array?new h(n.transformTo("uint8array",e)):new s(n.transformTo("array",e)):new a(e)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(e,t,r){"use strict";r.LOCAL_FILE_HEADER="PK",r.CENTRAL_FILE_HEADER="PK",r.CENTRAL_DIRECTORY_END="PK",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",r.ZIP64_CENTRAL_DIRECTORY_END="PK",r.DATA_DESCRIPTOR="PK\b"},{}],24:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../utils");function s(e){n.call(this,"ConvertWorker to "+e),this.destType=e}i.inherits(s,n),s.prototype.processChunk=function(e){this.push({data:i.transformTo(this.destType,e.data),meta:e.meta})},t.exports=s},{"../utils":32,"./GenericWorker":28}],25:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../crc32");function s(){n.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}e("../utils").inherits(s,n),s.prototype.processChunk=function(e){this.streamInfo.crc32=i(e.data,this.streamInfo.crc32||0),this.push(e)},t.exports=s},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataLengthProbe for "+e),this.propName=e,this.withStreamInfo(e,0)}n.inherits(s,i),s.prototype.processChunk=function(e){if(e){var t=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=t+e.data.length}i.prototype.processChunk.call(this,e)},t.exports=s},{"../utils":32,"./GenericWorker":28}],27:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataWorker");var t=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,e.then(function(e){t.dataIsReady=!0,t.data=e,t.max=e&&e.length||0,t.type=n.getTypeOf(e),t.isPaused||t._tickAndRepeat()},function(e){t.error(e)})}n.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,n.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(n.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var e=null,t=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":e=this.data.substring(this.index,t);break;case"uint8array":e=this.data.subarray(this.index,t);break;case"array":case"nodebuffer":e=this.data.slice(this.index,t)}return this.index=t,this.push({data:e,meta:{percent:this.max?this.index/this.max*100:0}})},t.exports=s},{"../utils":32,"./GenericWorker":28}],28:[function(e,t,r){"use strict";function n(e){this.name=e||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}n.prototype={push:function(e){this.emit("data",e)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(e){this.emit("error",e)}return!0},error:function(e){return!this.isFinished&&(this.isPaused?this.generatedError=e:(this.isFinished=!0,this.emit("error",e),this.previous&&this.previous.error(e),this.cleanUp()),!0)},on:function(e,t){return this._listeners[e].push(t),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(e,t){if(this._listeners[e])for(var r=0;r "+e:e}},t.exports=n},{}],29:[function(e,t,r){"use strict";var h=e("../utils"),i=e("./ConvertWorker"),s=e("./GenericWorker"),u=e("../base64"),n=e("../support"),a=e("../external"),o=null;if(n.nodestream)try{o=e("../nodejs/NodejsStreamOutputAdapter")}catch(e){}function l(e,o){return new a.Promise(function(t,r){var n=[],i=e._internalType,s=e._outputType,a=e._mimeType;e.on("data",function(e,t){n.push(e),o&&o(t)}).on("error",function(e){n=[],r(e)}).on("end",function(){try{var e=function(e,t,r){switch(e){case"blob":return h.newBlob(h.transformTo("arraybuffer",t),r);case"base64":return u.encode(t);default:return h.transformTo(e,t)}}(s,function(e,t){var r,n=0,i=null,s=0;for(r=0;r>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t}(e)},s.utf8decode=function(e){return h.nodebuffer?o.transformTo("nodebuffer",e).toString("utf-8"):function(e){var t,r,n,i,s=e.length,a=new Array(2*s);for(t=r=0;t>10&1023,a[r++]=56320|1023&n)}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(e=o.transformTo(h.uint8array?"uint8array":"array",e))},o.inherits(a,n),a.prototype.processChunk=function(e){var t=o.transformTo(h.uint8array?"uint8array":"array",e.data);if(this.leftOver&&this.leftOver.length){if(h.uint8array){var r=t;(t=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),t.set(r,this.leftOver.length)}else t=this.leftOver.concat(t);this.leftOver=null}var n=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}(t),i=t;n!==t.length&&(h.uint8array?(i=t.subarray(0,n),this.leftOver=t.subarray(n,t.length)):(i=t.slice(0,n),this.leftOver=t.slice(n,t.length))),this.push({data:s.utf8decode(i),meta:e.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},s.Utf8DecodeWorker=a,o.inherits(l,n),l.prototype.processChunk=function(e){this.push({data:s.utf8encode(e.data),meta:e.meta})},s.Utf8EncodeWorker=l},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(e,t,a){"use strict";var o=e("./support"),h=e("./base64"),r=e("./nodejsUtils"),u=e("./external");function n(e){return e}function l(e,t){for(var r=0;r>8;this.dir=!!(16&this.externalFileAttributes),0==e&&(this.dosPermissions=63&this.externalFileAttributes),3==e&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var e=n(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=e.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=e.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=e.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=e.readInt(4))}},readExtraFields:function(e){var t,r,n,i=e.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});e.index+4>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t},r.buf2binstring=function(e){return l(e,e.length)},r.binstring2buf=function(e){for(var t=new h.Buf8(e.length),r=0,n=t.length;r>10&1023,o[n++]=56320|1023&i)}return l(o,n)},r.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}},{"./common":41}],43:[function(e,t,r){"use strict";t.exports=function(e,t,r,n){for(var i=65535&e|0,s=e>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}},{}],46:[function(e,t,r){"use strict";var h,c=e("../utils/common"),u=e("./trees"),d=e("./adler32"),p=e("./crc32"),n=e("./messages"),l=0,f=4,m=0,_=-2,g=-1,b=4,i=2,v=8,y=9,s=286,a=30,o=19,w=2*s+1,k=15,x=3,S=258,z=S+x+1,C=42,E=113,A=1,I=2,O=3,B=4;function R(e,t){return e.msg=n[t],t}function T(e){return(e<<1)-(4e.avail_out&&(r=e.avail_out),0!==r&&(c.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0))}function N(e,t){u._tr_flush_block(e,0<=e.block_start?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,F(e.strm)}function U(e,t){e.pending_buf[e.pending++]=t}function P(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t}function L(e,t){var r,n,i=e.max_chain_length,s=e.strstart,a=e.prev_length,o=e.nice_match,h=e.strstart>e.w_size-z?e.strstart-(e.w_size-z):0,u=e.window,l=e.w_mask,f=e.prev,c=e.strstart+S,d=u[s+a-1],p=u[s+a];e.prev_length>=e.good_match&&(i>>=2),o>e.lookahead&&(o=e.lookahead);do{if(u[(r=t)+a]===p&&u[r+a-1]===d&&u[r]===u[s]&&u[++r]===u[s+1]){s+=2,r++;do{}while(u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&sh&&0!=--i);return a<=e.lookahead?a:e.lookahead}function j(e){var t,r,n,i,s,a,o,h,u,l,f=e.w_size;do{if(i=e.window_size-e.lookahead-e.strstart,e.strstart>=f+(f-z)){for(c.arraySet(e.window,e.window,f,f,0),e.match_start-=f,e.strstart-=f,e.block_start-=f,t=r=e.hash_size;n=e.head[--t],e.head[t]=f<=n?n-f:0,--r;);for(t=r=f;n=e.prev[--t],e.prev[t]=f<=n?n-f:0,--r;);i+=f}if(0===e.strm.avail_in)break;if(a=e.strm,o=e.window,h=e.strstart+e.lookahead,u=i,l=void 0,l=a.avail_in,u=x)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x)if(n=u._tr_tally(e,e.strstart-e.match_start,e.match_length-x),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=x){for(e.match_length--;e.strstart++,e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x&&e.match_length<=e.prev_length){for(i=e.strstart+e.lookahead-x,n=u._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-x),e.lookahead-=e.prev_length-1,e.prev_length-=2;++e.strstart<=i&&(e.ins_h=(e.ins_h<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(j(e),0===e.lookahead&&t===l)return A;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,N(e,!1),0===e.strm.avail_out))return A;if(e.strstart-e.block_start>=e.w_size-z&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):(e.strstart>e.block_start&&(N(e,!1),e.strm.avail_out),A)}),new M(4,4,8,4,Z),new M(4,5,16,8,Z),new M(4,6,32,32,Z),new M(4,4,16,16,W),new M(8,16,32,32,W),new M(8,16,128,128,W),new M(8,32,128,256,W),new M(32,128,258,1024,W),new M(32,258,258,4096,W)],r.deflateInit=function(e,t){return Y(e,t,v,15,8,0)},r.deflateInit2=Y,r.deflateReset=K,r.deflateResetKeep=G,r.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?_:(e.state.gzhead=t,m):_},r.deflate=function(e,t){var r,n,i,s;if(!e||!e.state||5>8&255),U(n,n.gzhead.time>>16&255),U(n,n.gzhead.time>>24&255),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(U(n,255&n.gzhead.extra.length),U(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=p(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(U(n,0),U(n,0),U(n,0),U(n,0),U(n,0),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,3),n.status=E);else{var a=v+(n.w_bits-8<<4)<<8;a|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(a|=32),a+=31-a%31,n.status=E,P(n,a),0!==n.strstart&&(P(n,e.adler>>>16),P(n,65535&e.adler)),e.adler=1}if(69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending!==n.pending_buf_size));)U(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.status=103)}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&F(e),n.pending+2<=n.pending_buf_size&&(U(n,255&e.adler),U(n,e.adler>>8&255),e.adler=0,n.status=E)):n.status=E),0!==n.pending){if(F(e),0===e.avail_out)return n.last_flush=-1,m}else if(0===e.avail_in&&T(t)<=T(r)&&t!==f)return R(e,-5);if(666===n.status&&0!==e.avail_in)return R(e,-5);if(0!==e.avail_in||0!==n.lookahead||t!==l&&666!==n.status){var o=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(j(e),0===e.lookahead)){if(t===l)return A;break}if(e.match_length=0,r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):3===n.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=S){if(j(e),e.lookahead<=S&&t===l)return A;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=x&&0e.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=x?(r=u._tr_tally(e,1,e.match_length-x),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):h[n.level].func(n,t);if(o!==O&&o!==B||(n.status=666),o===A||o===O)return 0===e.avail_out&&(n.last_flush=-1),m;if(o===I&&(1===t?u._tr_align(n):5!==t&&(u._tr_stored_block(n,0,0,!1),3===t&&(D(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),F(e),0===e.avail_out))return n.last_flush=-1,m}return t!==f?m:n.wrap<=0?1:(2===n.wrap?(U(n,255&e.adler),U(n,e.adler>>8&255),U(n,e.adler>>16&255),U(n,e.adler>>24&255),U(n,255&e.total_in),U(n,e.total_in>>8&255),U(n,e.total_in>>16&255),U(n,e.total_in>>24&255)):(P(n,e.adler>>>16),P(n,65535&e.adler)),F(e),0=r.w_size&&(0===s&&(D(r.head),r.strstart=0,r.block_start=0,r.insert=0),u=new c.Buf8(r.w_size),c.arraySet(u,t,l-r.w_size,r.w_size,0),t=u,l=r.w_size),a=e.avail_in,o=e.next_in,h=e.input,e.avail_in=l,e.next_in=0,e.input=t,j(r);r.lookahead>=x;){for(n=r.strstart,i=r.lookahead-(x-1);r.ins_h=(r.ins_h<>>=y=v>>>24,p-=y,0===(y=v>>>16&255))C[s++]=65535&v;else{if(!(16&y)){if(0==(64&y)){v=m[(65535&v)+(d&(1<>>=y,p-=y),p<15&&(d+=z[n++]<>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(d&(1<>>=y,p-=y,(y=s-a)>3,d&=(1<<(p-=w<<3))-1,e.next_in=n,e.next_out=s,e.avail_in=n>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function s(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function a(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=P,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new I.Buf32(n),t.distcode=t.distdyn=new I.Buf32(i),t.sane=1,t.back=-1,N):U}function o(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,a(e)):U}function h(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15=s.wsize?(I.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(n<(i=s.wsize-s.wnext)&&(i=n),I.arraySet(s.window,t,r-n,i,s.wnext),(n-=i)?(I.arraySet(s.window,t,r-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=i,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){e.msg="incorrect header check",r.mode=30;break}if(8!=(15&u)){e.msg="unknown compression method",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg="invalid window size",r.mode=30;break}r.dmax=1<>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>>8&255,r.check=B(r.check,E,2,0)),l=u=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(d=r.length)&&(d=o),d&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,n,s,d,k)),512&r.flags&&(r.check=B(r.check,n,d,s)),o-=d,s+=d,r.length-=d),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break e;for(d=0;k=n[s+d++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&d>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break e;o--,u+=n[s++]<>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==t)break;u>>>=2,l-=2;break e;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=30}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break e;o--,u+=n[s++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(d=r.length){if(o>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286>>=3,l-=3}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=_,l-=_,r.lens[r.have++]=b;else{if(16===b){for(z=_+2;l>>=_,l-=_,0===r.have){e.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],d=3+(3&u),u>>>=2,l-=2}else if(17===b){for(z=_+3;l>>=_)),u>>>=3,l-=3}else{for(z=_+7;l>>=_)),u>>>=7,l-=7}if(r.have+d>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=30;break}for(;d--;)r.lens[r.have++]=k}}if(30===r.mode)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){e.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(6<=o&&258<=h){e.next_out=a,e.avail_out=h,e.next_in=s,e.avail_in=o,r.hold=u,r.bits=l,R(e,c),a=e.next_out,i=e.output,h=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){e.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,64&g){e.msg="invalid distance code",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===h)break e;if(d=c-h,r.offset>d){if((d=r.offset-d)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=30;break}p=d>r.wnext?(d-=r.wnext,r.wsize-d):r.wnext-d,d>r.length&&(d=r.length),m=r.window}else m=i,p=a-r.offset,d=r.length;for(hd?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=t[r+a[v]]}if(k>>7)]}function U(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function P(e,t,r){e.bi_valid>d-r?(e.bi_buf|=t<>d-e.bi_valid,e.bi_valid+=r-d):(e.bi_buf|=t<>>=1,r<<=1,0<--t;);return r>>>1}function Z(e,t,r){var n,i,s=new Array(g+1),a=0;for(n=1;n<=g;n++)s[n]=a=a+r[n-1]<<1;for(i=0;i<=t;i++){var o=e[2*i+1];0!==o&&(e[2*i]=j(s[o]++,o))}}function W(e){var t;for(t=0;t>1;1<=r;r--)G(e,s,r);for(i=h;r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],G(e,s,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,s[2*i]=s[2*r]+s[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,s[2*r+1]=s[2*n+1]=i,e.heap[1]=i++,G(e,s,1),2<=e.heap_len;);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,s,a,o,h=t.dyn_tree,u=t.max_code,l=t.stat_desc.static_tree,f=t.stat_desc.has_stree,c=t.stat_desc.extra_bits,d=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(s=0;s<=g;s++)e.bl_count[s]=0;for(h[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<_;r++)p<(s=h[2*h[2*(n=e.heap[r])+1]+1]+1)&&(s=p,m++),h[2*n+1]=s,u>=7;n>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return o;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return h;for(t=32;t>>3,(s=e.static_len+3+7>>>3)<=i&&(i=s)):i=s=r+5,r+4<=i&&-1!==t?J(e,t,r,n):4===e.strategy||s===i?(P(e,2+(n?1:0),3),K(e,z,C)):(P(e,4+(n?1:0),3),function(e,t,r,n){var i;for(P(e,t-257,5),P(e,r-1,5),P(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(A[r]+u+1)]++,e.dyn_dtree[2*N(t)]++),e.last_lit===e.lit_bufsize-1},r._tr_align=function(e){P(e,2,3),L(e,m,z),function(e){16===e.bi_valid?(U(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):8<=e.bi_valid&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)}(e)}},{"../utils/common":41}],53:[function(e,t,r){"use strict";t.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],54:[function(e,t,r){(function(e){!function(r,n){"use strict";if(!r.setImmediate){var i,s,t,a,o=1,h={},u=!1,l=r.document,e=Object.getPrototypeOf&&Object.getPrototypeOf(r);e=e&&e.setTimeout?e:r,i="[object process]"==={}.toString.call(r.process)?function(e){process.nextTick(function(){c(e)})}:function(){if(r.postMessage&&!r.importScripts){var e=!0,t=r.onmessage;return r.onmessage=function(){e=!1},r.postMessage("","*"),r.onmessage=t,e}}()?(a="setImmediate$"+Math.random()+"$",r.addEventListener?r.addEventListener("message",d,!1):r.attachEvent("onmessage",d),function(e){r.postMessage(a+e,"*")}):r.MessageChannel?((t=new MessageChannel).port1.onmessage=function(e){c(e.data)},function(e){t.port2.postMessage(e)}):l&&"onreadystatechange"in l.createElement("script")?(s=l.documentElement,function(e){var t=l.createElement("script");t.onreadystatechange=function(){c(e),t.onreadystatechange=null,s.removeChild(t),t=null},s.appendChild(t)}):function(e){setTimeout(c,0,e)},e.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),r=0;r orange -> purple) */ + --cn-teal-1: #A0BABF; + --cn-teal-2: #B8D6D1; + --cn-green: #A8D5BA; + --cn-lime: #F5EEAB; + + --cn-orange-1:#F3C683; + --cn-orange-2:#E87E4D; + --cn-red: #CD463E; + + --cn-purple-1:#7B8FA3; + --cn-purple-2:#4B6478; + --cn-purple-3:#3B5068; + + /* App neutrals */ + --bg: #F7F8FA; + --surface: #FFFFFF; + --surface-2: #F2F4F7; + --surface-3: #E9EEF3; + + --text: #0F172A; + --muted: #475569; + --muted-2: #556275; + + --border: rgba(15, 23, 42, 0.12); + --border-2: rgba(15, 23, 42, 0.18); + + --shadow: 0 10px 30px rgba(2, 6, 23, 0.08); + --shadow-sm: 0 2px 10px rgba(2, 6, 23, 0.06); + + /* Primary brand */ + --primary: var(--cn-purple-3); + --primary-2: var(--cn-purple-2); + + --focus: rgba(160, 186, 191, 0.7); + + /* Layout sizing (responsive without rewriting layout) */ + --palette-w: clamp(190px, 20vw, 260px); + --sidebar-w: clamp(260px, 28vw, 360px); + --gutter: 12px; + + --radius: 5px; + --radius-sm: 5px; + + /* Type scale */ + --text-xs: 11px; + --text-sm: 12px; + --text-base: 14px; + --text-md: 16px; + --text-lg: 20px; + --text-xl: 26px; + + /* Spacing scale */ + --space-1: 4px; + --space-2: 8px; + --space-3: 12px; + --space-4: 16px; + --space-5: 24px; + --space-6: 32px; + + /* Layout heights */ + --navbar-h: 80px; + --tabs-h: 28px; + + /* Accent & selection */ + accent-color: var(--cn-purple-2); + + /* Transition timing */ + --ease: cubic-bezier(0.22, 0.61, 0.36, 1); + --duration: 0.18s; +} + +/* ---------- Base ---------- */ +*, +*::before, +*::after{ + box-sizing: border-box; +} + +html, body{ + width: 100%; + height: 100%; +} + +body{ + font: var(--text-base)/1.4 "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif !important; + color: var(--text); + background: var(--bg); + /* override legacy textured background */ + background-image: none !important; +} + +a{ + color: var(--primary); + text-decoration: none; +} +a:hover{ + text-decoration: underline; +} + +:focus{ + outline: none; +} +:focus-visible{ + outline: 2px solid var(--focus); + outline-offset: 2px; +} + +/* ---------- Drop target overlay ---------- */ +#dropTarget{ + position: absolute; + top: 0; bottom: 0; + left: 0; right: 0; + background: rgba(15, 23, 42, 0.45); + display: none; + width: 100%; + height: 100%; + z-index: 9999; + backdrop-filter: blur(2px); +} +#dropTarget div{ + display: table-cell; + vertical-align: middle; + text-align: center; + font-size: clamp(22px, 3vw, 40px); + color: #fff; + font-weight: 600; +} + +/* ---------- Header / Navbar (Bootstrap legacy-friendly) ---------- */ +/* #header background intentionally not overridden — keeps the original NoiseModelling logo from wps-gui.css */ + +div.btn-group, a.btn{ + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +/* legacy */ +a.brand{ line-height: 24px; } +a.brand span{ + vertical-align: middle; + font-size: 22px !important; + color: #fff; + font-weight: 600; + letter-spacing: 0.2px; +} + +.navbar{ + height: var(--navbar-h); + border: 0; +} +.navbar.navbar-inverse{ + background-color: var(--primary); + background-image: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(0,0,0,0.06)); + box-shadow: var(--shadow-sm); +} +.navbar-fixed-top{ + position: absolute !important; + z-index: 100 !important; +} +.navbar-inner > .container-fluid{ + padding-right: 10px; + padding-left: 20px; + padding-top: 0; + padding-bottom: 0; + position: relative; + display: flex; + align-items: center; + height: var(--navbar-h); +} +.navbar-inner > .container-fluid > .btn-group{ + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; +} +.navbar-inner > .container-fluid > .btn-group.pull-right{ + margin-left: auto; + float: none; +} + +/* Buttons (works with legacy Bootstrap class names) */ +.btn{ + border-radius: 5px !important; + border: 1px solid rgba(255,255,255,0.18); + background: rgba(255,255,255,0.10); + color: #fff; + box-shadow: none; + transition: transform .05s ease, background .15s ease, border-color .15s ease; +} +.btn:hover{ + background: rgba(255,255,255,0.16); + border-color: rgba(255,255,255,0.28); +} +.btn:active{ + transform: translateY(1px); +} +.btn-primary{ + background: rgba(255,255,255,0.16); +} +.btn-danger{ + background: rgba(205, 70, 62, 0.20); + border-color: rgba(205, 70, 62, 0.45); +} +.btn-success{ + background: rgba(160, 186, 191, 0.20); + border-color: rgba(160, 186, 191, 0.45); +} + +/* Dropdown menu polish */ +.dropdown-menu{ + border-radius: 5px !important; + border: 1px solid var(--border) !important; + box-shadow: var(--shadow) !important; + padding: 6px !important; + background: var(--surface) !important; +} +.dropdown-menu > li > a{ + border-radius: 5px; + padding: var(--space-2) var(--space-3); + transition: background var(--duration) var(--ease); +} +.dropdown-menu > li > a:hover{ + background: var(--surface-2); +} + +/* ---------- Layout ---------- */ + +#main-container{ + position: absolute; + top: 85px; + left: 0; + bottom: 0; + right: 0; + overflow: hidden; +} + +#palette{ + background: var(--surface); + width: var(--palette-w); + text-align: center; + + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + position: absolute; + top: var(--gutter); + left: var(--gutter); + bottom: var(--gutter); + + border: 1px solid var(--border); + border-radius: var(--radius); + box-shadow: var(--shadow-sm); + overflow: hidden; +} + +#sidebar{ + background: var(--surface); + width: var(--sidebar-w); + position: absolute; + right: var(--gutter); + top: var(--gutter); + bottom: var(--gutter); + + border: 1px solid var(--border); + border-radius: var(--radius); + box-shadow: var(--shadow-sm); + overflow: hidden; +} +#sidebar.closing{ + background: var(--surface-2); + border-color: var(--cn-red); + border-style: dashed; +} + +#workspace{ + position: absolute; + margin: 0; + top: var(--gutter); + left: calc(var(--palette-w) + (var(--gutter) * 2)); + bottom: var(--gutter); + right: calc(var(--sidebar-w) + (var(--gutter) * 2)); + overflow: hidden; + + border: 1px solid var(--border); + border-radius: var(--radius); +} + +/* (borders already set on individual rules above) */ + +/* workspace main canvas container */ +#chart{ + overflow: auto; + background: var(--surface-3); + position: absolute; + bottom: 0px; + top: 30px; + left: 0px; + right: 0px; + border-radius: 0; +} + +#chart-zoom-controls{ + position: absolute; + bottom: 30px; + right: calc(var(--sidebar-w) + (var(--gutter) * 2) + 20px); + color: var(--muted); + z-index: 10; +} +#chart-zoom-controls .btn{ + color: var(--text) !important; + background: var(--surface) !important; + border: 1px solid var(--border) !important; + box-shadow: var(--shadow-sm); + border-radius: var(--radius-sm) !important; + padding: 4px 8px; + font-size: var(--text-sm); +} +#chart-zoom-controls .btn:hover{ + background: var(--surface-2) !important; + border-color: var(--border-2) !important; +} + +#sidebar-separator{ + width: 15px; + background: url("grip.png") no-repeat 50% 50%; + position: absolute; + right: calc(var(--sidebar-w) + var(--gutter) + 1px); + top: var(--gutter); + bottom: var(--gutter); + cursor: col-resize; +} + +/* toolbar */ +#workspace-toolbar{ + display: none; + position: absolute; + top: 30px; + left: 0; + right: 18px; + padding: 8px 10px; + background: rgba(255,255,255,0.75); + border-bottom: 1px solid var(--border); + backdrop-filter: blur(6px); +} + +/* Palette scroll */ +.palette-scroll{ + display: none; + position: absolute; + height: calc(100% - 44px); + top: 44px; + left: 0; + right: 0; + padding: 8px; + overflow-y: auto; +} +.palette-spinner{ + position: absolute; + left: 0; right: 0; + top: 44px; + padding: 8px; +} + +/* Sidebar internal scroll */ +#sidebar .sidebar-scroll{ + position: absolute; + top: 44px; + bottom: 0; + left: 0; + right: 0; + overflow: auto; + padding: 10px 12px; +} + +/* Headers inside palette/sidebar */ +.palette-header, .palette_header, .sidebar_header{ + height: 44px; + line-height: 44px; + text-align: left; + padding: 0 12px; + font-weight: 700; + color: var(--text); + background: linear-gradient(180deg, rgba(255,255,255,0.75), rgba(255,255,255,0.55)); + border-bottom: 1px solid var(--border); +} + +/* Sidebar close button (if present) */ +.sidebar_close{ + position: absolute; + top: 9px; + right: 10px; + width: 28px; + height: 28px; + border-radius: 5px; + border: 1px solid var(--border); + background: var(--surface); + color: var(--muted); + line-height: 26px; + text-align: center; + cursor: pointer; + transition: background var(--duration) var(--ease), + color var(--duration) var(--ease); +} +.sidebar_close:hover{ + background: var(--surface-2); + color: var(--text); +} + +/* Sidebar closed tweaks (legacy selectors preserved) */ +.sidebar-closed > #sidebar{ display:none !important; } +.sidebar-closed > #sidebar-separator{ right: 0px !important; } +.sidebar-closed > #workspace{ right: 15px !important; } +.sidebar-closed > #chart-zoom-controls{ right: 35px !important; } +.sidebar-closed > #workspace-toolbar{ right: 35px !important; } + +/* ---------- Palette nodes ---------- */ +.palette_node{ + cursor: move; + font-size: var(--text-sm); + background: var(--surface); + margin: 4px auto; + height: 32px; + border-radius: 5px; + border: 1px solid var(--border); + box-shadow: 0 1px 0 rgba(2, 6, 23, 0.03); + background-position: 8px 50%; + background-repeat: no-repeat; + width: calc(var(--palette-w) - 32px); + max-width: 220px; + background-size: 18px 18px; + position: relative; + display: flex; + align-items: center; + justify-content: flex-start; + text-align: left; + padding-left: 10px; + padding-right: 10px; + color: var(--text); + transition: border-color var(--duration) var(--ease), + box-shadow var(--duration) var(--ease), + background var(--duration) var(--ease); +} +.palette_node:hover{ + border-color: rgba(51, 65, 85, 0.30); + box-shadow: 0 6px 18px rgba(2, 6, 23, 0.08); + background-color: #fff; +} +.palette_port{ + position: absolute; + top: 12px; + left: -6px; + background: var(--surface); + border-radius: 5px; + width: 12px; + height: 12px; + border: 1px solid rgba(51, 65, 85, 0.20); + box-shadow: 0 1px 0 rgba(2, 6, 23, 0.05); +} +.palette_port_output{ + left: auto; + right: -6px; +} +.palette_node:hover .palette_port{ + border-color: rgba(160, 186, 191, 0.65); +} + +/* ---------- Lasso ---------- */ +.lasso{ + background-color: rgba(15, 23, 42, 0.45); + color: #fff; + outline: none; + border-radius: 5px; +} + +/* ---------- Labels ---------- */ +.node_label{ + font-size: var(--text-sm); + fill: rgba(15, 23, 42, 0.92); +} +.node_label_italic{ font-style: italic; } +.node_label_unknown{ + font-style: italic; + fill: var(--cn-red) !important; +} +.node_label_white{ fill: var(--text) !important; } + +/* ---------- Graph nodes (SVG) ---------- */ +.node{ + stroke: rgba(71, 85, 105, 0.35); + cursor: move; + stroke-width: 2; + filter: drop-shadow(0 2px 6px rgba(2,6,23,0.10)); + transition: stroke var(--duration) var(--ease), + stroke-width var(--duration) var(--ease); +} + +.node_input{ + fill: var(--cn-lime); +} +.node_input.node_required{ + fill: var(--cn-orange-1); +} +.node_process{ + fill: var(--cn-teal-2); +} +.node_output{ + fill: var(--cn-green); +} + +/* state */ +.node_incomplete{ + stroke-width: 2; + stroke-dasharray: 8,4; + stroke: rgba(100, 116, 139, 0.55); +} +.node_selected{ + stroke: rgba(51, 65, 85, 0.85); + stroke-width: 3; +} +.node_hovered{ + stroke: rgba(232, 126, 77, 0.85); +} +.node_highlighted{ + stroke: rgba(232, 126, 77, 0.95); + stroke-width: 3; + stroke-dasharray: 10, 4; +} + +.node_unknown{ + stroke-width: 1; + stroke: rgba(15, 23, 42, 0.25); + fill: rgba(100, 116, 139, 0.35); + cursor: pointer; +} + +.node_tools{ + fill: rgba(255,255,255,0.7); + stroke: rgba(15, 23, 42, 0.18); + cursor: pointer; + stroke-width: 1; +} +.node_tools_hovered{ + stroke: rgba(232, 126, 77, 0.85); + fill: rgba(255,255,255,0.95); +} + +.node_button{ + fill: inherit; +} + +.port{ + fill: #fff; + stroke: rgba(71, 85, 105, 0.50); + stroke-width: 1.5; + cursor: crosshair; +} +.port_hovered{ + stroke: var(--cn-orange-2); + stroke-width: 2.5; + fill: rgba(232, 126, 77, 0.40); +} + +/* errors / badges */ +.node_error{ + stroke: rgba(205, 70, 62, 0.95); + stroke-width: 2.5; + fill: var(--cn-orange-2); +} +.node_required.node_invalid{ + stroke: rgba(205, 70, 62, 0.95); +} + +.node_badge{ + stroke: rgba(51, 65, 85, 0.35); + stroke-width: 1; + fill: rgba(160, 186, 191, 0.65); +} +.node_badge_label{ + stroke-width: 0; + fill: rgba(255,255,255,0.92); + font-size: 11px; + pointer-events: none; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +/* ---------- Links ---------- */ +.link_line{ + stroke: rgba(71, 85, 105, 0.55); + stroke-width: 3; + fill: none; + pointer-events: none; +} +.link_outline{ + stroke: rgba(255,255,255,0.9); + stroke-width: 6; + cursor: crosshair; + fill: none; +} +.link_background{ + stroke: #fff; + opacity: 0; + stroke-width: 30; + cursor: crosshair; + fill: none; +} + +g.link_selected path.link_line{ + stroke: rgba(232, 126, 77, 0.95); +} +g.link_unknown path.link_line{ + stroke: rgba(100, 116, 139, 0.65); + stroke-dasharray: 6,5; +} + +/* ---------- Forms / inputs ---------- */ +input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), +select, textarea{ + border-radius: 5px; + border: 1px solid var(--border); + padding: var(--space-2) var(--space-3); + background: #fff; + color: var(--text); + transition: border-color var(--duration) var(--ease), + box-shadow var(--duration) var(--ease); +} +input:focus, select:focus, textarea:focus{ + border-color: rgba(51, 65, 85, 0.40); + box-shadow: 0 0 0 3px rgba(160, 186, 191, 0.35); +} + +input.input-append-left{ + width: 95% !important; + margin-left: 2%; +} + +/* ---------- Palette search ---------- */ +#palette-search input{ + width: calc(100% - 30px); + border: 1px solid var(--border); + border-radius: var(--radius-sm); + padding: 4px 8px; + font-size: 12px; + margin-left: 22px; +} +#palette-search input:focus{ + border-color: rgba(51, 65, 85, 0.40); + box-shadow: 0 0 0 3px rgba(160, 186, 191, 0.35); +} +#palette-search i.glyphicon-search{ + position: absolute; + top: 12px; + left: 14px; + color: var(--muted); + font-size: 12px; +} +#palette-search i.glyphicon-remove{ + color: var(--muted); +} +#palette-search-input::-ms-clear{ + display: none; +} + +/* ---------- Sidebar content ---------- */ +#sidebar-content{ + font-size: 1em; + position: absolute; + top: 35px; + left: 0; + right: 0; + bottom: 0; + overflow: auto; + padding: 8px; +} +#sidebar-content p{ + font-size: 0.9em; + padding: 4px; +} +#sidebar-content select{ + width: 100%; + font-size: 12px; + margin: 4px 0; +} + +/* ---------- Tabs ---------- */ +#workspace-tabs{ + margin-right: 28px; +} +#workspace-add-tab{ + position: absolute; + top: 0; + right: 0; + height: 28px; + width: 28px; + border-bottom: 1px solid var(--border); +} +#btn-workspace-add-tab{ + display: inline-block; + width: 100%; + background: var(--surface-2); + height: 100%; + line-height: 28px; + text-align: center; +} + +ul.red-ui-tabs{ + list-style-type: none; + padding: 5px 2px 0 5px; + margin: 0; + display: block; + height: var(--tabs-h); + border-bottom: 1px solid var(--border); + background: var(--surface-2); + -webkit-user-select: none; + user-select: none; +} +ul.red-ui-tabs li{ + border-top-left-radius: var(--radius-sm); + border-top-right-radius: var(--radius-sm); + display: inline-block; + border-left: 1px solid var(--border); + border-top: 1px solid var(--border); + border-right: 1px solid var(--border); + border-bottom: 1px solid var(--border); + background: var(--surface-2); + margin: 0 5px 0 0; + height: 23px; + line-height: 17px; + max-width: 150px; + width: 14%; + overflow: hidden; + white-space: nowrap; + position: relative; +} +ul.red-ui-tabs li a.red-ui-tab-label{ + display: block; + padding: 3px 16px; + color: var(--muted); +} +ul.red-ui-tabs li a.red-ui-tab-close{ + background: rgba(255,255,255,0.8); + position: absolute; + right: 2px; + top: 2px; + display: block; + width: 20px; + height: 20px; + line-height: 20px; + text-align: center; + padding: 0; + border-radius: 5px; +} +ul.red-ui-tabs li a.red-ui-tab-close:hover{ + background: var(--surface-3) !important; +} +ul.red-ui-tabs li a:hover{ + text-decoration: none; + background: var(--surface-2); +} +ul.red-ui-tabs li.active{ + background: var(--surface); + border-bottom: 1px solid var(--surface); +} +ul.red-ui-tabs li.active a{ + color: var(--text); +} +ul.red-ui-tabs li.active a.red-ui-tab-close{ + background: rgba(255,255,255,0.8); +} +ul.red-ui-tabs li.active a.red-ui-tab-label:hover{ + background: var(--surface); +} +ul.red-ui-tabs li.red-ui-add-tab{ + width: 25px; + border-top-right-radius: 5px; + line-height: 22px; +} +ul.red-ui-tabs li.red-ui-add-tab a{ + padding: 2px 4px; +} + +/* ---------- Config list ---------- */ +ul.tab-config-list{ + list-style-type: none; + padding: 3px; + margin: 0; + user-select: none; +} +ul.tab-config-list li{ + max-width: 400px; + font-size: 13px; + background: var(--surface-2); + margin: 10px auto; + border-radius: var(--radius-sm); + border: 1px solid var(--border); + padding: 3px 8px; +} +div.tab-config-list-entry{ + position: relative; + margin: 4px 0; + padding: 8px 4px 8px 10px; + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--radius-sm); + cursor: pointer; +} +div.tab-config-list-entry:hover{ + background: var(--surface-2); +} +div.tab-config-list-users{ + position: absolute; + right: 3px; + top: 3px; + bottom: 3px; + line-height: 27px; + font-size: 11px; + background: var(--surface-2); + float: right; + border: 1px solid var(--border); + border-radius: var(--radius-sm); + padding: 1px 5px; +} + +/* ---------- Misc UI ---------- */ +i.spinner{ + display: inline-block; + width: 14px; + height: 14px; + line-height: 14px; + vertical-align: text-top; + background: url(spin.svg) no-repeat 50% 50%; + background-size: contain; +} +.wpsbuilder{ + margin-right: 20px; +} +.x-hidden{ + display: none; +} +.btn-clear-div{ + margin-left: 10px; +} +.input-map{ + margin-left: 2%; + width: 95%; + height: 200px; + clear: both; +} +.output-map{ + margin-top: 2%; + margin-left: 2%; + width: 95%; + height: 85%; + clear: both; +} +#tab-inputs, #tab-results{ + height: 100%; +} +#workspace-content, #tab-xml{ + height: 100%; +} +#tab-xml pre{ + height: 90%; + overflow-y: auto; + background-color: var(--surface-2); +} +#btn-download{ + margin: 5px; +} +#progress-indicator{ + position: absolute; + right: 25px; + top: 35px; +} +.btn-group-map{ + margin: 5px; +} +.wpsgui.form-control[readonly]{ + cursor: inherit; +} +#btn-zoom-zero, #btn-zoom-in, #btn-zoom-out{ + font-size: 12px; +} +.wpsgui.dropdown-menu{ + min-width: 275px; +} +.save-success, .open-success{ + display: none; + margin-left: 20px; + color: var(--cn-green); + font-size: 16px; +} + +#btn-run-process{ + display: none; + margin-top: 0px; + background: linear-gradient(135deg, #4B6478, #3B5068) !important; + color: #fff !important; + border: 2px solid rgba(255,255,255,0.22) !important; + font-weight: 700; + font-size: var(--text-md); + padding: 8px 22px; + letter-spacing: 0.3px; + box-shadow: 0 4px 16px rgba(59, 80, 104, 0.35); + transition: transform var(--duration) var(--ease), + box-shadow var(--duration) var(--ease), + background var(--duration) var(--ease); +} +#btn-run-process:hover{ + background: linear-gradient(135deg, #5A7A92, #4B6478) !important; + box-shadow: 0 6px 24px rgba(59, 80, 104, 0.50); + transform: translateY(-1px); +} +#btn-run-process:active{ + transform: translateY(1px); + box-shadow: var(--shadow-sm); +} +#btn-run-process i{ + margin-right: 4px; +} + +.navbar-fixed-top, .navbar-fixed-bottom{ + z-index: 1000; +} + +.popover-title{ display: none; } + +.ui-autocomplete{ + max-height: 250px; + overflow-x: hidden; + overflow-y: scroll; +} + +.help-key{ + border: 1px solid var(--border); + padding: 4px; + border-radius: var(--radius-sm); + background: var(--surface-2); + font-family: Courier, monospace; + box-shadow: var(--shadow-sm); +} + +#helpcontent{ + padding: 20px; + border: 1px solid var(--border); + border-radius: var(--radius); + background: var(--surface); +} +#helpnavigation{ + overflow: hidden; + border: 1px solid var(--border); + border-radius: var(--radius); + background: var(--surface); +} +#helpnavigation li a{ + font-size: 1.2em; + padding: 10px; + border-bottom: 1px solid var(--border); +} + +.group-box{ + stroke-width: 1px; + stroke: var(--muted); + fill: rgba(208, 211, 238, 0.1); + stroke-dasharray: 3 3; +} +.group-box-active{ + fill: var(--surface); + stroke: var(--cn-orange-2); +} +.group_label{ + stroke-width: 0; + fill: var(--muted); + font-size: 11px; + pointer-events: none; + user-select: none; +} + +/* ---------- Drag lines (spline connections) ---------- */ +.drag_line{ + stroke: var(--cn-orange-2); + stroke-width: 5; + fill: none; + pointer-events: none; +} +.drag_line_hidden{ + stroke: var(--cn-orange-2); + stroke-width: 0; + pointer-events: none; + fill: none; +} + +/* ---------- Tool arrow ---------- */ +.tool_arrow{ + stroke-width: 1; + stroke: var(--muted); + fill: var(--muted); + cursor: pointer; +} + +/* ---------- Function label ---------- */ +.function_label{ + font-size: 12px; + fill: var(--text); +} + +/* ---------- Palette categories ---------- */ +.palette-category{ + border-bottom: 1px solid var(--border); +} +.palette-content{ + padding: 4px 0; +} +.palette-header{ + cursor: pointer; + padding: var(--space-2) var(--space-3); + font-weight: 600; + font-size: var(--text-sm); + color: var(--text); + background: var(--surface-2); + border-bottom: 1px solid var(--border); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: flex; + align-items: center; + gap: 6px; +} +.palette-header i{ + transition: transform 0.2s var(--ease); + transform: rotate(-90deg); /* collapsed → points right */ + display: inline-block; +} +.palette-header i.expanded{ + transform: rotate(0deg); /* expanded → points down */ +} +.palette-header span{ + margin-left: 4px; +} +.palette_label{ + font-size: var(--text-sm); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +/* ---------- Notifications ---------- */ +.notification{ + position: absolute; + top: 2px; + right: 2px; + width: 14px; + height: 14px; + background: var(--cn-red); + line-height: 14px; + text-align: center; + font-size: 9px; + border-radius: 50%; + color: #fff; +} +#notifications{ + position: fixed; + top: auto; + left: auto; + bottom: 0; + right: 0; + margin-left: 0; + z-index: 10000; + width: 500px; +} +#notifications .alert{ + margin: 6px; + box-shadow: var(--shadow-sm); + transition: opacity var(--duration) var(--ease), + transform var(--duration) var(--ease); +} + +/* ---------- Shade overlay ---------- */ +#shade{ + position: absolute; + top: 0; left: 0; right: 0; bottom: 0; + background: rgba(15, 23, 42, 0.45); + z-index: 5000; +} + +/* ---------- Forms ---------- */ +.form-row{ + clear: both; + margin-bottom: 8px; +} +div.form-row-abstract{ + padding: 8px 10px; + font-style: italic; + color: var(--muted); +} +.form-row label{ + display: inline-block; + width: 100px; + text-align: right; + padding-right: 10px; + vertical-align: top; + margin-top: 4px; +} +.form-row input, .form-control{ + width: 70%; + border-radius: 5px !important; + border: 1px solid var(--border) !important; + background: #fff !important; + color: var(--text) !important; +} +button.input-append-right{ + margin-left: -4px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.form-horizontal input[type='checkbox']{ + width: auto; +} +.form-tips{ + background: var(--surface-2); + padding: 8px; + border: 1px solid var(--border); + border-radius: var(--radius-sm); + font-size: 12px; + color: var(--muted); +} +.form-tips code{ + border: none; + color: var(--cn-red); +} + +/* ---------- Node info ---------- */ +table.node-info{ + margin: 10px; +} +table.node-info tr{ + border-bottom: 1px solid var(--border); +} +table.node-info tr.blank{ + border-bottom: none; +} +table.node-info tr.blank td{ + padding: 12px 0 4px; + font-weight: bold; +} +table.node-info td:first-child{ + vertical-align: top; + width: 90px; + padding: 4px; + color: var(--muted); +} +table.node-info td:last-child{ + padding: 4px; +} +div.node-info{ + padding: 4px 8px; +} + +/* ---------- Input error ---------- */ +.input-error{ + border-color: var(--cn-red) !important; + box-shadow: 0 0 0 3px rgba(205, 70, 62, 0.25) !important; +} + +/* ---------- Misc missing ---------- */ +.hidden{ + display: none !important; +} +#node-help{ + width: 700px; +} +#node-help * td{ + padding: 0.8em 0.5em; +} +#node-help * tr > td:first-child+td+td{ + padding-left: 5em; +} +#node-select-library{ + overflow: hidden; +} +#node-select-library ul{ + list-style: none; + padding: 0; + margin: 2px; +} +#node-select-library li{ + cursor: pointer; +} +#node-select-library li.list-selected{ + background: var(--surface-2); +} +#node-select-library li.list-hover{ + background: var(--cn-lime); +} +.node-text-editor{ + border: 1px solid var(--border); + border-radius: var(--radius-sm); + overflow: hidden; +} +.leftButton{ + margin-right: 200px !important; +} + +/* Sidebar content details */ +#sidebar-content #add-geoms{ + width: 100%; +} +#sidebar-content ul.nav-pills.text-or-map{ + margin-bottom: 8px; +} +#sidebar-content ul.nav-pills.text-or-map > li > a{ + border-radius: var(--radius-sm); + padding: 4px 10px; + font-size: 12px; +} +#sidebar-content ul.nav-pills.text-or-map > li.active > a, +#sidebar-content ul.nav-pills.text-or-map > li.active > a:hover, +#sidebar-content ul.nav-pills.text-or-map > li.active > a:focus{ + background-color: var(--primary); + color: #fff; +} + +.ol-attribution img{ + max-width: 2em; +} + +/* ---------- Small responsiveness layer (no HTML changes) ---------- */ +@media (max-width: 900px){ + :root{ + --palette-w: clamp(170px, 26vw, 220px); + } + .navbar{ + height: 72px; + } + #main-container{ + top: 77px; + } +} + +@media (max-width: 720px){ + #palette{ + width: min(92vw, 360px); + left: 50%; + transform: translateX(-50%); + top: var(--gutter); + bottom: auto; + height: 50vh; + z-index: 200; + } + #workspace{ + left: var(--gutter); + right: var(--gutter); + } +} + +/* ---------- Scrollbar theming ---------- */ +::-webkit-scrollbar{ + width: 8px; + height: 8px; +} +::-webkit-scrollbar-track{ + background: var(--surface-2); + border-radius: var(--radius-sm); +} +::-webkit-scrollbar-thumb{ + background: var(--cn-teal-1); + border-radius: var(--radius-sm); + border: 2px solid var(--surface-2); +} +::-webkit-scrollbar-thumb:hover{ + background: var(--cn-purple-1); +} +/* Firefox scrollbar */ +*{ + scrollbar-width: thin; + scrollbar-color: var(--cn-teal-1) var(--surface-2); +} + +/* ---------- Selection / Accent ---------- */ +::selection{ + background: rgba(160, 186, 191, 0.40); + color: var(--text); +} + +/* ---------- Canvas dot-grid ---------- */ +#chart{ + background-image: radial-gradient(circle, var(--border) 1px, transparent 1px) !important; + background-size: 20px 20px !important; +} + +/* ---------- Dialog / Modal overlay ---------- */ +.ui-widget-overlay{ + background: rgba(15, 23, 42, 0.55) !important; + backdrop-filter: blur(3px); +} +.ui-dialog{ + border-radius: var(--radius) !important; + border: 1px solid var(--border) !important; + box-shadow: var(--shadow) !important; + background: var(--surface) !important; + padding: 0 !important; +} +.ui-dialog .ui-dialog-titlebar{ + background: var(--surface-2) !important; + border-bottom: 1px solid var(--border) !important; + border-radius: var(--radius) var(--radius) 0 0 !important; + padding: var(--space-3) var(--space-4) !important; + font-weight: 600; +} +.ui-dialog .ui-dialog-content{ + padding: var(--space-4) !important; + font-size: var(--text-base); + color: var(--text); +} +.ui-dialog .ui-dialog-buttonpane{ + background: var(--surface-2) !important; + border-top: 1px solid var(--border) !important; + border-radius: 0 0 var(--radius) var(--radius) !important; + padding: var(--space-3) var(--space-4) !important; +} +.ui-dialog .ui-dialog-buttonpane button{ + border-radius: var(--radius-sm) !important; + padding: var(--space-2) var(--space-4) !important; + font-size: var(--text-sm); +} + +/* ---------- Button disabled state ---------- */ +.btn:disabled, .btn.disabled{ + opacity: 0.45; + cursor: not-allowed; + pointer-events: none; +} + +/* ---------- prefers-reduced-motion ---------- */ +@media (prefers-reduced-motion: reduce){ + *, *::before, *::after{ + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +} + +/* ---------- End ---------- */ \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/themes/coloringnoise/wpsbuilder-header.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/themes/coloringnoise/wpsbuilder-header.png new file mode 100644 index 000000000..a0588b6fa Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/themes/coloringnoise/wpsbuilder-header.png differ diff --git a/wpsbuilder/dist/wps-gui.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wps-gui.css similarity index 98% rename from wpsbuilder/dist/wps-gui.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wps-gui.css index baf7f41e6..0b7a4406f 100644 --- a/wpsbuilder/dist/wps-gui.css +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wps-gui.css @@ -193,11 +193,12 @@ body { font-size: 40px; color: #fff; } + #header { - background: url("wpsbuilder-header.png"); + background: url("wpsbuilder-header.png") no-repeat; display: inline-block; - height: 60px; - width: 420px; + height: 58px; + width: 433px; margin-right: 20px; } @@ -231,14 +232,23 @@ a.brand span { .navbar-inner > .container-fluid { padding-right: 10px; padding-left: 20px; - padding-top: 8px; + padding-top: 0; + padding-bottom: 0; position: relative; - + display: flex; + align-items: center; + height: 80px; } .navbar-inner > .container-fluid > .btn-group { - margin-top: 12px; - margin-bottom: 65px; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; +} + +.navbar-inner > .container-fluid > .btn-group.pull-right { + margin-left: auto; + float: none; } #workspace { @@ -306,7 +316,6 @@ a.brand span { overflow: hidden; background: #f3f3f3; text-align: center; - height: 35px; padding: 6px; border-top: 1px solid #999; box-sizing:border-box; @@ -325,7 +334,7 @@ a.brand span { /* bartvde change to glyphicon */ #palette-search i.glyphicon-remove { position: absolute; - right: 10px; + right: 14px; top: 12px; } diff --git a/wpsbuilder/dist/wps-gui.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wps-gui.js similarity index 98% rename from wpsbuilder/dist/wps-gui.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wps-gui.js index 3846260b4..d53a2f0bb 100644 --- a/wpsbuilder/dist/wps-gui.js +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wps-gui.js @@ -61117,7 +61117,7 @@ wps.process.prototype.execute = function(options) { xmlhttp.onload = function() { if (this.status !== 200) { if (options.failure) { - options.failure.call(options.scope, 'HTTP status error on WPS:Execute request: ' + this.statusText, body); + options.failure.call(options.scope, 'HTTP status error on WPS:Execute request: ' + this.responseText, body); return; } } @@ -61199,6 +61199,7 @@ wps.process.prototype.parseDescription = function(description) { var server = this.client.servers[this.server]; this.description = this.client.unmarshaller.unmarshalString( server.processDescription[this.identifier]).value.processDescription[0]; + }; wps.process.prototype.setInputData = function(input, data) { @@ -61716,13 +61717,13 @@ var extent = [-180, -90, 180, 90]; // }) //}); wps.backgroundLayer = new ol.layer.Tile({ - source: new ol.source.TileWMS({ - url: 'https://maps.heigit.org/osm-wms/service?', - params: { - 'LAYERS': 'osm_auto:all' - } - }) - }); + source: new ol.source.TileWMS({ + url: 'https://ows.terrestris.de/osm/service?', + params: { + 'LAYERS': 'OSM-WMS' + } + }) +}); // apparently axis order is not what we expect when using WPS var projection = new ol.proj.Projection({ code: 'http://www.opengis.net/gml/srs/epsg.xml#4326', @@ -61746,7 +61747,7 @@ wps.SUBPROCESS = 'process|'; wps.VECTORLAYER = 'vector|'; wps.RASTERLAYER = 'raster|'; wps.ONLINE_DOCS_URL = 'https://noisemodelling.readthedocs.io'; -wps.LOCAL_DOCS_URL = 'noisemodelling-readthedocs-io-en-latest.pdf'; +wps.LOCAL_DOCS_URL = 'help/index.html'; wps.editor.prototype.addRasterLayer = function(id, node, value) { var mapId = node._parent; @@ -61955,9 +61956,12 @@ wps.editor.prototype.showEditForm = function(node) { var hasMap = false, bboxTool = false, i, ii; // simple input var name = node._info.identifier.value; - var nameText = name; - if (node.required !== true) { - nameText += ' (optional)'; + var nameText = name +":"; + var abstract = '

    ' + node._info._abstract.value.replace('\n', '
    ') + '

    '; + if(node._info.literalData && node._info.literalData.defaultValue) { + abstract += '

    🛠 Default value: ' + node._info.literalData.defaultValue + '

    ' + } else if (node.required !== true) { + abstract += '

    (optional)

    '; } var pId, id = wps.editor.PREFIX + node._parent + '-' + name.replace(/ /g, '_'); var inputId = id; @@ -61965,7 +61969,7 @@ wps.editor.prototype.showEditForm = function(node) { var saveButton = '
    '; var selected; - html += '
    ' + node._info._abstract.value + '
    '; + html += '
    ' + abstract + '
    '; if (node._info.literalData) { html += '
    '; html += '
    '; @@ -61990,7 +61994,11 @@ wps.editor.prototype.showEditForm = function(node) { var value = node.value; value = (value === undefined) ? '' : value; html += '
    '; - html += '
    '; + var textarea = document.createElement('textarea'); + textarea.id = id; + textarea.className = 'form-control input-sm'; + textarea.textContent = value; // Browser automatically escapes this safely + html += textarea.outerHTML; } html += saveButton; if (node._info.maxOccurs > 1 && node._info.maxOccurs > node._info.minOccurs) { @@ -62516,8 +62524,10 @@ wps.ui = function(options) { this.initializeSplitter(); $('#file-open').click($.proxy(wps.ui.load, null, this)); $('#file-save').click($.proxy(this.save, null, this)); - $('#export-clipboard').click($.proxy(this.exportClipboard, null, this)); - $('#import-clipboard').click($.proxy(this.importClipboard, null, this)); + $('#save-project').click($.proxy(this.saveProject, null, this)); + $('#open-project').click($.proxy(this.openProject, null, this)); + $('#save-project-db').click($.proxy(this.saveProjectWithDatabase, null, this)); + $('#open-project-db').click($.proxy(this.openProjectWithDatabase, null, this)); $( "#dialog" ).dialog({ modal: true, autoOpen: false, @@ -62648,6 +62658,8 @@ wps.ui.load = function(ui, evt, nodes) { ui.redraw(); if (local) { $('.open-success').fadeIn().delay(1500).fadeOut(); + } else { + ui.autoSave(); } } }; @@ -62683,27 +62695,38 @@ wps.ui.prototype.recurse = function(node) { } }; -wps.ui.prototype.parentComplete = function(node) { - var processId = node._parent; - var process = this.processes[processId], parentNode; - var values = {}; - for (var i=0, ii=this.nodes.length; i 0) { - var node = selection.datum(); + if (!selection.empty()) { + var node = null; + // Search the selection for a node of type 'process' + selection.each(function(d) { + if (d.type === 'process') { + node = d; + } + }); + + // If no process node was found in the selection (e.g., only a link was selected), + // fall back to the first available node and find its parent + if (!node) { + node = selection.datum(); + } hasSelected = true; var processId = node.type === 'process' ? node.id : node._parent; if (ui.findNodeById(processId).complete !== true) { @@ -63164,9 +63335,73 @@ wps.ui.prototype.execute = function(ui) { recurse(inputs, ui, values); + const getCookie = (name) => { + const value = `; ${document.cookie}`; + const parts = value.split(`; ${name}=`); + if (parts.length === 2) return parts.pop().split(';').shift(); + return null; + }; + /** + * Generates a Python script that performs the WPS POST request + * @param {string} xmlPayload - The XML content for the body + * @param {string} jwt - The JWT token to be used in the Cookie header + * @param targetUrl Post url + */ + var generatePythonScript = function(xmlPayload, jwt, targetUrl) { + const referer=window.location.origin+window.location.pathname; + // We use a template literal for the Python code. + // We escape backticks if necessary, but here we just inject the variables. + const pythonCode = `import urllib.request +import urllib.error + +# Variables +xml_content = """${xmlPayload}""" +jwt_token = "${jwt}" + +def send_request(): + url = "${targetUrl}" + + # Encode the XML content to bytes + encoded_data = xml_content.encode('utf-8') + + # Define Headers (using the injected JWT) + headers = { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0", + "Accept": "*/*", + "Accept-Language": "fr,fr-FR;q=0.9,en-US;q=0.8,en;q=0.7", + "Content-Type": "application/xml", + "Origin": "${window.location.origin}", + "Connection": "keep-alive", + "Referer": "${referer}", + "Cookie": f"jwt={jwt_token}", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin" + } + + req = urllib.request.Request(url, data=encoded_data, headers=headers, method="POST") + + try: + with urllib.request.urlopen(req) as response: + print(f"Status: {response.getcode()}") + print(response.read().decode('utf-8')) + except urllib.error.HTTPError as e: + print(f"HTTP Error {e.code}: {e.read().decode('utf-8')}") + except Exception as e: + print(f"Error: {e}") + +if __name__ == "__main__": + send_request() +`; + + return pythonCode; + }; var prettyXML = function(body) { var code = $('#tab-xml pre code').get(0); - $(code).html(document.createTextNode(vkbeautify.xml(body, 2))); + var prettyXml = vkbeautify.xml(body, 2); + const targetUrl = window.location.origin + window.location.pathname.replace(/\/$/, "") + "/ows"; + var pythonCode = generatePythonScript(prettyXml, getCookie('jwt'), targetUrl) + $(code).html(document.createTextNode(pythonCode)); hljs.highlightBlock(code); }; @@ -63288,39 +63523,61 @@ wps.ui.prototype.checkSubLinkForDelete = function(link, process) { }; wps.ui.prototype.deleteSelection = function() { - var redraw = false; - if (this.selectedLink !== null) { - var src = this.findNodeById(this.selectedLink.source); - var dst = this.findNodeById(this.selectedLink.target); - var input = src.type === 'input' ? src : dst; - this.editor_.setValue(false, false, undefined, input); - this.nodes.splice(this.nodes.indexOf(this.selectedLink), 1); - this.selectedLink = null; - redraw = true; - } - var selection = d3.selectAll(".node_selected"); - if (selection[0].length > 0) { - var node = selection.datum(); - if (node.type === 'process') { - this.deleteInputMap(node.id); - $('.input-map').detach(); - $('.output-map').detach(); - $('#tab-inputs').html(''); - $('#tab-results').html(''); - this.nodes.splice(this.nodes.indexOf(node), 1); - for (var i=this.nodes.length-1; i>=0; --i) { - if (this.nodes[i] instanceof wps.ui.link && this.checkSubLinkForDelete(this.nodes[i], node.id)) { - this.nodes.splice(i, 1); - } else if (this.nodes[i]._parent === node.id) { - this.nodes.splice(i, 1); - } - } + var redraw = false; + var me = this; + + // 1. Handle Link deletion (original logic) + if (this.selectedLink !== null) { + var src = this.findNodeById(this.selectedLink.source); + var dst = this.findNodeById(this.selectedLink.target); + var input = src.type === 'input' ? src : dst; + this.editor_.setValue(false, false, undefined, input); + this.nodes.splice(this.nodes.indexOf(this.selectedLink), 1); + this.selectedLink = null; + redraw = true; + } + + // 2. Handle Node deletion (Updated to handle multiple selected nodes) + var selection = d3.selectAll(".node_selected"); + if (!selection.empty()) { + // Convert selection to data array to avoid issues while modifying the DOM/nodes + selection.each(function(node) { + // Check if node still exists in the list (might have been deleted by its parent process in this same loop) + var nodeIndex = me.nodes.indexOf(node); + if (nodeIndex === -1) return; + + if (node.type === 'process') { + // Clean up UI maps and tabs + me.deleteInputMap(node.id); + $('.input-map').detach(); + $('.output-map').detach(); + $('#tab-inputs').html(''); + $('#tab-results').html(''); + + // Remove the process itself + me.nodes.splice(me.nodes.indexOf(node), 1); + + // Remove all children (inputs/outputs) and links associated with this process + for (var i = me.nodes.length - 1; i >= 0; --i) { + var n = me.nodes[i]; + if (n instanceof wps.ui.link && me.checkSubLinkForDelete(n, node.id)) { + me.nodes.splice(i, 1); + } else if (n._parent === node.id) { + me.nodes.splice(i, 1); + } + } + redraw = true; + } + // Note: In this UI, inputs/outputs are tied to processes. + // We don't delete individual inputs via the delete key normally, + // but if you wanted to allow it, you would add logic here. + }); + } + + if (redraw) { + this.autoSave(); + this.redraw(); } - redraw = true; - } - if (redraw) { - this.redraw(); - } }; wps.ui.prototype.zoomIn = function(evt) { @@ -63431,6 +63688,7 @@ wps.ui.canvasMouseUp = function(ui) { delete me.movingSet[i].ox; delete me.movingSet[i].oy; } + me.autoSave(); } me.redraw(); me.resetMouseVars(); @@ -63473,100 +63731,176 @@ wps.ui.prototype.createCanvas = function() { this.dragLine = this.vis.append("svg:path").attr("class", "drag_line"); }; -wps.ui.prototype.createDropTarget = function() { - var me = this; - this.dropZone_.droppable({ - accept:".palette_node", - drop: function( event, ui ) { - d3.event = event; - var selected_tool = $(ui.draggable[0]).data('type'); - var process = me.client_.getProcess(me.defaultServer_, selected_tool, {callback: function(info, error, statusText) { - if (error === true) { - $('#tab-results').html('Error getting process description, details: ' + statusText); - me.activateTab('tab-results'); - return; - } - var mousePos = d3.touches(this)[0]||d3.mouse(this); - mousePos[1] += this.scrollTop; - mousePos[0] += this.scrollLeft; - mousePos[1] /= me.scaleFactor; - mousePos[0] /= me.scaleFactor; - mousePos[0] = Math.max(mousePos[0], 300); - var config = { - x: mousePos[0], - y: mousePos[1], - w: this.nodeWidth, - type: 'process', - dirty: true, - _info: info, - inputs: info.dataInputs.input.length, - outputs: info.processOutputs.output.length, - label: selected_tool - }; - var nn = new wps.ui.node(config); - me.processes[nn.id] = process; - var link, i, ii, delta = 50, span = delta * nn.inputs, deltaY = (span-delta)/2; - var startY = mousePos[1]; - for (i=0, ii=nn.inputs; i 0), - complete: false, - label: info.dataInputs.input[i].title.value - }; - if (inputConfig.y < 15) { - startY = 100 + deltaY; - inputConfig.y = startY-deltaY; - } - var input = new wps.ui.node(inputConfig); - deltaY -= delta; - me.nodes.push(input); - // create a link as well between input and process - link = new wps.ui.link({ - source: input.id, - target: nn.id, - _parent: nn.id - }); - me.nodes.push(link); - } - } - for (i=0, ii=nn.outputs; i maxInputW) maxInputW = inputW; + } + maxInputW = Math.max(maxInputW, me.nodeWidth); + + // Calculate the maximum width among all outputs + var maxOutputW = 0; + for (var i = 0; i < info.processOutputs.output.length; i++) { + var outputW = me.calculateTextWidth(info.processOutputs.output[i].title.value); + if (outputW > maxOutputW) maxOutputW = outputW; + } + maxOutputW = Math.max(maxOutputW, me.nodeWidth); + + // Calculate X positions so they don't overlap regardless of text length + // Positions are centers of nodes + var inputX = mousePos[0] - (processW / 2) - horizontalGutter - (maxInputW / 2); + var outputX = mousePos[0] + (processW / 2) + horizontalGutter + (maxOutputW / 2); + + // Prevent inputs from falling off the left side of the workspace + var leftEdgeOffset = (mousePos[0] - inputX) + (maxInputW / 2) + 20; + mousePos[0] = Math.max(mousePos[0], leftEdgeOffset); + // Recalculate after potential shift + inputX = mousePos[0] - (processW / 2) - horizontalGutter - (maxInputW / 2); + outputX = mousePos[0] + (processW / 2) + horizontalGutter + (maxOutputW / 2); + // --- END DYNAMIC CALCULATIONS --- + + // We want the left-most edge of the longest label to be at x=20 + // LeftEdge = mouseX - (processW/2) - gutter - maxInputW + var currentLeftEdge = mousePos[0] - (processW / 2) - horizontalGutter - maxInputW; + + if (currentLeftEdge < 20) { + // Push the process block just enough to keep the longest label on screen + mousePos[0] = 20 + maxInputW + horizontalGutter + (processW / 2); + } + + // This is the vertical line where the right sides of all input blocks will touch + var inputRightEdgeX = mousePos[0] - (processW / 2) - horizontalGutter; + + // --- BOUNDARY CHECK --- + // Ensure the widest input doesn't go off the left side of the screen + if (inputRightEdgeX - maxInputW < 20) { + var shift = 20 - (inputRightEdgeX - maxInputW); + mousePos[0] += shift; + // Recalculate Right Edge after shift + inputRightEdgeX = mousePos[0] - (processW / 2) - horizontalGutter; + } + // Sorting + if (info.dataInputs && info.dataInputs.input) { + info.dataInputs.input.sort(function(a, b) { + // 1. Check Mandatory Status (minOccurs > 0) + var isMandatoryA = (a.minOccurs > 0); + var isMandatoryB = (b.minOccurs > 0); + + // If one is mandatory and the other isn't, mandatory goes first + if (isMandatoryA !== isMandatoryB) { + return isMandatoryA ? -1 : 1; + } + + // 2. Secondary Sort: Alphabetical by Title + var titleA = (a.title && a.title.value) ? a.title.value.toLowerCase() : ""; + var titleB = (b.title && b.title.value) ? b.title.value.toLowerCase() : ""; + + return titleA.localeCompare(titleB); + }); + } + var config = { + x: mousePos[0], + y: mousePos[1], + w: processW, + type: 'process', + dirty: true, + _info: info, + inputs: info.dataInputs.input.length, + outputs: info.processOutputs.output.length, + label: selected_tool + }; + var nn = new wps.ui.node(config); + me.processes[nn.id] = process; + + var link, i, ii, delta = 35, span = delta * nn.inputs, deltaY = (span-delta)/2; + var startY = mousePos[1]; + + for (i=0, ii=nn.inputs; i 0), + complete: false, + label: inputInfo.title.value.replace(/_/g, ' ') + }; + + if (inputConfig.y < 15) { + startY = 100 + deltaY; + inputConfig.y = startY-deltaY; + } + var input = new wps.ui.node(inputConfig); + deltaY -= delta; + me.nodes.push(input); + link = new wps.ui.link({source: input.id, target: nn.id, _parent: nn.id}); + me.nodes.push(link); + } + } + + for (i=0, ii=nn.outputs; i
    ' + '' + - group + '
    '); + groupLabel + ''); this.parentContainer_.append(category); var content = $('
    '); $(category).append(content); @@ -64015,7 +64398,7 @@ wps.ui.prototype.createProcess = function(process) { var summary = offering._abstract.value; var title = offering.title.value; var id = offering.identifier.value; - var d = $('
    ' + id.split(':')[1] + '
    '); + var d = $('
    ' + id.split(':')[1].replace(/_/g, ' ') + '
    '); $(d).data('type', id); $(d).popover({ title: title, diff --git a/wpsbuilder/dist/wps-gui.min.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wps-gui.min.css similarity index 100% rename from wpsbuilder/dist/wps-gui.min.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wps-gui.min.css diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-header.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-header.png new file mode 100644 index 000000000..5c72134d2 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-header.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-header.svg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-header.svg new file mode 100644 index 000000000..43324d525 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-header.svg @@ -0,0 +1,257 @@ + + + +image/svg+xmlNoiseModelling diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-splashscreen.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-splashscreen.png new file mode 100644 index 000000000..9b8ddb5df Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-splashscreen.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-splashscreen.svg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-splashscreen.svg new file mode 100644 index 000000000..f03977daa --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/dist/wpsbuilder-splashscreen.svg @@ -0,0 +1,468 @@ + + + +image/svg+xmlAccordion05/20266.0https://noise-planet.org/noisemodelling.htmlNoiseModelling diff --git a/wpsbuilder/vendor/highlight/CHANGES.md b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/CHANGES.md similarity index 100% rename from wpsbuilder/vendor/highlight/CHANGES.md rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/CHANGES.md diff --git a/wpsbuilder/vendor/highlight/LICENSE b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/LICENSE similarity index 100% rename from wpsbuilder/vendor/highlight/LICENSE rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/LICENSE diff --git a/wpsbuilder/vendor/highlight/README.md b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/README.md similarity index 100% rename from wpsbuilder/vendor/highlight/README.md rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/README.md diff --git a/wpsbuilder/vendor/highlight/README.ru.md b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/README.ru.md similarity index 100% rename from wpsbuilder/vendor/highlight/README.ru.md rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/README.ru.md diff --git a/wpsbuilder/vendor/highlight/highlight.pack.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/highlight.pack.js similarity index 100% rename from wpsbuilder/vendor/highlight/highlight.pack.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/highlight.pack.js diff --git a/wpsbuilder/vendor/highlight/styles/arta.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/arta.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/arta.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/arta.css diff --git a/wpsbuilder/vendor/highlight/styles/ascetic.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/ascetic.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/ascetic.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/ascetic.css diff --git a/wpsbuilder/vendor/highlight/styles/atelier-dune.dark.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-dune.dark.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/atelier-dune.dark.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-dune.dark.css diff --git a/wpsbuilder/vendor/highlight/styles/atelier-dune.light.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-dune.light.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/atelier-dune.light.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-dune.light.css diff --git a/wpsbuilder/vendor/highlight/styles/atelier-forest.dark.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-forest.dark.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/atelier-forest.dark.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-forest.dark.css diff --git a/wpsbuilder/vendor/highlight/styles/atelier-forest.light.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-forest.light.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/atelier-forest.light.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-forest.light.css diff --git a/wpsbuilder/vendor/highlight/styles/atelier-heath.dark.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-heath.dark.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/atelier-heath.dark.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-heath.dark.css diff --git a/wpsbuilder/vendor/highlight/styles/atelier-heath.light.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-heath.light.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/atelier-heath.light.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-heath.light.css diff --git a/wpsbuilder/vendor/highlight/styles/atelier-lakeside.dark.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-lakeside.dark.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/atelier-lakeside.dark.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-lakeside.dark.css diff --git a/wpsbuilder/vendor/highlight/styles/atelier-lakeside.light.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-lakeside.light.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/atelier-lakeside.light.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-lakeside.light.css diff --git a/wpsbuilder/vendor/highlight/styles/atelier-seaside.dark.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-seaside.dark.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/atelier-seaside.dark.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-seaside.dark.css diff --git a/wpsbuilder/vendor/highlight/styles/atelier-seaside.light.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-seaside.light.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/atelier-seaside.light.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/atelier-seaside.light.css diff --git a/wpsbuilder/vendor/highlight/styles/brown_paper.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/brown_paper.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/brown_paper.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/brown_paper.css diff --git a/wpsbuilder/vendor/highlight/styles/brown_papersq.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/brown_papersq.png similarity index 100% rename from wpsbuilder/vendor/highlight/styles/brown_papersq.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/brown_papersq.png diff --git a/wpsbuilder/vendor/highlight/styles/codepen-embed.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/codepen-embed.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/codepen-embed.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/codepen-embed.css diff --git a/wpsbuilder/vendor/highlight/styles/color-brewer.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/color-brewer.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/color-brewer.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/color-brewer.css diff --git a/wpsbuilder/vendor/highlight/styles/dark.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/dark.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/dark.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/dark.css diff --git a/wpsbuilder/vendor/highlight/styles/default.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/default.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/default.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/default.css diff --git a/wpsbuilder/vendor/highlight/styles/docco.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/docco.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/docco.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/docco.css diff --git a/wpsbuilder/vendor/highlight/styles/far.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/far.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/far.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/far.css diff --git a/wpsbuilder/vendor/highlight/styles/foundation.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/foundation.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/foundation.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/foundation.css diff --git a/wpsbuilder/vendor/highlight/styles/github.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/github.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/github.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/github.css diff --git a/wpsbuilder/vendor/highlight/styles/googlecode.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/googlecode.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/googlecode.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/googlecode.css diff --git a/wpsbuilder/vendor/highlight/styles/hybrid.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/hybrid.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/hybrid.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/hybrid.css diff --git a/wpsbuilder/vendor/highlight/styles/idea.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/idea.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/idea.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/idea.css diff --git a/wpsbuilder/vendor/highlight/styles/ir_black.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/ir_black.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/ir_black.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/ir_black.css diff --git a/wpsbuilder/vendor/highlight/styles/kimbie.dark.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/kimbie.dark.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/kimbie.dark.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/kimbie.dark.css diff --git a/wpsbuilder/vendor/highlight/styles/kimbie.light.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/kimbie.light.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/kimbie.light.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/kimbie.light.css diff --git a/wpsbuilder/vendor/highlight/styles/magula.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/magula.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/magula.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/magula.css diff --git a/wpsbuilder/vendor/highlight/styles/mono-blue.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/mono-blue.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/mono-blue.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/mono-blue.css diff --git a/wpsbuilder/vendor/highlight/styles/monokai.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/monokai.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/monokai.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/monokai.css diff --git a/wpsbuilder/vendor/highlight/styles/monokai_sublime.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/monokai_sublime.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/monokai_sublime.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/monokai_sublime.css diff --git a/wpsbuilder/vendor/highlight/styles/obsidian.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/obsidian.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/obsidian.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/obsidian.css diff --git a/wpsbuilder/vendor/highlight/styles/paraiso.dark.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/paraiso.dark.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/paraiso.dark.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/paraiso.dark.css diff --git a/wpsbuilder/vendor/highlight/styles/paraiso.light.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/paraiso.light.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/paraiso.light.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/paraiso.light.css diff --git a/wpsbuilder/vendor/highlight/styles/pojoaque.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/pojoaque.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/pojoaque.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/pojoaque.css diff --git a/wpsbuilder/vendor/highlight/styles/pojoaque.jpg b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/pojoaque.jpg similarity index 100% rename from wpsbuilder/vendor/highlight/styles/pojoaque.jpg rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/pojoaque.jpg diff --git a/wpsbuilder/vendor/highlight/styles/railscasts.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/railscasts.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/railscasts.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/railscasts.css diff --git a/wpsbuilder/vendor/highlight/styles/rainbow.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/rainbow.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/rainbow.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/rainbow.css diff --git a/wpsbuilder/vendor/highlight/styles/school_book.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/school_book.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/school_book.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/school_book.css diff --git a/wpsbuilder/vendor/highlight/styles/school_book.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/school_book.png similarity index 100% rename from wpsbuilder/vendor/highlight/styles/school_book.png rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/school_book.png diff --git a/wpsbuilder/vendor/highlight/styles/solarized_dark.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/solarized_dark.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/solarized_dark.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/solarized_dark.css diff --git a/wpsbuilder/vendor/highlight/styles/solarized_light.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/solarized_light.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/solarized_light.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/solarized_light.css diff --git a/wpsbuilder/vendor/highlight/styles/sunburst.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/sunburst.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/sunburst.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/sunburst.css diff --git a/wpsbuilder/vendor/highlight/styles/tomorrow-night-blue.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/tomorrow-night-blue.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/tomorrow-night-blue.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/tomorrow-night-blue.css diff --git a/wpsbuilder/vendor/highlight/styles/tomorrow-night-bright.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/tomorrow-night-bright.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/tomorrow-night-bright.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/tomorrow-night-bright.css diff --git a/wpsbuilder/vendor/highlight/styles/tomorrow-night-eighties.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/tomorrow-night-eighties.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/tomorrow-night-eighties.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/tomorrow-night-eighties.css diff --git a/wpsbuilder/vendor/highlight/styles/tomorrow-night.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/tomorrow-night.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/tomorrow-night.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/tomorrow-night.css diff --git a/wpsbuilder/vendor/highlight/styles/tomorrow.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/tomorrow.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/tomorrow.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/tomorrow.css diff --git a/wpsbuilder/vendor/highlight/styles/vs.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/vs.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/vs.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/vs.css diff --git a/wpsbuilder/vendor/highlight/styles/xcode.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/xcode.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/xcode.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/xcode.css diff --git a/wpsbuilder/vendor/highlight/styles/zenburn.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/zenburn.css similarity index 100% rename from wpsbuilder/vendor/highlight/styles/zenburn.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/highlight/styles/zenburn.css diff --git a/wpsbuilder/vendor/ol.css b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/ol.css similarity index 100% rename from wpsbuilder/vendor/ol.css rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/ol.css diff --git a/wpsbuilder/vendor/ol.js b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/ol.js similarity index 100% rename from wpsbuilder/vendor/ol.js rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/ol.js diff --git a/wpsbuilder/vendor/wps.json b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/wps.json similarity index 100% rename from wpsbuilder/vendor/wps.json rename to noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/vendor/wps.json diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/Building_Grid3D.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/Building_Grid3D.png new file mode 100644 index 000000000..54d0e88ff Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/Building_Grid3D.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/acoustics_parameters_confFavorableOccurrences.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/acoustics_parameters_confFavorableOccurrences.png new file mode 100644 index 000000000..e9a03ab29 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/acoustics_parameters_confFavorableOccurrences.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/acoustics_parameters_confMaxReflDist.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/acoustics_parameters_confMaxReflDist.png new file mode 100644 index 000000000..dee0101f4 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/acoustics_parameters_confMaxReflDist.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/acoustics_parameters_confMaxSrcDist.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/acoustics_parameters_confMaxSrcDist.png new file mode 100644 index 000000000..4a274f322 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/acoustics_parameters_confMaxSrcDist.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/building_grid_output.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/building_grid_output.png new file mode 100644 index 000000000..6ed39ad6a Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/building_grid_output.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/change_SRID.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/change_SRID.png new file mode 100644 index 000000000..cd34bce4f Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/change_SRID.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/create_isosurface.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/create_isosurface.png new file mode 100644 index 000000000..99b61847d Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/create_isosurface.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/delaunay_grid_output.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/delaunay_grid_output.png new file mode 100644 index 000000000..8af2acfde Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/delaunay_grid_output.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/export_table.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/export_table.png new file mode 100644 index 000000000..013e7b2b4 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/export_table.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_asc_file.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_asc_file.png new file mode 100644 index 000000000..51d3ba3b0 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_asc_file.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_asc_folder.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_asc_folder.png new file mode 100644 index 000000000..cef7aba94 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_asc_folder.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_file.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_file.png new file mode 100644 index 000000000..56347ceaf Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_file.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_folder.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_folder.png new file mode 100644 index 000000000..f512f4561 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_folder.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_osm_file.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_osm_file.png new file mode 100644 index 000000000..4a6a17bcd Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/import_osm_file.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/railway_plateform.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/railway_plateform.png new file mode 100644 index 000000000..decb2bfae Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/railway_plateform.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/receivers_random_nReceivers.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/receivers_random_nReceivers.png new file mode 100644 index 000000000..494a668de Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/receivers_random_nReceivers.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/receivers_random_output.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/receivers_random_output.png new file mode 100644 index 000000000..868e02520 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/receivers_random_output.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/regular_grid_output.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/regular_grid_output.png new file mode 100644 index 000000000..73f73da48 Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/regular_grid_output.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/train_plateforme.png b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/train_plateforme.png new file mode 100644 index 000000000..b2782d10f Binary files /dev/null and b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/wps_images/train_plateforme.png differ diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/xmlFiles/wcs.xml b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/xmlFiles/wcs.xml new file mode 100644 index 000000000..18f922b34 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/xmlFiles/wcs.xml @@ -0,0 +1,83 @@ + + + Web Coverage Service + This server implements the WCS specification 1.0 and 1.1.1, it's reference implementation of WCS 1.1.1. All layers published by this service are available on WMS also. + + WCS + WMS + GEOSERVER + + WCS + 1.1.0 + 1.1.1 + NONE + NONE + + + The Ancient Geographers + + + Claudius Ptolomaeus + Chief Geographer + + + + Alexandria + Egypt + claudius.ptolomaeus@gmail.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + False + + + + + + XML + + + + + \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/xmlFiles/wfs.xml b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/xmlFiles/wfs.xml new file mode 100644 index 000000000..e436a7b55 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/static/xmlFiles/wfs.xml @@ -0,0 +1,556 @@ + + + GeoServer Web Feature Service + This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction. + + WFS + WMS + GEOSERVER + + WFS + 1.1.0 + NONE + NONE + + + The Ancient Geographers + + Claudius Ptolomaeus + Chief Geographer + + + + + + + + Alexandria + + + Egypt + claudius.ptolomaeus@gmail.com + + + + + + + + + + + + + + 1.0.0 + 1.1.0 + + + text/xml + + + ServiceIdentification + ServiceProvider + OperationsMetadata + FeatureTypeList + Filter_Capabilities + + + + + + + + + + + text/xml; subtype=gml/3.1.1 + + + + + + + + + + + results + hits + + + text/xml; subtype=gml/3.1.1 + GML2 + KML + SHAPE-ZIP + application/gml+xml; version=3.2 + application/json + application/vnd.google-earth.kml xml + application/vnd.google-earth.kml+xml + csv + gml3 + gml32 + json + text/csv + text/xml; subtype=gml/2.1.2 + text/xml; subtype=gml/3.2 + + + 2 + + + + + + + + + + + + + + + + + + + ALL + SOME + + + + + + + + + + + results + hits + + + text/xml; subtype=gml/3.1.1 + GML2 + KML + SHAPE-ZIP + application/gml+xml; version=3.2 + application/json + application/vnd.google-earth.kml xml + application/vnd.google-earth.kml+xml + csv + gml3 + gml32 + json + text/csv + text/xml; subtype=gml/2.1.2 + text/xml; subtype=gml/3.2 + + + + + + + + + + + text/xml; subtype=gml/3.1.1 + + + GenerateNew + UseExisting + ReplaceDuplicate + + + ALL + SOME + + + + + + Query + Insert + Update + Delete + Lock + + + + + + gml:Envelope + gml:Point + gml:LineString + gml:Polygon + + + + + + + + + + + + + + + + + + + LessThan + GreaterThan + LessThanEqualTo + GreaterThanEqualTo + EqualTo + NotEqualTo + Like + Between + NullCheck + + + + + + abs + abs_2 + abs_3 + abs_4 + acos + Add_Laeq_Leq_columns + Add_Primary_Key + AddCoverages + Affine + Agent_Exposure + Aggregate + And + Area + area2 + AreaGrid + array + asin + atan + atan2 + attributeCount + BandMerge + bands + BandSelect + BarnesSurface + between + boundary + boundaryDimension + boundedBy + Bounds + buffer + BufferFeatureCollection + bufferWithSegments + Building_Grid + Building_Grid3D + Categorize + ceil + centerLine + centroid + Change_SRID + classify + ClassifyByRange + Clean_Buildings_Table + Clean_Database + Clip + CollectGeometries + Collection_Average + Collection_Bounds + Collection_Count + Collection_Max + Collection_Median + Collection_Min + Collection_Nearest + Collection_Sum + Collection_Unique + Concatenate + contains + Contour + contrast + convert + convexHull + ConvolveCoverage + cos + Count + CoverageClassStats + Create_Isosurface + CropCoverage + crosses + darken + dateDifference + dateFormat + dateParse + Delaunay_Grid + densify + desaturate + difference + dimension + disjoint + disjoint3D + Display_Database + distance + distance3D + double2bool + Drop_a_Table + endAngle + endPoint + Enrich_DEM + Enrich_DEM_with_lines + Enrich_DEM_with_rail + Enrich_DEM_with_road + Enrich_Landcover_with_rail + env + envelope + EqualArea + EqualInterval + equalsExact + equalsExactTolerance + equalTo + exp + Export_Table + exteriorRing + Feature + FeatureClassStats + floor + footprints + geometry + geometryType + geomFromWKT + geomLength + GeorectifyCoverage + GetFullCoverage + getGeometryN + getX + getY + getz + grayscale + greaterEqualThan + greaterThan + Grid + GroupCandidateSelection + Heatmap + hsl + id + IEEEremainder + if_then_else + Import + Import_Activities + Import_Asc_File + Import_Asc_Folder + Import_File + Import_Folder + Import_OSM + Import_OSM_Pedestrian + Import_Symuvia + in + in10 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + inArray + InclusionFeatureCollection + int2bbool + int2ddouble + interiorPoint + interiorRingN + Interpolate + intersection + IntersectionFeatureCollection + intersects + intersects3D + isCached + isClosed + isCoverage + isEmpty + isInstanceOf + isLike + isNull + isometric + isRing + isSimple + isValid + isWithinDistance + isWithinDistance3D + Jenks + Jiffle + jsonPointer + labelPoint + language + lapply + length + lessEqualThan + lessThan + lighten + list + listMultiply + litem + literate + log + LRSGeocode + LRSMeasure + LRSSegment + mapGet + max + max_2 + max_3 + max_4 + min + min_2 + min_3 + min_4 + mincircle + minimumdiameter + minrectangle + mix + modulo + MultiplyCoverages + Nearest + Noise_From_Attenuation_Matrix + Noise_level_from_source + Noise_level_from_traffic + Noise_Map_Difference + NormalizeCoverage + not + notEqualTo + now + numberFormat + numberFormat2 + numGeometries + numInteriorRing + numPoints + octagonalenvelope + offset + Or + overlaps + PagedUnique + parameter + parseBoolean + parseDouble + parseInt + parseLong + pgNearest + pi + Plot_Exposition_Distribution + PlotDirectivity + PointBuffers + pointN + PointStacker + PolygonExtraction + polygonize + PolyLabeller + pow + property + PropertyExists + Quantile + Query + Railway_Emission_from_Traffic + random + Random_Grid + RangeLookup + RasterAsPointCollection + RasterZonalStatistics + RasterZonalStatistics2 + Receivers_From_Activities_Closest + Receivers_From_Activities_Random + Recode + RectangularClip + Regular_Grid + relate + relatePattern + reproject + ReprojectGeometry + rescaleToPixels + rint + Road_Emission_From_AADF + Road_Emission_From_TMJA + Road_Emission_from_Traffic + round + round_2 + roundDouble + saturate + ScaleCoverage + Screen_to_building + Set_Height + setCRS + shade + simplify + Simplify_Geometries + sin + size + Snap + Sources_From_TimeString + spin + splitPolygon + sqrt + StandardDeviation + startAngle + startPoint + StoreCoverage + strAbbreviate + strCapitalize + strConcat + strDefaultIfBlank + strEndsWith + strEqualsIgnoreCase + strIndexOf + stringTemplate + strLastIndexOf + strLength + strMatches + strPosition + strReplace + strStartsWith + strStripAccents + strSubstring + strSubstringStart + strToLowerCase + strToUpperCase + strTrim + strTrim2 + strURLEncode + StyleCoverage + symDifference + Table_Visualization_Data + Table_Visualization_Map + tan + tint + toDegrees + toRadians + touches + toWKT + Traffic_From_Events + Traffic_Probabilistic_Modelling + Transform + TransparencyFill + union + UnionFeatureCollection + Unique + UniqueInterval + VectorToRaster + VectorZonalStatistics + vertices + within + ZerodB_Source_From_Roads + + + + + + + + + + \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/about.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/about.html new file mode 100644 index 000000000..7b40c91cd --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/about.html @@ -0,0 +1,76 @@ + + + + +
    +
    +
    +
    +

    System status

    +

    Java Virtual Machine Memory

    +
    + + +
    +
    +

    Heap Memory Usage

    +
    +
    + Used: 0 MB + Max: 0 MB +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +

    Loaded libraries

    +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    Library NameVersionLast ModifiedCommit / Build
    Library Name1.0.0Date + - +
    No library information is available
    +
    +
    +
    + + + + diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/add_job.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/add_job.html new file mode 100644 index 000000000..f9ab52faf --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/add_job.html @@ -0,0 +1,36 @@ + + + + + +
    +
    +
    +

    Add a new job

    +
    + +
    +
    +
    + Add a new processing job to the queue +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/blank.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/blank.html new file mode 100644 index 000000000..f7986bcc3 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/blank.html @@ -0,0 +1,20 @@ + + + + + + + Plamade computation platform + + + + + + +

    Notification

    +
    + +
    +
    + + \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/generate_report.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/generate_report.html new file mode 100644 index 000000000..d86db8818 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/generate_report.html @@ -0,0 +1,52 @@ + + + + + +
    +
    +
    +

    Generate debug report

    +
    + +
    +
    +
    + Create a propagation report for a specific location +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/header.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/header.html new file mode 100644 index 000000000..61bd50d76 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/header.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/index.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/index.html new file mode 100644 index 000000000..72dacd4ae --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/index.html @@ -0,0 +1,19 @@ + + + + +
    +
    +
    + NoiseModelling +

    + Click on Get Started in order to proceed to authentication +

    +

    + Get Started +

    +
    +
    + + diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/job_list.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/job_list.html new file mode 100644 index 000000000..5202c5098 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/job_list.html @@ -0,0 +1,84 @@ + + + + + +
    +
    +
    +

    Manage jobs

    +

    Processing job management

    +
    +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Job ID: 1 +
    Userjohn@localhost
    ScriptProcessGroup:process
    Start DateMonday, July 19, 2021 11:39 AM
    End Date-
    Duration-
    Progression15 %
    StatusQueued
    LogsView Logs
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/job_logs.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/job_logs.html new file mode 100644 index 000000000..27aa66df3 --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/job_logs.html @@ -0,0 +1,25 @@ + + + + +
    +
    +
    +

    +

    Job latest logs

    +
    +
    +
    blah blah
    +
    +
    + + +
    + + diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/login.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/login.html new file mode 100644 index 000000000..f6503e02b --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/login.html @@ -0,0 +1,26 @@ + + + + +

    User authentification

    +
    + +
    +
    +
    + Open your one-time password manager and fill the generated code (ex: KeePassXC, FreeOTP) +
    + +
    +
    + +
    + +

    By logging in, you consent to our use of a cookie to track your session as per the General Data Protection Regulation (GDPR).

    +
    +
    +
    + + \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/menu.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/menu.html new file mode 100644 index 000000000..c92f5f97c --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/menu.html @@ -0,0 +1,26 @@ + diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/register.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/register.html new file mode 100644 index 000000000..3ff0d346c --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/register.html @@ -0,0 +1,34 @@ + + + + +

    User register

    +
    + +
    +
    + + +
    + You can use any one-time password manager (ex: KeePassXC, FreeOTP) to finalize the registration and login here later +
    + QR Code +
    +
    +
    +
    + Scan the QRCode or write down these codes + +
    +
    + Enter the generated one-time password to finalize your account creation +
    + + +
    +
    +
    +
    + + \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/user_edit.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/user_edit.html new file mode 100644 index 000000000..461d3697a --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/user_edit.html @@ -0,0 +1,54 @@ + + + + +
    +
    +
    +

    Edit user

    +
    + +
    +
    +
    + User attributes +
    + + +
    +
    +
    + User rights +
    + + +
    +
    +
    + Danger zone +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/users.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/users.html new file mode 100644 index 000000000..cfc60716b --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/users.html @@ -0,0 +1,53 @@ + + + + + +
    +
    +
    +

    Manage accounts

    +

    Create new accounts and modify existing ones

    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + +
    account emailDatabase sizeRegister LinkGroupsActions
    15.8 MbEdit
    +
    +
    +
    + Create a new user + + + +
    +
    +
    +
    + + + diff --git a/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/wpsbuilder_index.html b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/wpsbuilder_index.html new file mode 100644 index 000000000..63c00367b --- /dev/null +++ b/noisemodelling-scripts/src/main/resources/org/noise_planet/noisemodelling/webserver/thymeleaf/wpsbuilder_index.html @@ -0,0 +1,162 @@ + + + + NoiseModelling + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    + + +
    + +
    + + + + + + + diff --git a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestAcousticTools.groovy b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestAcousticTools.groovy similarity index 66% rename from wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestAcousticTools.groovy rename to noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestAcousticTools.groovy index ac67559ec..beff38d9b 100644 --- a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestAcousticTools.groovy +++ b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestAcousticTools.groovy @@ -10,32 +10,35 @@ * */ -package org.noise_planet.noisemodelling.wps +package org.noise_planet.noisemodelling.scripts import groovy.sql.Sql import org.h2gis.functions.io.shp.SHPRead -import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.GeometryTableUtilities +import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation -import org.junit.Test +import org.junit.jupiter.api.Test import org.noise_planet.noisemodelling.jdbc.NoiseMapDatabaseParameters -import org.noise_planet.noisemodelling.wps.Acoustic_Tools.Add_Laeq_Leq_columns -import org.noise_planet.noisemodelling.wps.Acoustic_Tools.Create_Isosurface -import org.noise_planet.noisemodelling.wps.NoiseModelling.Noise_level_from_traffic -import org.noise_planet.noisemodelling.wps.NoiseModelling.Road_Emission_from_Traffic -import org.noise_planet.noisemodelling.wps.Receivers.Delaunay_Grid +import org.noise_planet.noisemodelling.scripts.Acoustic_Tools.Add_Laeq_Leq_columns +import org.noise_planet.noisemodelling.scripts.Acoustic_Tools.Create_Isosurface +import org.noise_planet.noisemodelling.scripts.NoiseModelling.Noise_level_from_source +import org.noise_planet.noisemodelling.scripts.NoiseModelling.Road_Emission_from_Traffic +import org.noise_planet.noisemodelling.scripts.Receivers.Regular_Grid import org.slf4j.Logger import org.slf4j.LoggerFactory - import java.sql.SQLException +import static org.junit.jupiter.api.Assertions.assertEquals +import static org.junit.jupiter.api.Assertions.assertTrue + /** * Test parsing of zip file using H2GIS database */ class TestAcousticTools extends JdbcTestCase { Logger LOGGER = LoggerFactory.getLogger(TestAcousticTools.class) + @Test void testAddLeqLaeqColumns1() { SHPRead.importTable(connection, TestAcousticTools.getResource("ROADS2.shp").getPath()) @@ -50,6 +53,7 @@ class TestAcousticTools extends JdbcTestCase { assertEquals("This table does not contain column with this suffix : HZ", res) } + @Test void testAddLeqLaeqColumns2() { SHPRead.importTable(connection, TestAcousticTools.getResource("ROADS2.shp").getPath()) @@ -66,6 +70,7 @@ class TestAcousticTools extends JdbcTestCase { assertEquals(true, fields.contains("LEQ")) } + @Test void testCreateIsosurface() { def sql = new Sql(connection) @@ -74,19 +79,22 @@ class TestAcousticTools extends JdbcTestCase { sql.execute("CREATE SPATIAL INDEX ON BUILDINGS(THE_GEOM)") sql.execute("CREATE SPATIAL INDEX ON ROADS2(THE_GEOM)") - new Delaunay_Grid().exec(connection, ["buildingTableName": "BUILDINGS", - "sourcesTableName" : "ROADS2", - "sourceDensification": 0]); - + new Regular_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", + "sourcesTableName" : "ROADS2", + "fenceTableName" : "ROADS2", + "outputTriangleTable" : true, + "delta" : 50]); - new Noise_level_from_traffic().exec(connection, [tableBuilding :"BUILDINGS", tableRoads: "ROADS2", - tableReceivers: "RECEIVERS", - confMaxSrcDist:100, confTemperature:20, confHumidity:50, - confFavourableOccurrencesDefault: "0.5, 0.1, 0.1, 0.1, 0.2, 0.5," + - " 0.7, 0.8, 0.8, 0.6, 0.5, 0.5, 0.5, 0.5, 0.5, 0.2"]) - new Create_Isosurface().exec(connection, [resultTable : NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME]) + new Noise_level_from_source().exec(connection, [tableBuilding : "BUILDINGS", tableSources: "ROADS2", + tableReceivers : "RECEIVERS", + confMaxSrcDist : 100, + confDiffHorizontal : true, + confTemperature : 20, confHumidity: 50, + confFavourableOccurrencesDefault: "0.5, 0.1, 0.1, 0.1, 0.2, 0.5," + + " 0.7, 0.8, 0.8, 0.6, 0.5, 0.5, 0.5, 0.5, 0.5, 0.2"]) + new Create_Isosurface().exec(connection, [resultTable: NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME, keepTriangles: true]) assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("ROADS2"))) assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse(NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME))) assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("CONTOURING_NOISE_MAP"))) @@ -103,6 +111,7 @@ class TestAcousticTools extends JdbcTestCase { assertTrue(fieldValues.contains("7")); } + @Test void testUpdateZ() throws SQLException, IOException { SHPRead.importTable(connection, TestAcousticTools.getResource("receivers.shp").getPath()) def st = new Sql(connection) diff --git a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestDataAssimilation.groovy b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestDataAssimilation.groovy similarity index 76% rename from wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestDataAssimilation.groovy rename to noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestDataAssimilation.groovy index b49450e09..cc315c1d5 100644 --- a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestDataAssimilation.groovy +++ b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestDataAssimilation.groovy @@ -10,14 +10,15 @@ * */ -package org.noise_planet.noisemodelling.wps -import org.junit.Test -import org.noise_planet.noisemodelling.wps.Data_Assimilation.* -import org.noise_planet.noisemodelling.wps.Import_and_Export.Export_Table -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_File -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_OSM -import org.noise_planet.noisemodelling.wps.NoiseModelling.Noise_level_from_source -import org.noise_planet.noisemodelling.wps.Receivers.Regular_Grid +package org.noise_planet.noisemodelling.scripts +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir; +import org.noise_planet.noisemodelling.scripts.Data_Assimilation.* +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Export_Table +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_File +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_OSM +import org.noise_planet.noisemodelling.scripts.NoiseModelling.Noise_level_from_source +import org.noise_planet.noisemodelling.scripts.Receivers.Regular_Grid import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -25,23 +26,23 @@ class TestDataAssimilation extends JdbcTestCase { Logger logger = LoggerFactory.getLogger(TestDataAssimilation.class) @Test - void testSimulation() { + void testSimulation(@TempDir File tempDir) { logger.info('Start Test for Data Assimilation') // Path folder containing all the necessary data for this test - String workingFolder = TestDataAssimilation.class.getResource("dataAssimilation/").getPath() + File workingFolder = new File(TestDataAssimilation.class.getResource("dataAssimilation").toURI()) new All_Possible_Configuration().exec(connection, [ "trafficValues" : "0.01, 1.0, 2.0", "temperatureValues": "10, 15, 20" ]) new Export_Table().exec(connection, [ - "exportPath":"./target/ALL_CONFIGURATIONS.csv", // receivers + "exportPath": new File(tempDir, "ALL_CONFIGURATIONS.csv").getAbsolutePath(), // receivers "tableToExport":"ALL_CONFIGURATIONS" ]) new Import_File().exec(connection,[ - "pathFile" : workingFolder+"device_mapping_sf.geojson", + "pathFile" : new File(workingFolder, "device_mapping_sf.geojson").getAbsolutePath(), "inputSRID" : 2056, "tableName": "SENSORS_LOCATION" @@ -51,11 +52,11 @@ class TestDataAssimilation extends JdbcTestCase { "startDate" : "2024-08-25 06:30:00", "endDate" : "2024-08-25 07:30:00", "trainingRatio": 0.8, - "workingFolder": workingFolder, + "workingFolder": workingFolder.getAbsolutePath(), "targetSRID" : 2056 ]) new Import_OSM().exec(connection, [ - "pathFile" : workingFolder + "geneva.osm.pbf", + "pathFile" : new File(workingFolder , "geneva.osm.pbf").getAbsolutePath(), "targetSRID" : 2056, "ignoreGround" : true, "ignoreBuilding": false, @@ -72,7 +73,8 @@ class TestDataAssimilation extends JdbcTestCase { "tableBuilding": "BUILDINGS", "tableReceivers": "SENSORS_LOCATION", "confExportSourceId": false, - "confMaxSrcDist": 500, + "confMaxSrcDist": 50, + "confMaxError": 3, "confDiffVertical": false, "confDiffHorizontal": true ]) @@ -110,7 +112,8 @@ class TestDataAssimilation extends JdbcTestCase { "tableBuilding": "BUILDINGS", "tableReceivers": "RECEIVERS", "confExportSourceId": false, - "confMaxSrcDist": 200, + "confMaxSrcDist": 50, + "confMaxError": 3, "confDiffVertical": false, "confDiffHorizontal": true ]) diff --git a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestDatabaseManager.groovy b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestDatabaseManager.groovy similarity index 76% rename from wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestDatabaseManager.groovy rename to noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestDatabaseManager.groovy index 61b2b7697..3ed9e424d 100644 --- a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestDatabaseManager.groovy +++ b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestDatabaseManager.groovy @@ -10,22 +10,27 @@ * */ -package org.noise_planet.noisemodelling.wps +package org.noise_planet.noisemodelling.scripts +import groovy.sql.Sql import org.h2gis.functions.io.shp.SHPRead -import org.junit.Test +import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.MultiPoint -import org.noise_planet.noisemodelling.wps.Database_Manager.Add_Primary_Key -import org.noise_planet.noisemodelling.wps.Database_Manager.Clean_Database -import org.noise_planet.noisemodelling.wps.Database_Manager.Display_Database -import org.noise_planet.noisemodelling.wps.Database_Manager.Drop_a_Table -import org.noise_planet.noisemodelling.wps.Database_Manager.Table_Visualization_Data -import org.noise_planet.noisemodelling.wps.Database_Manager.Table_Visualization_Map +import org.noise_planet.noisemodelling.scripts.Database_Manager.Add_Primary_Key +import org.noise_planet.noisemodelling.scripts.Database_Manager.Clean_Database +import org.noise_planet.noisemodelling.scripts.Database_Manager.Display_Database +import org.noise_planet.noisemodelling.scripts.Database_Manager.Drop_a_Table +import org.noise_planet.noisemodelling.scripts.Database_Manager.Table_Visualization_Data +import org.noise_planet.noisemodelling.scripts.Database_Manager.Table_Visualization_Map +import org.noise_planet.noisemodelling.webserver.utilities.Logging import org.slf4j.Logger import org.slf4j.LoggerFactory import java.sql.Statement +import static org.junit.jupiter.api.Assertions.assertEquals +import static org.junit.jupiter.api.Assertions.assertTrue + /** * Test parsing of zip file using H2GIS database */ @@ -92,7 +97,7 @@ class TestDatabaseManager extends JdbcTestCase { @Test void testDisplayTables1() { SHPRead.importTable(connection, TestDatabaseManager.getResource("buildings.shp").getPath()) - String res = new Display_Database().exec(connection, []) + String res = new Display_Database().exec(connection, ["showColumns":false]) assertEquals("BUILDINGS

    ", res) } @@ -113,4 +118,13 @@ class TestDatabaseManager extends JdbcTestCase { assertTrue(res.contains("The srid of the table is 2154")) assertTrue(res.contains("POINT Z(223495.9880411485 6757167.98900822 0)")) } + + + @Test + void testConsoleDisplayTable() { + SHPRead.importTable(connection, TestDatabaseManager.getResource("buildings.shp").getPath()) + def area = 50 + def result = Logging.formatSqlQueryResult(new Sql(connection), "SELECT * FROM BUILDINGS WHERE ST_AREA(THE_GEOM) > $area LIMIT 5", 120) + assertTrue(result.contains("ID_WAY")) + } } diff --git a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestDynamic.groovy b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestDynamic.groovy similarity index 87% rename from wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestDynamic.groovy rename to noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestDynamic.groovy index 79d6494c0..2e46f0e86 100644 --- a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestDynamic.groovy +++ b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestDynamic.groovy @@ -1,22 +1,28 @@ -package org.noise_planet.noisemodelling.wps +package org.noise_planet.noisemodelling.scripts import groovy.sql.Sql +import org.h2gis.api.EmptyProgressVisitor import org.h2gis.utilities.JDBCUtilities +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir; + +import static org.junit.jupiter.api.Assertions.* import org.noise_planet.noisemodelling.jdbc.NoiseMapDatabaseParameters -import org.noise_planet.noisemodelling.wps.Acoustic_Tools.Create_Isosurface; -import org.noise_planet.noisemodelling.wps.Acoustic_Tools.DynamicIndicators; -import org.noise_planet.noisemodelling.wps.Database_Manager.Add_Primary_Key; -import org.noise_planet.noisemodelling.wps.Dynamic.Flow_2_Noisy_Vehicles; -import org.noise_planet.noisemodelling.wps.Dynamic.Ind_Vehicles_2_Noisy_Vehicles; -import org.noise_planet.noisemodelling.wps.Dynamic.Noise_From_Attenuation_Matrix; -import org.noise_planet.noisemodelling.wps.Dynamic.Point_Source_From_Network -import org.noise_planet.noisemodelling.wps.Dynamic.Split_Sources_Period; -import org.noise_planet.noisemodelling.wps.Geometric_Tools.Set_Height -import org.noise_planet.noisemodelling.wps.Import_and_Export.Export_Table; -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_File; -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_OSM; -import org.noise_planet.noisemodelling.wps.NoiseModelling.Noise_level_from_source -import org.noise_planet.noisemodelling.wps.Receivers.Regular_Grid +import org.noise_planet.noisemodelling.scripts.Acoustic_Tools.Create_Isosurface; +import org.noise_planet.noisemodelling.scripts.Acoustic_Tools.DynamicIndicators; +import org.noise_planet.noisemodelling.scripts.Database_Manager.Add_Primary_Key; +import org.noise_planet.noisemodelling.scripts.Dynamic.Flow_2_Noisy_Vehicles; +import org.noise_planet.noisemodelling.scripts.Dynamic.Ind_Vehicles_2_Noisy_Vehicles; +import org.noise_planet.noisemodelling.scripts.Dynamic.Noise_From_Attenuation_Matrix; +import org.noise_planet.noisemodelling.scripts.Dynamic.Point_Source_From_Network +import org.noise_planet.noisemodelling.scripts.Dynamic.Split_Sources_Period; +import org.noise_planet.noisemodelling.scripts.Geometric_Tools.Set_Height +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Export_Table; +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_File; +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_OSM; +import org.noise_planet.noisemodelling.scripts.NoiseModelling.Noise_level_from_source +import org.noise_planet.noisemodelling.scripts.NoiseModelling.Road_Emission_from_Traffic +import org.noise_planet.noisemodelling.scripts.Receivers.Regular_Grid class TestDynamic extends JdbcTestCase { @@ -24,13 +30,14 @@ class TestDynamic extends JdbcTestCase { /** * as SUMO or SYMUVIA or Drone input */ + @Test void testDynamicIndividualVehiclesTutorial() { // Import Buildings for your study area new Import_File().exec(connection, ["pathFile" : TestDatabaseManager.getResource("Dynamic/buildings_nm_ready_pop_heights.shp").getPath() , "inputSRID": "32635", - "tableName": "buildings"]) + "tableName": "buildings"], new EmptyProgressVisitor()) // Import the receivers (or generate your set of receivers using Regular_Grid script for example) new Import_File().exec(connection, @@ -114,6 +121,7 @@ class TestDynamic extends JdbcTestCase { /** * as OSM input */ + @Test void testDynamicFlowTutorialProbabilisticWithAttenuationMatrix() { // Import the road network (with predicted traffic flows) and buildings from an OSM file @@ -181,6 +189,7 @@ class TestDynamic extends JdbcTestCase { /** * as OSM input */ + @Test void testDynamicFlowTutorialProba() { // Import the road network (with predicted traffic flows) and buildings from an OSM file @@ -249,13 +258,8 @@ class TestDynamic extends JdbcTestCase { /** * as OSM input */ - void testDynamicFlowTutorialPoisson() { - - File tutorialOutputFolder = new File("build/tmp/TUTO_DYNAMIC_POISSON/") - - if(!tutorialOutputFolder.exists()) { - assertTrue(tutorialOutputFolder.mkdir()) - } + @Test + void testDynamicFlowTutorialPoisson(@TempDir File tutorialOutputFolder) { // Import the road network (with predicted traffic flows) and buildings from an OSM file new Import_OSM().exec(connection, [ @@ -280,24 +284,19 @@ class TestDynamic extends JdbcTestCase { // Create a receiver grid new Regular_Grid().exec(connection, [ "fenceTableName": "ROADS", - "delta" : 25, + "delta" : 15, + "height": 1.5, "outputTriangleTable" : true]) - // Set a height to the receivers at 1.5 m - new Set_Height().exec(connection, - [ "tableName":"RECEIVERS", - "height": 1.5 - ]) - // From the network with traffic flow to individual trajectories with associated Lw using the Poisson method // This method place the vehicles on the network according to the traffic flow following a poisson law // It keeps a coherence in the time series of the noise level new Flow_2_Noisy_Vehicles().exec(connection, ["tableRoads": "ROADS", - "method" : "POISSON", + "method" : "TNP", "timestep" : 1, "duration" : 60, - "gridStep" : 8]) + "gridStep" : 10]) assertTrue(JDBCUtilities.tableExists(connection, "SOURCES_EMISSION")) assertTrue(JDBCUtilities.tableExists(connection, "SOURCES_GEOM")) @@ -312,7 +311,7 @@ class TestDynamic extends JdbcTestCase { "tableSourcesEmission": "SOURCES_EMISSION", "tableReceivers" : "RECEIVERS", "maxError" : 3.0, - "confMaxSrcDist" : 800, + "confMaxSrcDist" : 200, "confDiffHorizontal" : true, "confReflOrder" : 0 ]) @@ -357,6 +356,7 @@ class TestDynamic extends JdbcTestCase { /** * as MATSIM input */ + @Test void testDynamicFluctuatingFlowTutorial() { // Import Buildings for your study area @@ -384,19 +384,22 @@ class TestDynamic extends JdbcTestCase { "sourceIndexFieldName" : "LINK_ID", "sourcePeriodFieldName" : "TIME"]) + new Road_Emission_from_Traffic().exec(connection, + ["tableRoads": "SOURCES_EMISSION"]) + // Compute the noise level from the network sources for each time period new Noise_level_from_source().exec(connection, ["tableBuilding" : "BUILDINGS", - "tableSources" : "SOURCES_GEOM", - "tableEmission" : "SOURCES_EMISSION", - "tableReceivers": "RECEIVERS", - "confDiffHorizontal" : true, - "confReflOrder" : 0 + "tableSources" : "SOURCES_GEOM", + "tableSourcesEmission" : "LW_ROADS", + "tableReceivers": "RECEIVERS", + "confDiffHorizontal" : true, + "confReflOrder" : 0 ]) def columnNames = JDBCUtilities.getColumnNames(connection, "RECEIVERS_LEVEL") - columnNames.containsAll(Arrays.asList("PERIOD", "LAEQ")) + assertTrue(columnNames.containsAll(Arrays.asList("PERIOD", "LAEQ"))) } diff --git a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestGeometricTools.groovy b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestGeometricTools.groovy similarity index 68% rename from wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestGeometricTools.groovy rename to noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestGeometricTools.groovy index 597f41b0b..d533752a0 100644 --- a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestGeometricTools.groovy +++ b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestGeometricTools.groovy @@ -10,23 +10,27 @@ * */ -package org.noise_planet.noisemodelling.wps +package org.noise_planet.noisemodelling.scripts import groovy.sql.Sql import org.h2gis.functions.io.shp.SHPRead import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation -import org.junit.Test -import org.noise_planet.noisemodelling.wps.Geometric_Tools.Change_SRID -import org.noise_planet.noisemodelling.wps.Geometric_Tools.Clean_Buildings_Table -import org.noise_planet.noisemodelling.wps.Geometric_Tools.Enrich_DEM_with_road -import org.noise_planet.noisemodelling.wps.Geometric_Tools.Screen_to_building -import org.noise_planet.noisemodelling.wps.Geometric_Tools.Set_Height -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_Asc_File -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_File +import org.junit.jupiter.api.Test; +import org.noise_planet.noisemodelling.scripts.Geometric_Tools.Change_SRID +import org.noise_planet.noisemodelling.scripts.Geometric_Tools.Clean_Buildings_Table +import org.noise_planet.noisemodelling.scripts.Geometric_Tools.Enrich_DEM_with_road +import org.noise_planet.noisemodelling.scripts.Geometric_Tools.Screen_to_building +import org.noise_planet.noisemodelling.scripts.Geometric_Tools.Set_Height +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_Asc_File +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_File import org.slf4j.Logger import org.slf4j.LoggerFactory + +import static org.junit.jupiter.api.Assertions.assertEquals +import static org.junit.jupiter.api.Assertions.assertTrue + /** * Test parsing of zip file using H2GIS database */ @@ -97,12 +101,12 @@ class TestGeometricTools extends JdbcTestCase { void testSetHeight2() { SHPRead.importTable(connection, TestGeometricTools.getResource("roads.shp").getPath()) def sql = new Sql(connection) - + def srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse("ROADS")) new Set_Height().exec(connection, ["height": 0.05, "tableName": "roads"]) - assertEquals(0.05, sql.firstRow("SELECT ST_Z(THE_GEOM) FROM ROADS")[0]) + assertEquals(srid, GeometryTableUtilities.getSRID(connection, TableLocation.parse("ROADS"))) } @Test @@ -117,6 +121,61 @@ class TestGeometricTools extends JdbcTestCase { assertEquals(0, sql.firstRow("select COUNT(*) COUNTINTERS FROM buildings S1, buildings S2 WHERE ST_AREA(S1.THE_GEOM) < ST_AREA(S2.THE_GEOM) AND S1.THE_GEOM && S2.THE_GEOM AND ST_DISTANCE(S1.THE_GEOM, S2.THE_GEOM) <= 0.05;")[0] as Integer) } + void testSetHeightByColumnName1() { + new Import_File().exec(connection,[ + "pathFile": TestGeometricTools.getResource("dem_test_height.geojson").getPath(), + "tableName": "DEM" + ]) + def sql = new Sql(connection) + new Set_Height().exec(connection, + ["tableName": "DEM", + "heightColumn": "ELEVATION"]) + + assertEquals( + 71.0, + sql.firstRow("SELECT ST_Z(THE_GEOM) AS z FROM DEM WHERE ID=41.0")[0] + ) + assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("DEM"))) + } + + @Test + void testSetHeightByColumnName2() { + def sql = new Sql(connection) + sql.execute(""" + CREATE TABLE RECEIVER ( + ID INT PRIMARY KEY, + THE_GEOM GEOMETRY, + ELEVATION DOUBLE + ) + """) + sql.execute(""" + INSERT INTO RECEIVER (ID, THE_GEOM, ELEVATION) VALUES + (1, ST_GeomFromText('POINT(654305.1 6853353.699999999)'), 12), + (2, ST_GeomFromText('POINT(654330.1 6853353.699999999)'), 57), + (3, ST_GeomFromText('POINT(654355.1 6853353.699999999)'), 89), + (4, ST_GeomFromText('POINT(654380.1 6853353.699999999)'), 10), + (5, ST_GeomFromText('POINT(654405.1 6853353.699999999)'), 25), + (6, ST_GeomFromText('POINT(654430.1 6853353.699999999)'), 0) + """) + + new Change_SRID().exec(connection,[ + "newSRID":2154, + "tableName":"RECEIVER" + ]) + + new Set_Height().exec(connection, [ + 'tableName': 'RECEIVER', + 'heightColumn': 'ELEVATION' + ]) + + def row = sql.firstRow("SELECT ST_Z(THE_GEOM) AS z FROM RECEIVER WHERE ID=2") + double actual = row.z + + assertEquals(57.0, actual) + + + } + @Test void testCleanBuildingsPop() { SHPRead.importTable(connection, TestGeometricTools.getResource("buildings.shp").getPath()) @@ -141,6 +200,7 @@ class TestGeometricTools extends JdbcTestCase { assertEquals(2154, srid2) } + @Test void testEnrichRoad() { new Import_Asc_File().exec(connection, diff --git a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestImportExport.groovy b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestImportExport.groovy similarity index 65% rename from wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestImportExport.groovy rename to noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestImportExport.groovy index 368a3539e..0194c5f18 100644 --- a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestImportExport.groovy +++ b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestImportExport.groovy @@ -10,26 +10,25 @@ * */ -package org.noise_planet.noisemodelling.wps +package org.noise_planet.noisemodelling.scripts import groovy.sql.Sql +import org.h2gis.api.EmptyProgressVisitor import org.h2gis.functions.io.shp.SHPRead -import org.junit.Assert -import org.junit.Test -import org.noise_planet.noisemodelling.wps.Database_Manager.Display_Database -import org.noise_planet.noisemodelling.wps.Database_Manager.Table_Visualization_Data -import org.noise_planet.noisemodelling.wps.Database_Manager.Table_Visualization_Map -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_Asc_Folder -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_OSM -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_OSM_Pedestrian -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_Symuvia -import org.noise_planet.noisemodelling.wps.Import_and_Export.Export_Table -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_Asc_File -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_File -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_Folder +import org.junit.jupiter.api.Assumptions +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir +import org.noise_planet.noisemodelling.scripts.Database_Manager.Display_Database +import org.noise_planet.noisemodelling.scripts.Database_Manager.Table_Visualization_Data +import org.noise_planet.noisemodelling.scripts.Database_Manager.Table_Visualization_Map +import org.noise_planet.noisemodelling.scripts.Import_and_Export.* import org.slf4j.Logger import org.slf4j.LoggerFactory +import javax.sql.DataSource +import java.sql.Connection + +import static org.junit.jupiter.api.Assertions.* /** * Test parsing of zip file using H2GIS database */ @@ -39,15 +38,16 @@ class TestImportExport extends JdbcTestCase { @Test void testImportSymuvia() { // Check empty database - Object res = new Display_Database().exec(connection, []) + Object res = new Display_Database().exec(connection, ["showColumns":true]) + + assertTrue(res.contains("Database is Empty")) - assertEquals("", res) // Import OSM file new Import_Symuvia().exec(connection, ["pathFile" : TestImportExport.getResource("symuvia.xml").getPath(), "defaultSRID": 2154]) - res = new Display_Database().exec(connection, []) + res = new Display_Database().exec(connection, ["showColumns":true]) assertTrue(res.contains("SYMUVIA_TRAJ")) @@ -58,12 +58,12 @@ class TestImportExport extends JdbcTestCase { @Test void testImportFile1() { - String res = new Import_File().exec(connection, + Map res = new Import_File().exec(connection, ["pathFile" : TestImportExport.getResource("receivers.shp").getPath(), "inputSRID": "2154", "tableName": "receivers"]) - assertEquals("The table RECEIVERS has been uploaded to database!", res) + assertEquals("RECEIVERS", res.outputTable) } @Test @@ -76,7 +76,7 @@ class TestImportExport extends JdbcTestCase { } catch (Exception e) { String expectedMessage = "ERROR : The table already has a different SRID than the one you gave."; - Assert.assertEquals("Exception message must be correct", expectedMessage, e.getMessage()); + assertEquals(expectedMessage, e.getMessage(), "Exception message must be correct"); } } @@ -133,10 +133,10 @@ class TestImportExport extends JdbcTestCase { } @Test - void testExportFile() { + void testExportFile(@TempDir File temp) { // Check export geojson - File testPath = new File("build/tmp/test.geojson") + File testPath = new File(temp, "test.geojson") if (testPath.exists()) { testPath.delete() @@ -145,12 +145,13 @@ class TestImportExport extends JdbcTestCase { SHPRead.importTable(connection, TestImportExport.getResource("receivers.shp").getPath()) String res = new Export_Table().exec(connection, - ["exportPath" : "build/tmp/test.geojson", + ["exportPath" : testPath.absolutePath, "tableToExport": "RECEIVERS"]) assertTrue(res.contains("RECEIVERS")) - assertTrue(res.contains("2154")) + // Check if the file exists + assertTrue(testPath.exists()) } @Test @@ -160,7 +161,7 @@ class TestImportExport extends JdbcTestCase { "pathFile" : TestImportExport.getResource("map.osm.pbf").getPath(), "targetSRID" : 2154 ]); - String res = new Display_Database().exec(connection, []) + String res = new Display_Database().exec(connection, ["showColumns":false]) assertEquals("BUILDINGS

    GROUND

    PEDESTRIAN_AREA

    PEDESTRIAN_POIS

    PEDESTRIAN_WAYS

    ", res) @@ -177,7 +178,7 @@ class TestImportExport extends JdbcTestCase { "ignoreRoads" : false, "removeTunnels" : true ]); - String res = new Display_Database().exec(connection, []) + String res = new Display_Database().exec(connection, ["showColumns":false]) assertEquals("BUILDINGS

    GROUND

    ROADS

    ", res) @@ -195,9 +196,36 @@ class TestImportExport extends JdbcTestCase { "ignoreRoads" : false, "removeTunnels" : true ]); - String res = new Display_Database().exec(connection, []) + String res = new Display_Database().exec(connection, ["showColumns":false]) assertEquals("BUILDINGS

    GROUND

    ROADS

    ", res) } + + /** + * Test Linked_Table with external PostGIS database POSTGRES_HOST must be defined + */ + @Test + void testLinkedTable() { + PostgisParameters parameters = getPostGISParametersFromEnv() + Assumptions.assumeTrue(parameters != null, "POSTGRES_HOST is not defined, skipping Linked_Table test") + try(DataSource pgDataSource = createPostgisDataSource(parameters)) { + // Send data + try (Connection postgisConnection = pgDataSource.getConnection()) { + postgisConnection.createStatement().execute("DROP TABLE IF EXISTS RECEIVERS") + SHPRead.importTable(postgisConnection, TestImportExport.getResource("receivers.shp").getPath()) + } + new Linked_Table().exec(connection, [ + localTableName: "RECEIVERS", + databaseUrl: "jdbc:postgresql_h2://$parameters.host:$parameters.port/$parameters.database", + username: parameters.user, + password: parameters.password, + remoteTableName: 'receivers'], new EmptyProgressVisitor()) + + // Read on the H2GIS side the receivers table stored in the PostGIS database + Sql sql = new Sql(connection) + int cpt = sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS")[0] as Integer + assertEquals(830, cpt) + } + } } diff --git a/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestNoiseModelling.groovy b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestNoiseModelling.groovy new file mode 100644 index 000000000..2cbdad888 --- /dev/null +++ b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestNoiseModelling.groovy @@ -0,0 +1,258 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + +package org.noise_planet.noisemodelling.scripts + +import groovy.sql.Sql +import org.h2.value.ValueBoolean +import org.h2gis.functions.io.shp.SHPRead +import org.h2gis.utilities.JDBCUtilities +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir +import org.noise_planet.noisemodelling.jdbc.NoiseMapDatabaseParameters +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_File +import org.noise_planet.noisemodelling.scripts.NoiseModelling.* +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import static org.junit.jupiter.api.Assertions.* +/** + * Test parsing of zip file using H2GIS database + */ +class TestNoiseModelling extends JdbcTestCase { + Logger LOGGER = LoggerFactory.getLogger(TestNoiseModelling.class) + + + @Test + void testRoadEmissionFromDEN() { + + new Import_File().exec(connection, + ["pathFile" : TestNoiseModelling.getResource("ROADS2.shp").getPath()]) + + String res = new Road_Emission_from_Traffic().exec(connection, + ["tableRoads": "ROADS2"]).result + + assertEquals("LW_ROADS", res) + + def fieldNames = JDBCUtilities.getColumnNames(connection, "LW_ROADS") + + def expectedOctaveFields = ["PK","THE_GEOM","HZD63","HZD125","HZD250","HZD500","HZD1000","HZD2000","HZD4000","HZD8000", + "HZE63","HZE125","HZE250","HZE500","HZE1000","HZE2000","HZE4000","HZE8000", + "HZN63","HZN125","HZN250","HZN500","HZN1000","HZN2000","HZN4000","HZN8000"] + + assertArrayEquals(expectedOctaveFields.toArray(new String[expectedOctaveFields.size()]), fieldNames.toArray(new String[fieldNames.size()])) + + } + + @Test + void testRailWayEmissionFromDEN(@TempDir File temp) { + + def sql = new Sql(connection) + + sql.execute("DROP TABLE IF EXISTS LW_RAILWAY") + + + new Import_File().exec(connection, + ["pathFile" : TestNoiseModelling.getResource("Train/RAIL_SECTIONS.shp").getPath(), + "inputSRID": "2154"]) + + new Import_File().exec(connection, + ["pathFile" : TestNoiseModelling.getResource("Train/RAIL_TRAFFIC.dbf").getPath(), + "inputSRID": "2154"]) + + new Import_File().exec(connection, + ["pathFile" : TestNoiseModelling.getResource("Train/receivers_Railway_.shp").getPath(), + "inputSRID": "2154", + "tableName" : "RECEIVERS"]) + + new Railway_Emission_from_Traffic().exec(connection, + ["tableRailwayTraffic": "RAIL_TRAFFIC", + "tableRailwayTrack": "RAIL_SECTIONS" + ]) + + def fieldNames = JDBCUtilities.getColumnNames(connection, "LW_RAILWAY") + + def expected = ["PK_SECTION","THE_GEOM","DIR_ID","GS","HZD50","HZD63","HZD80","HZD100","HZD125", + "HZD160","HZD200","HZD250","HZD315","HZD400","HZD500","HZD630","HZD800","HZD1000","HZD1250", + "HZD1600","HZD2000","HZD2500","HZD3150","HZD4000","HZD5000","HZD6300","HZD8000","HZD10000", + "HZE50","HZE63","HZE80","HZE100","HZE125","HZE160","HZE200","HZE250","HZE315","HZE400", + "HZE500","HZE630","HZE800","HZE1000","HZE1250","HZE1600","HZE2000","HZE2500","HZE3150", + "HZE4000","HZE5000","HZE6300","HZE8000","HZE10000","HZN50","HZN63","HZN80","HZN100","HZN125", + "HZN160","HZN200","HZN250","HZN315","HZN400","HZN500","HZN630","HZN800","HZN1000","HZN1250", + "HZN1600","HZN2000","HZN2500","HZN3150","HZN4000","HZN5000","HZN6300","HZN8000","HZN10000","PK"] + + assertArrayEquals(expected.toArray(new String[expected.size()]), fieldNames.toArray(new String[fieldNames.size()])) + + + SHPRead.importTable(connection, TestDatabaseManager.getResource("Train/buildings2.shp").getPath(), + "BUILDINGS", ValueBoolean.TRUE) + + sql.execute("DROP TABLE IF EXISTS LDAY_GEOM") + + new Noise_level_from_source().exec(connection, + ["tableBuilding" : "BUILDINGS", + "tableSources" : "LW_RAILWAY", + "tableReceivers": "RECEIVERS", + "confMaxSrcDist": 500, + "confMaxError" : 5.0]) + + assertTrue(JDBCUtilities.tableExists(connection, NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME)) + + def receiversCount = sql.rows("SELECT COUNT(*) CPT FROM "+ + NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME+" WHERE PERIOD = 'D'") + + assertEquals(688, receiversCount[0]["CPT"] as Integer) + } + + @Test + void testLdenFromEmission1khz() { + + new Import_File().exec(connection, + ["pathFile" : TestNoiseModelling.getResource("ROADS2.shp").getPath()]) + + new Road_Emission_from_Traffic().exec(connection, + ["tableRoads": "ROADS2"]) + + // select only 1khz band + Sql sql = new Sql(connection) + + sql.execute("CREATE TABLE LW_ROADS2(pk serial primary key, the_geom geometry, HZD1000 double) as select pk, the_geom, HZd1000 from LW_ROADS") + + new Import_File().exec(connection, + ["pathFile" : TestNoiseModelling.getResource("buildings.shp").getPath(), + "inputSRID": "2154", + "tableName": "buildings"]) + + new Import_File().exec(connection, + ["pathFile" : TestNoiseModelling.getResource("receivers.shp").getPath(), + "inputSRID": "2154", + "tableName": "receivers"]) + + + String res = new Noise_level_from_source().exec(connection, + ["tableBuilding" : "BUILDINGS", + "tableSources" : "LW_ROADS2", + "tableReceivers": "RECEIVERS"]) + + assertTrue(res.contains(NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME)) + + // fetch columns + def fields = JDBCUtilities.getColumnNames(connection, NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME) + + assertArrayEquals(["IDRECEIVER","PERIOD","THE_GEOM", "HZ1000", "LAEQ", "LEQ"].toArray(), fields.toArray()) + } + + @Test + void testAtmosphericSettings() { + + Sql sql = new Sql(connection) + + sql.execute( + $/CREATE TABLE SOURCES_EMISSION( + IDSOURCE INTEGER NOT NULL, + PERIOD VARCHAR, + HZ500 DOUBLE); + /$) + + sql.executeInsert("INSERT INTO SOURCES_EMISSION VALUES (1, 'D', 90.0), (1, 'E', 92.0), (1, 'N', 93.0);"); + + new Atmospheric_Template().exec(connection, ["tableSourcesEmission": "SOURCES_EMISSION"]) + + assertTrue(JDBCUtilities.tableExists(connection, "SOURCES_ATMOSPHERIC")) + + + List periods = JDBCUtilities.getUniqueFieldValues(connection, "SOURCES_ATMOSPHERIC", "PERIOD") + + ["D", "E", "N"].forEach { + assertTrue(periods.contains(it)) + } + } + + @Test + void testNoiseEmissionFromPeriod() { + new Import_File().exec(connection, + ["pathFile" : TestNoiseModelling.getResource("ROADS2.shp").getPath()]) + + // Create SOURCES_EMISSION table by splitting the LW_ROADS table old format period to separate lines + + Sql sql = new Sql(connection) + sql.execute("DROP TABLE IF EXISTS SOURCES_EMISSION") + sql.execute("CREATE TABLE SOURCES_EMISSION AS SELECT PK AS IDSOURCE, 'D' AS PERIOD," + + " TV_D as TV, HV_D as HV, LV_SPD_D as LV_SPD, HV_SPD_D as HV_SPD," + + " PVMT AS PVMT FROM ROADS2") + sql.execute("INSERT INTO SOURCES_EMISSION SELECT PK AS IDSOURCE, 'E' AS PERIOD," + + " TV_E as TV, HV_E as HV, LV_SPD_E as LV_SPD, HV_SPD_E as HV_SPD," + + " PVMT AS PVMT FROM ROADS2") + sql.execute("INSERT INTO SOURCES_EMISSION SELECT PK AS IDSOURCE, 'N' AS PERIOD," + + " TV_N as TV, HV_N as HV, LV_SPD_N as LV_SPD, HV_SPD_N as HV_SPD," + + " PVMT AS PVMT FROM ROADS2") + + // Convert to road emission + String res = new Road_Emission_from_Traffic().exec(connection, + ["tableRoads": "SOURCES_EMISSION"]).result + + // Check result table + assertEquals("LW_ROADS", res) + + def fieldNames = JDBCUtilities.getColumnNames(connection, "LW_ROADS") + + // Output fields export period in a separate field now + def gotPeriod = JDBCUtilities.getUniqueFieldValues(connection, "LW_ROADS", "PERIOD") + assertEquals(3, gotPeriod.size()) + assertTrue(gotPeriod.contains("D")) + assertTrue(gotPeriod.contains("E")) + assertTrue(gotPeriod.contains("N")) + + LOGGER.info(Arrays.toString(fieldNames.toArray())) + } + + @Test + void testRaysTableAndLineSourceSpacingRatio() { + String RAYS_TABLE = "RAYS" + Double LINE_SOURCE_RATIO = 4.0 + Integer EXPECTED_NB_RAYS = 125716 + + new Import_File().exec(connection, + ["pathFile" : TestNoiseModelling.getResource("ROADS2.shp").getPath()]) + + new Road_Emission_from_Traffic().exec(connection, + ["tableRoads": "ROADS2"]) + + new Import_File().exec(connection, + ["pathFile" : TestNoiseModelling.getResource("buildings.shp").getPath(), + "inputSRID": "2154", + "tableName": "buildings"]) + + new Import_File().exec(connection, + ["pathFile" : TestNoiseModelling.getResource("receivers.shp").getPath(), + "inputSRID": "2154", + "tableName": "receivers"]) + + Sql sql = new Sql(connection) + + new Noise_level_from_source().exec(connection, + ["tableBuilding" : "BUILDINGS", + "tableSources" : "LW_ROADS", + "tableReceivers" : "RECEIVERS", + "confRaysName" : RAYS_TABLE, + "confLineSourceSpacingRatio": LINE_SOURCE_RATIO, + "confReflOrder" : 0, + "confDiffVertical" : false, + "confDiffHorizontal" : false]) + + assertTrue(JDBCUtilities.tableExists(connection, RAYS_TABLE)) + int raysCount = sql.firstRow("SELECT COUNT(*) CPT FROM " + RAYS_TABLE)["CPT"] as Integer + LOGGER.info("number or rays with confLineSourceSpacingRatio = " + LINE_SOURCE_RATIO + " : " + raysCount) + assertEquals(raysCount, EXPECTED_NB_RAYS) + } + +} diff --git a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestReceivers.groovy b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestReceivers.groovy similarity index 66% rename from wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestReceivers.groovy rename to noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestReceivers.groovy index b429e3dbd..483b07fd4 100644 --- a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestReceivers.groovy +++ b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestReceivers.groovy @@ -10,11 +10,13 @@ * */ -package org.noise_planet.noisemodelling.wps +package org.noise_planet.noisemodelling.scripts +import groovy.sql.GroovyRowResult import groovy.sql.Sql import org.h2.value.ValueBoolean import org.h2.value.ValueGeometry +import org.h2gis.functions.io.geojson.GeoJsonRead import org.h2gis.functions.io.shp.SHPRead import org.h2gis.functions.io.shp.SHPWrite import org.h2gis.functions.spatial.crs.ST_SetSRID @@ -22,18 +24,25 @@ import org.h2gis.functions.spatial.crs.ST_Transform import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir import org.locationtech.jts.geom.Envelope import org.locationtech.jts.geom.GeometryFactory -import org.noise_planet.noisemodelling.wps.Geometric_Tools.Clean_Buildings_Table -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_File -import org.noise_planet.noisemodelling.wps.Receivers.Building_Grid -import org.noise_planet.noisemodelling.wps.Receivers.Building_Grid3D -import org.noise_planet.noisemodelling.wps.Receivers.Delaunay_Grid -import org.noise_planet.noisemodelling.wps.Receivers.Random_Grid -import org.noise_planet.noisemodelling.wps.Receivers.Regular_Grid +import org.noise_planet.noisemodelling.scripts.Geometric_Tools.Clean_Buildings_Table +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_File +import org.noise_planet.noisemodelling.scripts.Receivers.Building_Grid +import org.noise_planet.noisemodelling.scripts.Receivers.Building_Grid3D +import org.noise_planet.noisemodelling.scripts.Receivers.Delaunay_Grid +import org.noise_planet.noisemodelling.scripts.Receivers.Random_Grid +import org.noise_planet.noisemodelling.scripts.Receivers.Regular_Grid + +import static org.junit.jupiter.api.Assertions.assertEquals +import static org.junit.jupiter.api.Assertions.assertFalse +import static org.junit.jupiter.api.Assertions.assertTrue class TestReceivers extends JdbcTestCase { + @Test void testBuildingGrid3D() { def sql = new Sql(connection) @@ -42,10 +51,10 @@ class TestReceivers extends JdbcTestCase { sql.execute("CREATE INDEX bheight ON BUILDINGS(height)") - new Building_Grid3D().exec(connection, ["tableBuilding" : "BUILDINGS", - "delta" : 5, - "heightLevels" : 2.5, - "fenceTableName": "BUILDINGS"]) + new Building_Grid3D().exec(connection, ["tableBuilding" : "BUILDINGS", + "delta" : 5, + "heightLevels" : 2.5, + "fenceTableName": "BUILDINGS"]) def receivers_in_buildings = sql.firstRow("SELECT COUNT(*) from receivers r, buildings b where r.the_geom && b.the_geom and st_intersects(r.the_geom, b.the_geom) and ST_Z(r.the_geom) < b.height ")[0] as Integer assertEquals(0, receivers_in_buildings) @@ -63,6 +72,7 @@ class TestReceivers extends JdbcTestCase { } + @Test void testBuildingGrid3DNoFence() { def sql = new Sql(connection) @@ -71,9 +81,9 @@ class TestReceivers extends JdbcTestCase { sql.execute("CREATE INDEX bheight ON BUILDINGS(height)") - new Building_Grid3D().exec(connection, ["tableBuilding" : "BUILDINGS", - "delta" : 5, - "heightLevels" : 2.5]) + new Building_Grid3D().exec(connection, ["tableBuilding": "BUILDINGS", + "delta" : 5, + "heightLevels" : 2.5]) def receivers_in_buildings = sql.firstRow("SELECT COUNT(*) from receivers r, buildings b where r.the_geom && b.the_geom and st_intersects(r.the_geom, b.the_geom) and ST_Z(r.the_geom) < b.height ")[0] as Integer assertEquals(0, receivers_in_buildings) @@ -91,12 +101,13 @@ class TestReceivers extends JdbcTestCase { //Execute a second time for missing drop tables test - new Building_Grid3D().exec(connection, ["tableBuilding" : "BUILDINGS", - "delta" : 5, - "heightLevels" : 2.5]) + new Building_Grid3D().exec(connection, ["tableBuilding": "BUILDINGS", + "delta" : 5, + "heightLevels" : 2.5]) } + @Test void testBuildingGrid3DWithPop() { def sql = new Sql(connection) @@ -105,10 +116,10 @@ class TestReceivers extends JdbcTestCase { sql.execute("CREATE INDEX bheight ON BUILDINGS(height)") sql.execute("ALTER TABLE BUILDINGS ADD COLUMN POP INT DEFAULT RANDOM(20) + 1") - new Building_Grid3D().exec(connection, ["tableBuilding" : "BUILDINGS", - "delta" : 5, - "heightLevels" : 2.5, - "fenceTableName": "BUILDINGS"]) + new Building_Grid3D().exec(connection, ["tableBuilding" : "BUILDINGS", + "delta" : 5, + "heightLevels" : 2.5, + "fenceTableName": "BUILDINGS"]) def receivers_in_buildings = sql.firstRow("SELECT COUNT(*) from receivers r, buildings b where r.the_geom && b.the_geom and st_intersects(r.the_geom, b.the_geom) and ST_Z(r.the_geom) < b.height ")[0] as Integer assertEquals(0, receivers_in_buildings) @@ -125,6 +136,7 @@ class TestReceivers extends JdbcTestCase { } + @Test void testBuildingGrid() { def sql = new Sql(connection) @@ -134,11 +146,11 @@ class TestReceivers extends JdbcTestCase { SHPRead.importTable(connection, TestReceivers.getResource("roads.shp").getPath()) - new Building_Grid().exec(connection, ["tableBuilding" : "BUILDINGS", - "delta" : 5, - "height" : 6, - "sourcesTableName" : "ROADS", - "fenceTableName" : "BUILDINGS"]) + new Building_Grid().exec(connection, ["tableBuilding" : "BUILDINGS", + "delta" : 5, + "height" : 6, + "sourcesTableName": "ROADS", + "fenceTableName" : "BUILDINGS"]) def receivers_in_buildings = sql.firstRow("SELECT COUNT(*) from receivers r, buildings b where r.the_geom && b.the_geom and st_intersects(r.the_geom, b.the_geom) and ST_Z(r.the_geom) < b.height ")[0] as Integer @@ -156,6 +168,7 @@ class TestReceivers extends JdbcTestCase { assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) } + @Test void testBuildingGridWithPop() { def sql = new Sql(connection) @@ -166,11 +179,11 @@ class TestReceivers extends JdbcTestCase { SHPRead.importTable(connection, TestReceivers.getResource("roads.shp").getPath(), ValueBoolean.TRUE) - new Building_Grid().exec(connection, ["tableBuilding" : "BUILDINGS", - "delta" : 5, - "height" : 6, - "sourcesTableName" : "ROADS", - "fenceTableName" : "BUILDINGS"]) + new Building_Grid().exec(connection, ["tableBuilding" : "BUILDINGS", + "delta" : 5, + "height" : 6, + "sourcesTableName": "ROADS", + "fenceTableName" : "BUILDINGS"]) def receivers_pop = sql.firstRow("SELECT sum(pop) from receivers")[0] as Double @@ -182,6 +195,8 @@ class TestReceivers extends JdbcTestCase { assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) } + + @Test void testBuildingGridFence() { def sql = new Sql(connection) @@ -190,17 +205,18 @@ class TestReceivers extends JdbcTestCase { sql.execute("CREATE INDEX bheight ON BUILDINGS(height)") GeometryFactory f = new GeometryFactory(); - def g = f.toGeometry(new Envelope(223556.5, 223765.7,6758256.91, 6758576.3)) + def g = f.toGeometry(new Envelope(223556.5, 223765.7, 6758256.91, 6758576.3)) g.setSRID(2154) def gFence = ST_Transform.ST_Transform(connection, g, 4326) - new Building_Grid().exec(connection, ["tableBuilding" : "BUILDINGS", - "delta" : 5, - "height" : 6, - "fence" : gFence.toString()]) // in WPS Fence is an instance of geoscript.geom.Polygon not jts + new Building_Grid().exec(connection, ["tableBuilding": "BUILDINGS", + "delta" : 5, + "height" : 6, + "fence" : gFence.toString()]) + // in WPS Fence is an instance of geoscript.geom.Polygon not jts assertTrue(sql.firstRow("SELECT count(*) cpt from receivers")[0] > 0) - def receivers_pop = sql.firstRow("SELECT count(*) cpt from receivers r where not ST_Intersects(r.the_geom, :g)", [g : g])[0] as Integer + def receivers_pop = sql.firstRow("SELECT count(*) cpt from receivers r where not ST_Intersects(r.the_geom, :g)", [g: g])[0] as Integer assertEquals(0, receivers_pop); @@ -209,6 +225,7 @@ class TestReceivers extends JdbcTestCase { } + @Test void testDelaunayGridReduceExtent() { def sql = new Sql(connection) @@ -217,8 +234,8 @@ class TestReceivers extends JdbcTestCase { sql.execute("CREATE SPATIAL INDEX ON BUILDINGS(THE_GEOM)") sql.execute("CREATE SPATIAL INDEX ON ROADS(THE_GEOM)") - new Delaunay_Grid().exec(connection, ["buildingTableName": "BUILDINGS", - "sourcesTableName" : "ROADS", + new Delaunay_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", + "sourcesTableName" : "ROADS", "fenceNegativeBuffer": 500]); @@ -227,6 +244,7 @@ class TestReceivers extends JdbcTestCase { assertEquals(1127409.17, envelope.getArea(), 1.0) } + @Test void testDelaunayGrid() { def sql = new Sql(connection) @@ -235,8 +253,9 @@ class TestReceivers extends JdbcTestCase { sql.execute("CREATE SPATIAL INDEX ON BUILDINGS(THE_GEOM)") sql.execute("CREATE SPATIAL INDEX ON ROADS(THE_GEOM)") - new Delaunay_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", - "sourcesTableName" : "ROADS"]); + new Delaunay_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", + "sourcesTableName" : "ROADS", + "exportTrianglesGeometries": true]); assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) @@ -257,6 +276,7 @@ class TestReceivers extends JdbcTestCase { assertEquals(0.0, max_dist_c, 1e-6d); } + @Test void testDelaunayGridTableFence() { def sql = new Sql(connection) @@ -265,14 +285,15 @@ class TestReceivers extends JdbcTestCase { new Import_File().exec(connection, ["pathFile" : TestReceivers.getResource("dem.geojson").getPath(), - "inputSRID" : 2154]) + "inputSRID": 2154]) sql.execute("CREATE SPATIAL INDEX ON BUILDINGS(THE_GEOM)") sql.execute("CREATE SPATIAL INDEX ON ROADS(THE_GEOM)") - new Delaunay_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", - "sourcesTableName" : "ROADS", - "fenceTableName": "DEM"]); + new Delaunay_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", + "sourcesTableName" : "ROADS", + "fenceTableName" : "DEM", + "exportTrianglesGeometries": true]); def geomFence = GeometryTableUtilities.getEstimatedExtent(connection, "DEM", "THE_GEOM") @@ -290,6 +311,7 @@ class TestReceivers extends JdbcTestCase { assertEquals(expectedArea, res["area"], 5) } + @Test void testDelaunayGridClean() { def sql = new Sql(connection) @@ -301,8 +323,9 @@ class TestReceivers extends JdbcTestCase { new Clean_Buildings_Table().exec(connection, ["tableName": "buildings"]) - new Delaunay_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", - "sourcesTableName" : "ROADS"]); + new Delaunay_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", + "sourcesTableName" : "ROADS", + "exportTrianglesGeometries": true]); assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) @@ -320,39 +343,42 @@ class TestReceivers extends JdbcTestCase { assertEquals(0.0, max_dist_c, 1e-6d); } - public void testRandomGrid() { + @Test + void testRandomGrid() { def sql = new Sql(connection) SHPRead.importTable(connection, TestReceivers.getResource("buildings.shp").getPath()) SHPRead.importTable(connection, TestReceivers.getResource("roads.shp").getPath()) - new Random_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", - "sourcesTableName" : "ROADS", - "nReceivers" : 200]) + new Random_Grid().exec(connection, ["buildingTableName": "BUILDINGS", + "sourcesTableName" : "ROADS", + "nReceivers" : 200]) assertTrue(200 >= (sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS")[0] as Integer)) assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) } - public void testRandomGridFence() { + @Test + void testRandomGridFence() { def sql = new Sql(connection) SHPRead.importTable(connection, TestReceivers.getResource("buildings.shp").getPath()) SHPRead.importTable(connection, TestReceivers.getResource("roads.shp").getPath()) - new Random_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", - "sourcesTableName" : "ROADS", - "nReceivers" : 200, - "fenceTableName" : "BUILDINGS"]) + new Random_Grid().exec(connection, ["buildingTableName": "BUILDINGS", + "sourcesTableName" : "ROADS", + "nReceivers" : 200, + "fenceTableName" : "BUILDINGS"]) assertTrue(200 >= (sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS")[0] as Integer)) assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) } - public void testRandomGridFence2() { + @Test + void testRandomGridFence2() { def sql = new Sql(connection) @@ -365,22 +391,23 @@ class TestReceivers extends JdbcTestCase { def gFence = ST_Transform.ST_Transform(connection, g, 4326) - new Random_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", - "sourcesTableName" : "ROADS", - "nReceivers" : 200, - "fence" : gFence.toString()]) + new Random_Grid().exec(connection, ["buildingTableName": "BUILDINGS", + "sourcesTableName" : "ROADS", + "nReceivers" : 200, + "fence" : gFence.toString()]) assertFalse(0 == sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS")[0] as Integer) - assertEquals(0, sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS WHERE NOT ST_INTERSECTS(THE_GEOM, :geom)", [geom : g])[0] as Integer) + assertEquals(0, sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS WHERE NOT ST_INTERSECTS(THE_GEOM, :geom)", [geom: g])[0] as Integer) - assertEquals(0, sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS WHERE ST_INTERSECTS(THE_GEOM, :gNoReceiver)", [gNoReceiver : gNoReceiver])[0] as Integer) + assertEquals(0, sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS WHERE ST_INTERSECTS(THE_GEOM, :gNoReceiver)", [gNoReceiver: gNoReceiver])[0] as Integer) assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) } - public void testRegularGridFence() { + @Test + void testRegularGridFence() { def sql = new Sql(connection) @@ -388,34 +415,36 @@ class TestReceivers extends JdbcTestCase { SHPRead.importTable(connection, TestReceivers.getResource("roads.shp").getPath()) GeometryFactory f = new GeometryFactory(); - def g = f.toGeometry(new Envelope(223556.5, 223765.7,6758256.91, 6758576.3)) + def g = f.toGeometry(new Envelope(223556.5, 223765.7, 6758256.91, 6758576.3)) def gFence = ST_Transform.ST_Transform(connection, ST_SetSRID.setSRID(g, 2154), 4326) - new Regular_Grid().exec(connection, ["buildingTableName": "BUILDINGS", - "sourcesTableName" : "ROADS", - "delta" : 50, - "fence" : gFence.toString()]) + new Regular_Grid().exec(connection, ["buildingTableName": "BUILDINGS", + "sourcesTableName" : "ROADS", + "delta" : 50, + "fence" : gFence.toString()]) assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) } - public void testRegularGridFenceTable() { + @Test + void testRegularGridFenceTable() { def sql = new Sql(connection) SHPRead.importTable(connection, TestReceivers.getResource("buildings.shp").getPath()) SHPRead.importTable(connection, TestReceivers.getResource("roads.shp").getPath()) - new Regular_Grid().exec(connection, ["buildingTableName": "BUILDINGS", - "sourcesTableName" : "ROADS", - "delta" : 50, - "fenceTableName" : "BUILDINGS"]) + new Regular_Grid().exec(connection, ["buildingTableName": "BUILDINGS", + "sourcesTableName" : "ROADS", + "delta" : 50, + "fenceTableName" : "BUILDINGS"]) assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) } - public void testRegularGridFenceGeom() { + @Test + void testRegularGridFenceGeom(@TempDir File temp) { def sql = new Sql(connection) @@ -429,36 +458,90 @@ class TestReceivers extends JdbcTestCase { def gFence = ST_Transform.ST_Transform(connection, g, 4326) - new Regular_Grid().exec(connection, ["buildingTableName" : "BUILDINGS", + new Regular_Grid().exec(connection, ["buildingTableName": "BUILDINGS", "sourcesTableName" : "ROADS", - "delta" : 1, - "fence" : gFence.toString()]) + "delta" : 1, + "fence" : gFence.toString()]) assertFalse(0 == sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS")[0] as Integer) - assertEquals(0, sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS WHERE NOT ST_INTERSECTS(THE_GEOM, :geom)", [geom : g])[0] as Integer) + assertEquals(0, sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS WHERE NOT ST_INTERSECTS(THE_GEOM, :geom)", [geom: g])[0] as Integer) - assertEquals(0, sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS WHERE ST_INTERSECTS(THE_GEOM, :geom)", [geom : gNoReceiver])[0] as Integer) + assertEquals(0, sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS WHERE ST_INTERSECTS(THE_GEOM, :geom)", [geom: gNoReceiver])[0] as Integer) assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) - SHPWrite.exportTable(connection, "build/tmp/regular.shp", "RECEIVERS", ValueBoolean.TRUE) + SHPWrite.exportTable(connection, new File(temp.getAbsoluteFile(), "regular.shp").absolutePath, "RECEIVERS", ValueBoolean.TRUE) } - public void testRegularGridWithTriangleTable() { + @Test + void testRegularGridWithTriangleTable() { def sql = new Sql(connection) SHPRead.importTable(connection, TestReceivers.getResource("buildings.shp").getPath()) SHPRead.importTable(connection, TestReceivers.getResource("roads.shp").getPath()) - new Regular_Grid().exec(connection, ["fenceTableName" : "BUILDINGS", - "delta" : 50, - "outputTriangleTable" : true]) + new Regular_Grid().exec(connection, ["fenceTableName" : "BUILDINGS", + "delta" : 50, + "outputTriangleTable": true]) assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) assertEquals(1920, sql.firstRow("SELECT COUNT(*) FROM TRIANGLES")[0] as Integer) } + + /** + * Fix regression issue, when buffer linestring length is inferior than the delta and the building polygon are in 2D + */ + @Test + void testMissingReceivers() { + def sql = new Sql(connection) + + GeoJsonRead.importTable(connection, TestReceivers.getResource("regression_receivers/SMALL_BUILDING_NORECEIVER.geojson").getPath()) + + // Update the field pk, set it not null and as the primary key of the table + sql.execute("ALTER TABLE SMALL_BUILDING_NORECEIVER ALTER COLUMN pk SET NOT NULL") + sql.execute("ALTER TABLE SMALL_BUILDING_NORECEIVER ADD CONSTRAINT pk_small_building_noreceiver PRIMARY KEY (pk)") + + + new Building_Grid().exec(connection, ["tableBuilding": "SMALL_BUILDING_NORECEIVER", + "delta" : 5]) + assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("RECEIVERS"))) + + Set expected = new HashSet<>(Arrays.asList(1797, 1798, 1800, 1801)) + Set got = new HashSet<>() + sql.rows("SELECT DISTINCT build_pk from RECEIVERS").each { + GroovyRowResult rs -> + got.add(rs["build_pk"] as Integer) + } + assertEquals(expected, got) + + } + + + /** + * Fix regression issue, receivers points should be placed when neighbors buildings have an height inferior than the receiver height + */ + @Test + void testBuildingsReceiversOnTopOfShortBuildings() { + def sql = new Sql(connection) + + GeoJsonRead.importTable(connection, TestReceivers.getResource("regression_receivers/BUILDINGS_RECEIVERS_TOO_CLOSE.geojson").getPath()) + + // Update the field pk, set it not null and as the primary key of the table + sql.execute("ALTER TABLE BUILDINGS_RECEIVERS_TOO_CLOSE ALTER COLUMN pk SET NOT NULL") + sql.execute("ALTER TABLE BUILDINGS_RECEIVERS_TOO_CLOSE ADD CONSTRAINT pk_building PRIMARY KEY (pk)") + + + new Building_Grid().exec(connection, ["tableBuilding": "BUILDINGS_RECEIVERS_TOO_CLOSE", + "delta" : 5, + "distance" : 2]) + + def row = sql.firstRow("SELECT ST_Z(p.the_geom) - b.height relativeHeight, b.pk FROM RECEIVERS P, BUILDINGS_RECEIVERS_TOO_CLOSE B WHERE ST_INTERSECTS(p.the_geom, b.the_geom) ORDER BY relativeHeight") + def minRelativeHeight = row[0] as Double + def buildingId = row[1] as Integer + assertTrue(minRelativeHeight > 0, "Error, receiver should be at least 0 meters (excluded) above the building roof but it is placed at " + minRelativeHeight + " m ! building:" + buildingId) + } } diff --git a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestTutorials.groovy b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestTutorials.groovy similarity index 65% rename from wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestTutorials.groovy rename to noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestTutorials.groovy index e92c245fb..69e22854b 100644 --- a/wps_scripts/src/test/groovy/org/noise_planet/noisemodelling/wps/TestTutorials.groovy +++ b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/TestTutorials.groovy @@ -10,31 +10,31 @@ * */ -package org.noise_planet.noisemodelling.wps +package org.noise_planet.noisemodelling.scripts import groovy.sql.Sql -import org.h2gis.functions.io.shp.SHPRead +import org.h2gis.api.EmptyProgressVisitor import org.h2gis.utilities.GeometryTableUtilities import org.h2gis.utilities.JDBCUtilities import org.h2gis.utilities.TableLocation +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir import org.noise_planet.noisemodelling.jdbc.NoiseMapDatabaseParameters -import org.noise_planet.noisemodelling.wps.Acoustic_Tools.Create_Isosurface -import org.noise_planet.noisemodelling.wps.Database_Manager.Display_Database -import org.noise_planet.noisemodelling.wps.Database_Manager.Table_Visualization_Data -import org.noise_planet.noisemodelling.wps.Experimental_Matsim.Agent_Exposure -import org.noise_planet.noisemodelling.wps.Experimental_Matsim.Import_Activities -import org.noise_planet.noisemodelling.wps.Experimental_Matsim.Noise_From_Attenuation_Matrix_MatSim -import org.noise_planet.noisemodelling.wps.Experimental_Matsim.Receivers_From_Activities_Closest -import org.noise_planet.noisemodelling.wps.Experimental_Matsim.Traffic_From_Events -import org.noise_planet.noisemodelling.wps.Import_and_Export.Export_Table -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_File -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_Folder -import org.noise_planet.noisemodelling.wps.Import_and_Export.Import_OSM -import org.noise_planet.noisemodelling.wps.NoiseModelling.Noise_level_from_source -import org.noise_planet.noisemodelling.wps.NoiseModelling.Noise_level_from_traffic -import org.noise_planet.noisemodelling.wps.Receivers.Building_Grid -import org.noise_planet.noisemodelling.wps.Receivers.Delaunay_Grid -import org.noise_planet.noisemodelling.wps.Receivers.Regular_Grid +import org.noise_planet.noisemodelling.scripts.Acoustic_Tools.Create_Isosurface +import org.noise_planet.noisemodelling.scripts.Database_Manager.Display_Database +import org.noise_planet.noisemodelling.scripts.Database_Manager.Table_Visualization_Data +import org.noise_planet.noisemodelling.scripts.Experimental_Matsim.Agent_Exposure +import org.noise_planet.noisemodelling.scripts.Experimental_Matsim.Import_Activities +import org.noise_planet.noisemodelling.scripts.Experimental_Matsim.Receivers_From_Activities_Closest +import org.noise_planet.noisemodelling.scripts.Experimental_Matsim.Traffic_From_Events +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Export_Table +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_File +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_Folder +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_OSM +import org.noise_planet.noisemodelling.scripts.NoiseModelling.Noise_level_from_source +import org.noise_planet.noisemodelling.scripts.NoiseModelling.Road_Emission_from_Traffic +import org.noise_planet.noisemodelling.scripts.Receivers.Building_Grid +import org.noise_planet.noisemodelling.scripts.Receivers.Delaunay_Grid import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -43,22 +43,21 @@ import java.nio.file.Path import java.nio.file.Paths import java.util.zip.ZipFile -import static org.junit.jupiter.api.Assertions.assertTrue -import static org.junit.jupiter.api.Assertions.assertTrue - +import static org.junit.jupiter.api.Assertions.* /** - * Test parsing of zip file using H2GIS database + * Test the tutorials of the NoiseModelling documentation */ class TestTutorials extends JdbcTestCase { Logger LOGGER = LoggerFactory.getLogger(TestTutorials.class) + @Test void testTutorialGetStarted() { Sql sql = new Sql(connection) // Check empty database - Object res = new Display_Database().exec(connection, []) - assertEquals("", res) + Object res = new Display_Database().exec(connection, ["showColumns":true]) + assertTrue(res.contains("Database is Empty")) new Import_File().exec(connection, @@ -81,37 +80,55 @@ class TestTutorials extends JdbcTestCase { ["pathFile" : TestNoiseModelling.getResource("dem.geojson").getPath(), "inputSRID": "2154"]) + new Road_Emission_from_Traffic().exec(connection, [tableRoads : "ROADS2"]) - new Noise_level_from_traffic().exec(connection, + new Noise_level_from_source().exec(connection, ["tableBuilding" : "BUILDINGS", - "tableRoads" : "ROADS2", + "tableSources" : "LW_ROADS", "tableReceivers" : "RECEIVERS", "tableGroundAbs" : "ground_type", "tableDEM" : "dem", "confDiffHorizontal" : true, "confMaxSrcDist" : 2000.0, "confReflOrder" : 0, - "confMaxError" : 3.0, - "frequencyFieldPrepend": "LW"]) + "confMaxError" : 3.0]) + + + def periods = sql.rows("SELECT DISTINCT PERIOD FROM " + NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME) + def periodValues = periods.collect { + it.PERIOD + } + assertTrue(periodValues.contains("D")) + assertTrue(periodValues.contains("E")) + assertTrue(periodValues.contains("N")) + assertTrue(periodValues.contains("DEN")) def countReceivers = sql.firstRow("SELECT COUNT(*) FROM RECEIVERS")[0] as Integer def countResult = sql.firstRow("SELECT COUNT(*) FROM $NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME".toString())[0] as Integer assertEquals(4*countReceivers, countResult) - def minLevel = sql.firstRow("SELECT MIN(LW1000) FROM $NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME".toString())[0] as Double + def minLevel = sql.firstRow("SELECT MIN(HZ1000) FROM $NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME".toString())[0] as Double assertNotSame(-99.0, minLevel) - } + def receiverCount = sql.firstRow("SELECT COUNT(*) CPT FROM RECEIVERS")["CPT"] as Integer + + ["D", "E", "N", "DEN"].each { period -> + def periodCount = sql.firstRow("SELECT COUNT(*) CPT FROM " + NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME + " WHERE PERIOD = ?", [period])["CPT"] as Integer + assertEquals(receiverCount, periodCount) + } + } + + @Test void testTutorialPointSource() { Sql sql = new Sql(connection) // Check empty database - Object res = new Display_Database().exec(connection, []) - assertEquals("", res) + Object res = new Display_Database().exec(connection, ["showColumns":true]) + assertTrue(res.contains("Database is Empty")) new Import_Folder().exec(connection, ["pathFolder": TestImportExport.class.getResource("TutoPointSource/").getPath(), @@ -122,10 +139,10 @@ class TestTutorials extends JdbcTestCase { assertEquals(2154, GeometryTableUtilities.getSRID(connection, TableLocation.parse("BUILDINGS"))) // Check database - res = new Display_Database().exec(connection, []) + res = new Display_Database().exec(connection, ["showColumns":true]) assertTrue(res.contains("SOURCES")) - assertTrue(res.contains("BUILDINGS")) + assertTrue(res.contains("BUILDINGS")) // generate a grid of receivers using the buildings as envelope new Delaunay_Grid().exec(connection, [maxArea: 600, tableBuilding: "BUILDINGS", @@ -133,7 +150,7 @@ class TestTutorials extends JdbcTestCase { // Check database - res = new Display_Database().exec(connection, []) + res = new Display_Database().exec(connection, ["showColumns":true]) assertTrue(res.contains("RECEIVERS")) @@ -141,12 +158,13 @@ class TestTutorials extends JdbcTestCase { res = new Noise_level_from_source().exec(connection, ["tableSources" : "SOURCES", "tableBuilding" : "BUILDINGS", "tableReceivers" : "RECEIVERS", - "confReflOrder" : 1, - "confDiffVertical" : true, - "confDiffHorizontal" : true, + "confMaxSrcDist" : 50, + "confReflOrder" : 0, + "confDiffVertical" : false, + "confDiffHorizontal" : false, "frequencyFieldPrepend": "LW"]) - res = new Display_Database().exec(connection, []) + res = new Display_Database().exec(connection, ["showColumns":true]) // Check database def output = new Table_Visualization_Data().exec(connection, ["tableName": NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME]) @@ -154,30 +172,17 @@ class TestTutorials extends JdbcTestCase { assertTrue(res.contains(NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME)) assertTrue(output.contains("PERIOD")) - - // Check export geojson - File testPath = new File("build/tmp/tutoPointSource.geojson") - - if(testPath.exists()) { - testPath.delete() - } - - new Export_Table().exec(connection, - ["exportPath" : "build/tmp/tutoPointSource.geojson", - "tableToExport": NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME]) - - } - + @Test void testTutorialPointSourceDirectivity() { Logger logger = LoggerFactory.getLogger(TestTutorials.class) Sql sql = new Sql(connection) // Check empty database - Object res = new Display_Database().exec(connection, []) - assertEquals("", res) + Object res = new Display_Database().exec(connection, ["showColumns":true]) + assertTrue(res.contains("Database is Empty")) new Import_File().exec(connection, [ pathFile : TestTutorials.class.getResource("buildings.shp").getPath(), @@ -201,7 +206,7 @@ class TestTutorials extends JdbcTestCase { - res = new Display_Database().exec(connection, []) + res = new Display_Database().exec(connection, ["showColumns":true]) assertTrue(res.contains("BUILDINGS")) assertTrue(res.contains("DIRECTIVITY")) @@ -210,18 +215,16 @@ class TestTutorials extends JdbcTestCase { assertTrue(res.contains("DEM")) // generate a grid of receivers using the buildings as envelope - logger.info(new Delaunay_Grid().exec(connection, [maxArea: 60, tableBuilding: "BUILDINGS", - sourcesTableName : "POINT_SOURCE" , height: 1.6])); - + new Delaunay_Grid().exec(connection, [maxArea: 60, tableBuilding: "BUILDINGS", + sourcesTableName : "POINT_SOURCE" , height: 1.6]) - new Export_Table().exec(connection, [exportPath:"build/tmp/receivers.shp", tableToExport: "RECEIVERS"]) - new Export_Table().exec(connection, [exportPath:"build/tmp/TRIANGLES.shp", tableToExport: "TRIANGLES"]) new Noise_level_from_source().exec(connection, [tableBuilding: "BUILDINGS", tableSources:"POINT_SOURCE", tableReceivers : "RECEIVERS", tableGroundAbs: "GROUND_TYPE", tableSourceDirectivity: "DIRECTIVITY", - confMaxSrcDist : 800, + confMaxSrcDist : 50, + confReflOrder : 0, tableDEM: "DEM", "frequencyFieldPrepend": "LW" ]) @@ -230,12 +233,6 @@ class TestTutorials extends JdbcTestCase { [resultTable: NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME, smoothCoefficient : 0.4]) - new Export_Table().exec(connection, [exportPath:"build/tmp/CONTOURING_NOISE_MAP.shp", tableToExport: "CONTOURING_NOISE_MAP"]) - - new Export_Table().exec(connection, - [exportPath:"build/tmp/TUTO_DIR_RECEIVERS_LEVEL.shp", - tableToExport: NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME]) - def columnNames = JDBCUtilities.getColumnNames(connection, NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME) assertTrue(columnNames.contains("IDRECEIVER")) @@ -246,16 +243,12 @@ class TestTutorials extends JdbcTestCase { } - void testTutorialMatsim() { - Logger logger = LoggerFactory.getLogger(TestTutorials.class) + @Test + void testTutorialMatsim(@TempDir Path tempDataDir) { Sql sql = new Sql(connection) - Path tempDataDir = new File("build/tmp/matsim/").toPath(); - - Files.createDirectories(tempDataDir); - // URL of the file to download - String fileUrl = "https://github.com/Symexpo/matsim-noisemodelling/releases/download/v5.0.0/scenario_matsim.zip"; + String fileUrl = "https://github.com/Universite-Gustave-Eiffel/NoiseModelling/releases/download/v5.X-Matsim-Test-Scenario/scenario_matsim.zip"; // Create a temporary directory Path zipFilePath = tempDataDir.resolve("scenario_matsim.zip"); @@ -264,7 +257,7 @@ class TestTutorials extends JdbcTestCase { String matsimFolder = tempDataDir.toString(); String resultsFolder = tempDataDir.toString() + "/results/"; Files.createDirectories(Path.of(resultsFolder)); - String populationFactor = "0.001"; // 0.001 for 1/1000 of the population + String populationFactor = "0.01"; // 0.001 for 1/1000 of the population int timeBinSize = 900; int timeBinMin = 0; @@ -277,28 +270,28 @@ class TestTutorials extends JdbcTestCase { if (!zipFilePath.toFile().exists()) { // Download the file - InputStream ins = new URL(fileUrl).openStream(); - Files.copy(ins, zipFilePath); + try (InputStream ins = new URL(fileUrl).openStream()) { + Files.copy(ins, zipFilePath); + } // Unzip the file - ZipFile zipFile = new ZipFile(zipFilePath.toFile()); - zipFile.stream().forEach({ entry -> - try { - Path entryPath = tempDataDir.resolve(entry.getName()); - if (entry.isDirectory()) { - Files.createDirectories(entryPath); - } else { - Files.createDirectories(entryPath.getParent()); - InputStream insz = zipFile.getInputStream(entry); - Files.copy( insz, entryPath ); + try (ZipFile zipFile = new ZipFile(zipFilePath.toFile())) { + zipFile.stream().forEach({ entry -> + try { + Path entryPath = tempDataDir.resolve(entry.getName()); + if (entry.isDirectory()) { + Files.createDirectories(entryPath); + } else { + Files.createDirectories(entryPath.getParent()); + try (InputStream insz = zipFile.getInputStream(entry)) { + Files.copy(insz, entryPath); + } + } + } catch (IOException e) { + throw new RuntimeException(e); } - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - - // Clean up - zipFile.close(); + }); + } } new Import_OSM().exec(connection, Map.of( "pathFile", osmFile, @@ -355,31 +348,21 @@ class TestTutorials extends JdbcTestCase { params.put("tableBuilding", "BUILDINGS"); params.put("tableReceivers", "ACTIVITIES_RECEIVERS"); params.put("tableSources", "MATSIM_ROADS"); + params.put("tableSourcesEmission", "MATSIM_ROADS_LW"); params.put("confMaxSrcDist", 50); params.put("confMaxReflDist", 10); params.put("confReflOrder", 0); params.put("confSkipLevening", true); params.put("confSkipLnight", true); params.put("confSkipLden", true); - params.put("confExportSourceId", true); + params.put("confExportSourceId", false); params.put("confDiffVertical", false); params.put("confDiffHorizontal", false); new Noise_level_from_source().exec(connection, params); - sql.execute("DROP TABLE IF EXISTS ATTENUATION_TRAFFIC"); - sql.execute("ALTER TABLE RECEIVERS_LEVEL RENAME TO ATTENUATION_TRAFFIC"); - - new Noise_From_Attenuation_Matrix_MatSim().exec(connection, Map.of( - "matsimRoads", "MATSIM_ROADS", - "matsimRoadsLw", "MATSIM_ROADS_LW", - "attenuationTable", "ATTENUATION_TRAFFIC", - "receiversTable", "ACTIVITIES_RECEIVERS", - "outTableName", "RESULT_GEOM", - "timeBinSize", timeBinSize, - "timeBinMin", timeBinMin, - "timeBinMax", timeBinMax - )); + sql.execute("DROP TABLE IF EXISTS ACTIVITIES_RECEIVERS_LEVEL"); + sql.execute("ALTER TABLE RECEIVERS_LEVEL RENAME TO ACTIVITIES_RECEIVERS_LEVEL"); params = new HashMap<>(); params.put("experiencedPlansFile", Paths.get(matsimFolder, "output_experienced_plans.xml.gz")); @@ -388,7 +371,7 @@ class TestTutorials extends JdbcTestCase { params.put("SRID", srid); params.put("receiversTable", "ACTIVITIES_RECEIVERS"); params.put("outTableName", "EXPOSURES"); - params.put("dataTable", "RESULT_GEOM"); + params.put("dataTable", "ACTIVITIES_RECEIVERS_LEVEL"); params.put("timeBinSize", timeBinSize); params.put("timeBinMin", timeBinMin); params.put("timeBinMax", timeBinMax); @@ -401,12 +384,26 @@ class TestTutorials extends JdbcTestCase { )); new Export_Table().exec(connection, Map.of( - "tableToExport", "RESULT_GEOM", - "exportPath", Paths.get(resultsFolder, "RESULT_GEOM.shp") + "tableToExport", "ACTIVITIES_RECEIVERS_LEVEL", + "exportPath", Paths.get(resultsFolder, "ACTIVITIES_RECEIVERS_LEVEL.shp") + )); + + new Export_Table().exec(connection, Map.of( + "tableToExport", "EXPOSURES", + "exportPath", Paths.get(resultsFolder, "EXPOSURES.shp") )); - assertTrue(Paths.get(resultsFolder, "RESULT_GEOM.shp").toFile().exists()); + assertTrue(Paths.get(resultsFolder, "ACTIVITIES_RECEIVERS_LEVEL.shp").toFile().exists()); + assertTrue(Paths.get(resultsFolder, "EXPOSURES.shp").toFile().exists()); assertTrue(buildingsPath.toFile().exists()); assertTrue(roadsPath.toFile().exists()); } + + @Test + void testGetStartedDev() { + new get_started_tutorial_complex().exec(connection, [resourcesFolder : new File(TestTutorials.getResource("ROADS2.shp").getFile()).getParent()], new EmptyProgressVisitor()) + + assertTrue(JDBCUtilities.tableExists(connection, "LW_ROADS")) + assertTrue(JDBCUtilities.tableExists(connection, "RECEIVERS_LEVEL")) + } } diff --git a/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/get_started_tutorial_complex.groovy b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/get_started_tutorial_complex.groovy new file mode 100644 index 000000000..a4ed41db2 --- /dev/null +++ b/noisemodelling-scripts/src/test/groovy/org/noise_planet/noisemodelling/scripts/get_started_tutorial_complex.groovy @@ -0,0 +1,55 @@ +package org.noise_planet.noisemodelling.scripts + +import org.h2gis.api.ProgressVisitor +import org.noise_planet.noisemodelling.scripts.Import_and_Export.Import_File +import org.noise_planet.noisemodelling.scripts.NoiseModelling.Noise_level_from_source +import org.noise_planet.noisemodelling.scripts.NoiseModelling.Road_Emission_from_Traffic +import org.noise_planet.noisemodelling.webserver.utilities.Logging +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import groovy.sql.Sql +import java.io.File + +import java.sql.Connection + +title = 'Tutorial script' +description = 'Long description of tutorial script' + +inputs = [ resourcesFolder : [ + description: "Path of the resource folder for input data", + title: "Resource folder", + default: 'resources', + type: String.class +]] + +outputs = [result: [name: 'Result output string', title: 'Result output string', description: 'Result table name. Can be used as input for another WPS process', type: String.class]] + +def exec(Connection connection, Map input, ProgressVisitor progress) { + Logger logger = LoggerFactory.getLogger("tutorial") + ProgressVisitor tutorialProgress = progress.subProcess(7) + // 7 steps in this task + + def resourceFolder = input.resourcesFolder as String + // Upload files to database + def groundTable = new Import_File().exec(connection, ["pathFile": new File(resourceFolder, "ground_type.shp")], tutorialProgress)["outputTable"] + + def buildingTable = new Import_File().exec(connection, ["pathFile": new File(resourceFolder, "buildings.shp")], tutorialProgress)["outputTable"] + + def receiversTable = new Import_File().exec(connection, ["pathFile": new File(resourceFolder, "receivers.shp")], tutorialProgress)["outputTable"] + + def roadsTable = new Import_File().exec(connection, ["pathFile": new File(resourceFolder, "ROADS2.shp")], tutorialProgress)["outputTable"] + + def demTable = new Import_File().exec(connection, ["pathFile": new File(resourceFolder, "dem.geojson")], tutorialProgress)["outputTable"] + + def roadEmissionTable = new Road_Emission_from_Traffic().exec(connection, [tableRoads : roadsTable]).result + + // print some lines of road emission + Logging.formatSqlQueryResult(new Sql(connection), "SELECT * FROM $roadEmissionTable LIMIT 10" as String) + + // Run Calculation + def resultTable = new Noise_level_from_source().exec(connection, ["tableBuilding": buildingTable, "tableSources": roadEmissionTable, "tableReceivers": receiversTable, + "tableDEM" : demTable, "tableGroundAbs": groundTable], tutorialProgress) + + // Return results + return Logging.formatSqlQueryResult(new Sql(connection), "SELECT * FROM $resultTable.result ORDER BY IDRECEIVER, PERIOD LIMIT 10" as String, 120) +} diff --git a/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/AssumptionLoggerExtension.java b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/AssumptionLoggerExtension.java new file mode 100644 index 000000000..039ed7fe3 --- /dev/null +++ b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/AssumptionLoggerExtension.java @@ -0,0 +1,28 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + *

    + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Contact: contact@noise-planet.org + * + */ + +package org.noise_planet.noisemodelling; + +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.TestWatcher; + +import java.util.Locale; + +public class AssumptionLoggerExtension implements TestWatcher { + + @Override + public void testAborted(ExtensionContext context, Throwable cause) { + // This method is called when an Assumption fails + System.err.printf(Locale.ROOT, "Test '%s' cancelled (Assumption failed) : %s%n", context.getDisplayName(), + cause.getMessage()); + } +} \ No newline at end of file diff --git a/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/VersionUtilsTest.java b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/VersionUtilsTest.java new file mode 100644 index 000000000..7aab0ac4f --- /dev/null +++ b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/VersionUtilsTest.java @@ -0,0 +1,26 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + *

    + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Contact: contact@noise-planet.org + * + */ + +package org.noise_planet.noisemodelling; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class VersionUtilsTest { + + @Test + public void testGetVersion() { + String version = VersionUtils.getVersion(); + assertNotNull(version); + assertNotEquals("Unknown", version); + } +} diff --git a/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/scripts/JdbcTestCase.java b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/scripts/JdbcTestCase.java new file mode 100644 index 000000000..8bcc1756b --- /dev/null +++ b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/scripts/JdbcTestCase.java @@ -0,0 +1,134 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + *

    + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Contact: contact@noise-planet.org + * + */ + +package org.noise_planet.noisemodelling.scripts; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.apache.log4j.PropertyConfigurator; +import org.h2.Driver; +import org.h2.util.OsgiDataSourceFactory; +import org.h2gis.functions.factory.H2GISFunctions; +import org.h2gis.postgis_jts.ConnectionWrapper; +import org.h2gis.utilities.JDBCUtilities; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.noise_planet.noisemodelling.VersionUtils; +import org.noise_planet.noisemodelling.webserver.NoiseModellingServerHttpTest; +import org.osgi.service.jdbc.DataSourceFactory; +import org.postgresql.ds.PGSimpleDataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Objects; +import java.util.Optional; +import java.util.Properties; + +public class JdbcTestCase { + + DataSource dataSource; + Connection connection; + boolean isH2GISDatabase = false; + + static Logger LOG = LoggerFactory.getLogger(JdbcTestCase.class); + + /** + * Retrieves PostgreSQL connection parameters from environment variables. + * @return a {@link PostgisParameters} object containing the parameters or null if POSTGRES_HOST environment variable is not set + */ + public static PostgisParameters getPostGISParametersFromEnv() { + if(System.getenv("POSTGRES_HOST") == null) { + return null; + } + String pgUser = Optional.ofNullable(System.getenv("POSTGRES_USER")).orElse("noisemodelling"); + String pgPass = Optional.ofNullable(System.getenv("POSTGRES_PASSWORD")).orElse("noisemodelling"); + String pgPort = Optional.ofNullable(System.getenv("POSTGRES_PORT")).orElse("5432"); + String pgDb = Optional.ofNullable(System.getenv("POSTGRES_DB")).orElse("noisemodelling_db"); + String pgHost = Optional.ofNullable(System.getenv("POSTGRES_HOST")).orElse("localhost"); + return new PostgisParameters(pgUser, pgPass, pgPort, pgDb, pgHost); + } + + /** + * Creates a DataSource for PostgreSQL using the provided parameters. + * @param params the PostgreSQL connection parameters + * @return a DataSource configured for PostgreSQL + * @throws SQLException if an error occurs while creating the DataSource + */ + public static DataSource createPostgisDataSource(PostgisParameters params) throws SQLException { + HikariConfig config = new HikariConfig(); + config.setUsername(params.user); + config.setPassword(params.password); + config.setDataSourceClassName(PGSimpleDataSource.class.getCanonicalName()); + config.addDataSourceProperty("portNumbers", Integer.parseInt(params.port)); + config.addDataSourceProperty("databaseName", params.database); + config.addDataSourceProperty("serverNames", params.host); + return new HikariDataSource(config); + } + + /** + * Creates a DataSource for PostgreSQL from environment variables. + * @return a DataSource configured for PostgreSQL + * @throws SQLException if an error occurs while creating the DataSource + */ + public static DataSource createPostgisDataSourceFromEnv() throws SQLException { + return createPostgisDataSource(getPostGISParametersFromEnv()); + } + + public static DataSource createDataSource(String user, String password, boolean debug) throws SQLException { + // Create H2 memory DataSource + Driver driver = Driver.load(); + OsgiDataSourceFactory dataSourceFactory = new OsgiDataSourceFactory(driver); + Properties properties = new Properties(); + String databasePath = "jdbc:h2:mem:junit"+System.currentTimeMillis(); + properties.setProperty(DataSourceFactory.JDBC_URL, databasePath); + properties.setProperty(DataSourceFactory.JDBC_USER, user); + properties.setProperty(DataSourceFactory.JDBC_PASSWORD, password); + if (debug) { + properties.setProperty("TRACE_LEVEL_FILE", "3"); // enable debug + } + return dataSourceFactory.createDataSource(properties); + } + + @BeforeEach + void initConnection() throws SQLException { + dataSource = createDataSource("sa", "sa", false); + isH2GISDatabase = !(dataSource instanceof HikariDataSource); + if(isH2GISDatabase) { + connection = JDBCUtilities.wrapConnection(dataSource.getConnection()); + H2GISFunctions.load(connection); + } else { + connection = new ConnectionWrapper(dataSource.getConnection()); + } + } + + @AfterEach + void closeConnection() throws SQLException { + connection.close(); + try { + // close connection pool, we are supposed to have a single connection pool + HikariDataSource hds = dataSource.unwrap(HikariDataSource.class); + hds.close(); + } catch (SQLException e) { + // ignore + } + } + + @BeforeAll + public static void init() { + PropertyConfigurator.configure( + Objects.requireNonNull(VersionUtils.class.getResource("log4j_tests.properties"))); + } +} diff --git a/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/scripts/MainTest.java b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/scripts/MainTest.java new file mode 100644 index 000000000..bea607fed --- /dev/null +++ b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/scripts/MainTest.java @@ -0,0 +1,114 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + *

    + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Contact: contact@noise-planet.org + * + */ +package org.noise_planet.noisemodelling.scripts; + +import org.apache.log4j.PropertyConfigurator; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.LoggerContext; +import org.h2gis.utilities.JDBCUtilities; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; +import org.noise_planet.noisemodelling.AssumptionLoggerExtension; +import org.noise_planet.noisemodelling.VersionUtils; +import org.noise_planet.noisemodelling.runner.Main; +import org.noise_planet.noisemodelling.webserver.utilities.Logging; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(AssumptionLoggerExtension.class) +public class MainTest { + String dbName = UUID.randomUUID().toString().replace("-", ""); + + @BeforeEach + public void initLogger() { + PropertyConfigurator.configure( + Objects.requireNonNull(VersionUtils.class.getResource("log4j_tests.properties"))); + } + + @AfterEach + public void tearDown() throws Exception { + Logging.clearAppenders(); + } + + @Test + public void testSetHeight(@TempDir File temp) throws Exception { + String receiverPath = MainTest.class.getResource("receivers.shp").getPath(); + Main.parseArgsAndRun("-w", temp.getAbsolutePath(), + "-d", dbName, + "-s", "src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_File.groovy", + "--pathFile", receiverPath); + + Main.parseArgsAndRun("-w", temp.getAbsolutePath(), + "-d", dbName, + "-s", "src/main/groovy/org/noise_planet/noisemodelling/scripts/Geometric_Tools/Set_Height.groovy", + "--tableName", "RECEIVERS", "--height" , "1.5"); + } + + @Test + public void testConnectionToPostGIS(@TempDir File temp) throws Exception { + String pgHost = System.getenv("POSTGRES_HOST"); + Assumptions.assumeTrue(pgHost != null && !pgHost.isEmpty(), "POSTGRES_HOST is not defined, skipping PostGIS test"); + + String pgUser = Optional.ofNullable(System.getenv("POSTGRES_USER")).orElse("noisemodelling"); + String pgPass = Optional.ofNullable(System.getenv("POSTGRES_PASSWORD")).orElse("noisemodelling"); + String pgPort = Optional.ofNullable(System.getenv("POSTGRES_PORT")).orElse("5432"); + String pgDb = Optional.ofNullable(System.getenv("POSTGRES_DB")).orElse("noisemodelling_db"); + + String buildingsPath = MainTest.class.getResource("buildings.shp").getPath(); + + Main.main("-w", temp.getAbsolutePath(), + "-d", pgDb, + "-u", pgUser, + "-p", pgPass, + "-s", "src/main/groovy/org/noise_planet/noisemodelling/scripts/Import_and_Export/Import_File.groovy", + "--port", pgPort, + "--host", pgHost, + "--pathFile", buildingsPath, + "--tableName", "BUILDINGS"); + + try (Connection connection = JdbcTestCase.createPostgisDataSourceFromEnv().getConnection()) { + assertTrue(JDBCUtilities.tableExists(connection, "BUILDINGS"), "Table BUILDINGS should exist in PostGIS"); + } + } + + @Test + public void testPostGISTutorialGroovy(@TempDir File temp) throws Exception { + String pgHost = System.getenv("POSTGRES_HOST"); + Assumptions.assumeTrue(pgHost != null && !pgHost.isEmpty(), "POSTGRES_HOST is not defined, skipping PostGIS test"); + + String pgUser = Optional.ofNullable(System.getenv("POSTGRES_USER")).orElse("noisemodelling"); + String pgPass = Optional.ofNullable(System.getenv("POSTGRES_PASSWORD")).orElse("noisemodelling"); + String pgPort = Optional.ofNullable(System.getenv("POSTGRES_PORT")).orElse("5432"); + String pgDb = Optional.ofNullable(System.getenv("POSTGRES_DB")).orElse("noisemodelling_db"); + + Main.main("-w", temp.getAbsolutePath(), + "-d", pgDb, + "-u", pgUser, + "-p", pgPass, + "-s", "src/test/groovy/org/noise_planet/noisemodelling/scripts/get_started_tutorial_complex.groovy", + "--port", pgPort, + "--host", pgHost, + "--resourcesFolder", "src/test/resources/org/noise_planet/noisemodelling/scripts"); + + try (Connection connection = JdbcTestCase.createPostgisDataSourceFromEnv().getConnection()) { + assertTrue(JDBCUtilities.tableExists(connection, "RECEIVERS_LEVEL"), "Table RECEIVERS_LEVEL should exist in PostGIS"); + } + } +} diff --git a/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/scripts/PostgisParameters.java b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/scripts/PostgisParameters.java new file mode 100644 index 000000000..47feaa276 --- /dev/null +++ b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/scripts/PostgisParameters.java @@ -0,0 +1,32 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + +package org.noise_planet.noisemodelling.scripts; + +/** + * Represents the parameters for connecting to a PostgreSQL database. + */ +public class PostgisParameters { + public final String user; + public final String password; + public final String port; + public final String database; + public final String host; + + PostgisParameters(String user, String password, String port, String database, String host) { + this.user = user; + this.password = password; + this.port = port; + this.database = database; + this.host = host; + } +} diff --git a/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/NoiseModellingServerHttpTest.java b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/NoiseModellingServerHttpTest.java new file mode 100644 index 000000000..9efecd0ca --- /dev/null +++ b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/NoiseModellingServerHttpTest.java @@ -0,0 +1,415 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + +package org.noise_planet.noisemodelling.webserver; + +import net.opengis.wps10.ExecuteResponseType; +import org.apache.log4j.PropertyConfigurator; +import org.h2.value.ValueBoolean; +import org.h2gis.api.EmptyProgressVisitor; +import org.h2gis.functions.io.geojson.GeoJsonRead; +import org.h2gis.functions.io.geojson.GeoJsonWrite; +import org.h2gis.functions.io.shp.SHPRead; +import org.h2gis.utilities.JDBCUtilities; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.io.TempDir; +import org.noise_planet.noisemodelling.VersionUtils; +import org.noise_planet.noisemodelling.scripts.NoiseModelling.Noise_level_from_source; +import org.noise_planet.noisemodelling.webserver.database.DatabaseManagement; +import org.noise_planet.noisemodelling.webserver.script.JobStates; + +import java.io.*; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.http.*; +import java.net.URI; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.sql.*; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.InputSource; + +import static org.junit.jupiter.api.Assertions.*; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class NoiseModellingServerHttpTest { + + /** + * A Javalin instance used to manage the HTTP server lifecycle and handle HTTP routes + * for the web application during testing. + * + * This static variable is initialized and configured in the {@code setUp} method, + * and is responsible for serving HTTP routes used by the test cases defined in the + * {@link NoiseModellingServerHttpTest} class. + * + * It supports the execution of various HTTP-based operations such as handling requests + * for WPS capabilities, process descriptions, and WPS execution, as verified in the test methods. + */ + private static NoiseModellingServer app; + + private Logger logger = LoggerFactory.getLogger(NoiseModellingServerHttpTest.class); + + /** + * The default port number on which the HTTP server will listen. + * + * This constant defines the port number used to establish server connections. + * It is primarily used during the setup phase of the server and + * in test cases to ensure proper server communication and resource access. + * + * Modifying this value may require corresponding updates in client-side + * configurations and resource endpoints to maintain compatibility. + */ + private static final int PORT = 8000; + /** + * The base URL for the OWS (OGC Web Services) endpoints used in the test cases. + * It dynamically constructs the URL using the `localhost` domain and the value + * of the `PORT` variable defined in the class. + * + * This URL serves as the base endpoint for various HTTP requests made during + * the execution of the test suite and is primarily used for testing capabilities, + * descriptions, and process execution of the WPS (Web Processing Service). + */ + private static final String BASE_URL = "http://localhost:" + PORT + "/"+Configuration.DEFAULT_APPLICATION_URL+"/builder/ows"; + + /** + * Sets up the test environment for the HTTP-based tests. + * This method is executed once before all tests in the test class. + * + * During the setup, a Javalin server instance is initialized by invoking the + * {@code Main.startServer} method with the browser opening disabled. The server + * instance is assigned to the static field {@code app}. + * + * @throws IOException if an I/O error occurs while starting the server. + */ + @BeforeAll + public static void setUp(@TempDir Path temporaryDirectory) throws IOException, SQLException, URISyntaxException { + PropertyConfigurator.configure( + Objects.requireNonNull(VersionUtils.class.getResource("log4j_tests.properties"))); + Configuration configuration = new Configuration(true); + configuration.setWorkingDirectory(temporaryDirectory.toString()); + // Copy unit test scripts and standard scripts to temporary directory + // Using recursive path copy to ensure that all scripts and subdirectories are included + // standard scripts from src/main/groovy/org/noise_planet/noisemodelling/scripts + // unit tests scripts in src/test/resources/org/noise_planet/noisemodelling/webserver/wps_scripts + copyScriptsFromResource(Path.of("src/main/groovy/org/noise_planet/noisemodelling/scripts").toAbsolutePath(), temporaryDirectory); + copyScriptsFromResource(Path.of("src/test/resources/org/noise_planet/noisemodelling/webserver/wps_scripts").toAbsolutePath(), temporaryDirectory); + configuration.setScriptPath(temporaryDirectory.resolve("scripts/").toString()); + app = new NoiseModellingServer(configuration); + app.startServer(false); + } + + private static void copyScriptsFromResource(Path resourcePath, Path temporaryDirectory) throws IOException { + try (Stream paths = Files.walk(resourcePath)) { + paths.forEach(path -> { + if (Files.isRegularFile(path)) { + try { + // Get the folders after "scripts" in the path and create the same structure in the temporary directory + Path relativePath = resourcePath.relativize(path); + Files.createDirectories(temporaryDirectory.resolve("scripts").resolve(relativePath.getParent())); + Path targetPath = temporaryDirectory.resolve("scripts").resolve(relativePath); + Files.copy(path, targetPath, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + }); + } + } + + /** + * Tears down the testing environment after all tests have been executed. + * + * This method is annotated with {@code @AfterAll}, meaning it will be executed + * once after all test cases in the test class have been run. It is responsible + * for performing cleanup operations such as stopping the application instance + * if it has been initialized during the test setup. + * + * If the application instance {@code app} is not null, this method will invoke + * the {@code stop()} method to cease its operations and release any resources + * associated with it. This ensures a proper shutdown and prevents resource leaks. + */ + @AfterAll + public static void tearDown() { + if (app != null) { + app.getJavalinInstance().stop(); + } + } + + @BeforeEach + public void clearInstance() throws SQLException { + if (app != null) { + try(Connection connection = app.getServerDataSource().getConnection()) { + connection.createStatement().execute("TRUNCATE TABLE JOBS"); + } + } + } + + @Test + @Order(1) + void testGetWPSCapabilities() throws Exception { + HttpClient client = HttpClient.newHttpClient(); + String serviceParam = URLEncoder.encode("WPS", StandardCharsets.UTF_8); + String requestParam = URLEncoder.encode("GetCapabilities", StandardCharsets.UTF_8); + URI uri = URI.create(BASE_URL + "?service=" + serviceParam + "&VERSION=1.0.0&request=" + requestParam); + + HttpRequest request = HttpRequest.newBuilder() + .uri(uri) + .GET() + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + assertEquals(200, response.statusCode()); + String body = response.body(); + assertNotNull(body); + // Check if XML is valid - will throw an exception if not valid + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + builder.parse(new InputSource(new StringReader(body))); + + assertTrue(body.contains("`. + * - A description for the process, mentioning "Convert screens to building format." + * - Detailed information about the process functionality, including conversions and + * optional merging with a building table layer. + * + * @throws Exception if an error occurs during the HTTP request, response handling, or validation steps. + */ + @Test + @Order(2) + void testGetWPSDescribeProcess() throws Exception { + HttpClient client = HttpClient.newHttpClient(); + String serviceParam = URLEncoder.encode("WPS", StandardCharsets.UTF_8); + String requestParam = URLEncoder.encode("DescribeProcess", StandardCharsets.UTF_8); + URI uri = URI.create(BASE_URL + "?service=" + serviceParam + "&VERSION=1.0.0&request=" + requestParam + "&identifier=Receivers:Delaunay_Grid"); + + HttpRequest request = HttpRequest.newBuilder() + .uri(uri) + .GET() + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + assertEquals(200, response.statusCode()); + String body = response.body(); + assertNotNull(body); + // Check if XML is valid - will throw an exception if not valid + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + builder.parse(new InputSource(new StringReader(body))); + // Check content + assertTrue(body.contains("Database_Manager:Clean_DatabaseareYouSuretrueresult"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(BASE_URL)) + .POST(HttpRequest.BodyPublishers.ofString(requestBody)) + .header("Content-Type", "text/xml") + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + assertEquals(200, response.statusCode()); + assertNotNull(response.body()); + assertTrue(response.body().contains("dropped")); + + try(Connection connection = app.getServerDataSource().getConnection()) { + List> jobs = DatabaseManagement.getJobs(connection, -1); + assertEquals(1, jobs.size()); + assertEquals("Database_Manager:Clean_Database", jobs.get(0).get("script").toString()); + assertEquals(JobStates.COMPLETED.name(), jobs.get(0).get("status").toString()); + } + } + + + + /** + * Test Delaunay script + * + * @throws Exception if an error occurs during the HTTP request, response handling, or validation steps. + */ + @Test + @Order(4) + void testPostWPSDelaunayExecute() throws Exception { + // Insert Data + try(Connection connection = app.getUserDataSource(1).getConnection()) { + GeoJsonRead.importTable(connection, + NoiseModellingServerHttpTest.class.getResource("wpsinput/BUILDINGS_LOW_HEIGHT.geojson").getFile(), + ValueBoolean.TRUE); + try(Statement statement = connection.createStatement()) { + statement.execute("CREATE TABLE ROADS(id integer primary key, geom geometry(LineStringZ, 2154))"); + statement.execute("INSERT INTO ROADS VALUES(1, ST_GeomFromText('LINESTRING Z (491283" + + ".47973571467446163 6772700.14766194019466639 0, 491298.31839100952493027 6772724" + + ".17215146496891975 0, 491352.2851671117823571 6772724.08382613584399223 0, 491352" + + ".2851671117823571 6772724.08382613584399223 0)', 2154))"); + } + } + HttpClient client = HttpClient.newHttpClient(); + String requestBody = "Receivers:Delaunay_GridtableBuildingBUILDINGS_LOW_HEIGHTsourcesTableNameROADSexportTrianglesGeometriestrueisoSurfaceInBuildingsfalseresult"; + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(BASE_URL)) + .POST(HttpRequest.BodyPublishers.ofString(requestBody)) + .header("Content-Type", "text/xml") + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + assertEquals(200, response.statusCode()); + + try(Connection connection = app.getUserDataSource(1).getConnection()) { + // debug export table triangles as geojson + // GeoJsonWrite.exportTable(connection, "target/TRIANGLES.geojson", "TRIANGLES"); + // Check if there is a triangle at the location of the building in x,y location 491303.97 6772708.80 + // No triangle should be under the buildings + try (PreparedStatement preparedStatement = connection.prepareStatement("SELECT 1 FROM TRIANGLES WHERE " + + "ST_Contains(the_geom, ST_GeomFromText('POINT(491303.97 6772708.80)', 2154))")) { + try(ResultSet rs = preparedStatement.executeQuery()) { + assertFalse(rs.next()); + } + } + // An area with a triangle at 491308.588, 6772710.399 + try (PreparedStatement preparedStatement = connection.prepareStatement("SELECT 1 FROM TRIANGLES WHERE " + + "ST_Contains(the_geom, ST_GeomFromText('POINT(491325.310 6772704.089)', 2154))")) { + try(ResultSet rs = preparedStatement.executeQuery()) { + assertTrue(rs.next()); + } + } + } + } + + @Test + void testPostWPSChainedExecution() throws Exception { + try(InputStream inputStream = TestParseWPSQueries.class.getResourceAsStream("wps_parse/chainedExecute1.xml")) { + assertNotNull(inputStream); + String requestBody = new String(inputStream.readAllBytes()); + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(BASE_URL)) + .POST(HttpRequest.BodyPublishers.ofString(requestBody)) + .header("Content-Type", "text/xml") + .build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + assertEquals(200, response.statusCode()); + // Check if BUILDINGS_LOW_HEIGHT table exists + + try(Connection connection = app.getUserDataSource(1).getConnection()) { + try (PreparedStatement preparedStatement = connection.prepareStatement("SELECT 1 FROM BUILDINGS_LOW_HEIGHT")) { + try(ResultSet rs = preparedStatement.executeQuery()) { + assertTrue(rs.next()); + } + } + } + // Check if the content of the buildings_low_height table is printed as html in response body + assertTrue(response.body().contains("The total number of rows is 9")); + } + } + + @Test + void testAsynchronousWPSExecute() throws Exception { + try(InputStream inputStream = TestParseWPSQueries.class.getResourceAsStream("wps_parse/asynchronousExecute.xml")) { + assertNotNull(inputStream); + String requestBody = new String(inputStream.readAllBytes()); + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(BASE_URL)) + .POST(HttpRequest.BodyPublishers.ofString(requestBody)) + .header("Content-Type", "text/xml") + .build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + assertEquals(200, response.statusCode()); + + ExecuteResponseType executeResponseType = OwsController.parseExecuteResponse(new ByteArrayInputStream(response.body().getBytes())); + String requestResponseUrl = executeResponseType.getStatusLocation(); + + // Polls status endpoint until process completes or fails + while (!(executeResponseType.getStatus().getProcessFailed() != null || + executeResponseType.getStatus().getProcessSucceeded() != null)) { + Thread.sleep(500); + request = HttpRequest.newBuilder() + .uri(URI.create(requestResponseUrl)) + .GET() + .build(); + response = client.send(request, HttpResponse.BodyHandlers.ofString()); + assertEquals(200, response.statusCode()); + executeResponseType = OwsController.parseExecuteResponse(new ByteArrayInputStream(response.body().getBytes())); + // log status and progression + if(executeResponseType.getStatus().getProcessStarted() != null) { + logger.info("Progress: {} %",executeResponseType.getStatus().getProcessStarted().getPercentCompleted()); + } + } + assertNull(executeResponseType.getStatus().getProcessFailed()); + } + } + +} diff --git a/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/TestJobLogs.java b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/TestJobLogs.java new file mode 100644 index 000000000..d2e48c14b --- /dev/null +++ b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/TestJobLogs.java @@ -0,0 +1,102 @@ +/** + * NoiseModelling is a library capable of producing noise maps. It can be freely used either for research and education, as well as by experts in a professional use. + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Official webpage : http://noise-planet.org/noisemodelling.html + * Contact: contact@noise-planet.org + */ + +package org.noise_planet.noisemodelling.webserver; + +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.io.TempDir; +import org.noise_planet.noisemodelling.webserver.utilities.Logging; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.*; + +public class TestJobLogs { + + /** + * Check if the most recent logging rows have been fetched by this method + * @throws IOException + */ + @Test + public void testFilter() throws IOException, URISyntaxException { + AtomicInteger fetchedLines = new AtomicInteger(0); + URL resourceFile = TestJobLogs.class.getResource("test.log"); + assertNotNull(resourceFile); + String lastLines = Logging.getLastLines( + new File(resourceFile.toURI()), + -1, "JOB_16", fetchedLines); + assertEquals(7, fetchedLines.get()); + assertLinesMatch(Arrays.asList("[JOB_16][JOB_16] ERROR 2026-02-24 12:06:11 - Command java -v", + " exit-status: 127", + "[sshd-SshClient[1e3d79ba]-nio2-thread-1][JOB_16] ERROR 2026-02-24 12:06:11 - bash: line 1: java: command not found", + "[JOB_16][JOB_16] INFO 2026-02-24 12:06:11 - Successfully connected to the server localhost", + "[sshd-SshClient[1e3d79ba]-nio2-thread-4][JOB_16] WARN 2026-02-24 12:06:11 - No server key configured. Trusting the server automatically (not recommended for production).", + "[JOB_16][org.apache.sshd.client.config.hosts.DefaultConfigFileHostEntryResolver] INFO 2026-02-24 12:06:11 - resolveEffectiveResolver(testuser@localhost:2222) loaded 4 entries from /Users/user/.ssh/config", + "[JOB_16][org.apache.sshd.common.io.DefaultIoServiceFactoryFactory] INFO 2026-02-24 12:06:11 - No detected/configured IoServiceFactoryFactory; using Nio2ServiceFactoryFactory"), Arrays.asList(lastLines.split("\\r?\\n|\\r"))); + } + + /** + * Check if the most recent logging rows have been fetched by this method + * @throws IOException + */ + @Test + public void testFilterLimited() throws IOException, URISyntaxException { + AtomicInteger fetchedLines = new AtomicInteger(0); + URL resourceFile = TestJobLogs.class.getResource("test.log"); + assertNotNull(resourceFile); + String lastLines = Logging.getLastLines( + new File(resourceFile.toURI()), + 2, "JOB_16", fetchedLines); + assertEquals(2, fetchedLines.get()); + assertLinesMatch(Arrays.asList("[JOB_16][JOB_16] ERROR 2026-02-24 12:06:11 - Command java -v" + , " exit-status: 127"), Arrays.asList(lastLines.split("\\r?\\n|\\r"))); + } + + + /** + * Check of other job logs not included + * + * @throws IOException + */ + @Test + public void testFilterExceptionOtherJob() throws IOException, URISyntaxException { + AtomicInteger fetchedLines = new AtomicInteger(0); + URL resourceFile = TestJobLogs.class.getResource("exception_test.log"); + assertNotNull(resourceFile); + String lastLines = Logging.getLastLines(new File(resourceFile.toURI()), -1, "JOB_9", fetchedLines); + assertEquals(3, fetchedLines.get()); + assertEquals("[JOB_9][JOB_9] INFO 15 déc. 16:23:25 - End : Display database" + System.lineSeparator() + "[JOB_9][JOB_9] INFO 15 déc. 16:23:25 - " + + "inputs {_progression=org.noise_planet.noisemodelling.pathfinder.utils.profiler" + + ".RootProgressVisitor@34f93c74, _configuration=org.noise_planet.noisemodelling.webserver" + + ".Configuration@30cb6bcc, showColumns=true}" + System.lineSeparator() + "[JOB_9][JOB_9] INFO 15 déc. 16:23:25 - Start : Display " + + "database" + System.lineSeparator(), lastLines); + } + + /** + * Check of job logs contain exception traceback + * + * @throws IOException + */ + @Test + public void testFilterExceptionJobTraceback() throws IOException, URISyntaxException { + AtomicInteger fetchedLines = new AtomicInteger(0); + URL resourceFile = TestJobLogs.class.getResource("exception_test.log"); + assertNotNull(resourceFile); + String lastLines = Logging.getLastLines(new File(resourceFile.toURI()), -1, "JOB_8", fetchedLines); + assertEquals(74, fetchedLines.get()); + assertEquals("[JOB_8][JOB_8] ERROR 15 déc. 15:47:09 - Error executing WPS Database_Manager:Add_Primary_KeypkNameIDtableNametestresult" + System.lineSeparator() + "java" + ".util.concurrent.ExecutionException: java.lang.RuntimeException: org.codehaus.groovy.runtime" + ".InvokerInvocationException: java.sql.SQLException: Table TEST not found."+System.lineSeparator() + "\tat java.base/java" + ".util.concurrent.FutureTask.report(FutureTask.java:122)"+System.lineSeparator() + "\tat java.base/java.util.concurrent" + ".FutureTask.get(FutureTask.java:205)"+System.lineSeparator() + "\tat org.noise_planet.noisemodelling.webserver.OwsController" + ".handleWPSPost(OwsController.java:381)"+System.lineSeparator() + "\tat io.javalin.router.Endpoint.handle(Endpoint.kt:52)" + ""+System.lineSeparator() + "\tat io.javalin.router.ParsedEndpoint.handle(ParsedEndpoint.kt:15)"+System.lineSeparator() + "\tat io.javalin.http" + ".servlet.DefaultTasks.HTTP$lambda$11$lambda$9$lambda$8(DefaultTasks.kt:55)"+System.lineSeparator() + "\tat io.javalin" + ".http.servlet.JavalinServlet.handleTask(JavalinServlet.kt:99)"+System.lineSeparator() + "\tat io.javalin.http.servlet" + ".JavalinServlet.handleSync(JavalinServlet.kt:64)"+System.lineSeparator() + "\tat io.javalin.http.servlet.JavalinServlet" + ".handle(JavalinServlet.kt:50)"+System.lineSeparator() + "\tat io.javalin.http.servlet.JavalinServlet.service" + "(JavalinServlet.kt:30)"+System.lineSeparator() + "\tat jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587)"+System.lineSeparator() + "\tat io.javalin.jetty.JavalinJettyServlet.service(JavalinJettyServlet.kt:52)"+System.lineSeparator() + "\tat jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587)"+System.lineSeparator() + "\tat org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)"+System.lineSeparator() + "\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:529)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1580)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1381)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)"+System.lineSeparator() + "\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1303)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:173)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.Server.handle(Server.java:563)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)"+System.lineSeparator() + "\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)"+System.lineSeparator() + "\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)"+System.lineSeparator() + "\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)"+System.lineSeparator() + "\tat org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)"+System.lineSeparator() + "\tat org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)"+System.lineSeparator() + "\tat org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)"+System.lineSeparator() + "\tat org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)"+System.lineSeparator() + "\tat org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)"+System.lineSeparator() + "\tat org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)"+System.lineSeparator() + "\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)"+System.lineSeparator() + "\tat org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)"+System.lineSeparator() + "\tat org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)"+System.lineSeparator() + "\tat java.base/java.lang.Thread.run(Thread.java:829)"+System.lineSeparator() + "Caused by: java.lang.RuntimeException: org.codehaus.groovy.runtime.InvokerInvocationException: java.sql.SQLException: Table TEST not found."+System.lineSeparator() + "\tat org.noise_planet.noisemodelling.webserver.script.Job.call(Job.java:118)"+System.lineSeparator() + "\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)"+System.lineSeparator() + "\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)"+System.lineSeparator() + "\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)"+System.lineSeparator() + "\t... 1 more"+System.lineSeparator() + "Caused by: org.codehaus.groovy.runtime.InvokerInvocationException: java.sql.SQLException: Table TEST not found."+System.lineSeparator() + "\tat org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)"+System.lineSeparator() + "\tat groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:274)"+System.lineSeparator() + "\tat groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1240)"+System.lineSeparator() + "\tat groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1013)"+System.lineSeparator() + "\tat groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:798)"+System.lineSeparator() + "\tat groovy.lang.GroovyObject.invokeMethod(GroovyObject.java:39)"+System.lineSeparator() + "\tat groovy.lang.Script.invokeMethod(Script.java:101)"+System.lineSeparator() + "\tat org.noise_planet.noisemodelling.webserver.script.Job.call(Job.java:112)"+System.lineSeparator() + "\t... 4 more"+System.lineSeparator() + "Caused by: java.sql.SQLException: Table TEST not found."+System.lineSeparator() + "\tat org.h2gis.utilities.JDBCUtilities.getIntegerPrimaryKey(JDBCUtilities.java:446)"+System.lineSeparator() + "\tat org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:344)"+System.lineSeparator() + "\tat org.noise_planet.noisemodelling.scripts.Database_Manager.Add_Primary_Key.exec(Add_Primary_Key.groovy:84)"+System.lineSeparator() + "\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)"+System.lineSeparator() + "\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)"+System.lineSeparator() + "\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)"+System.lineSeparator() + "\tat java.base/java.lang.reflect.Method.invoke(Method.java:566)"+System.lineSeparator() + "\tat org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:338)"+System.lineSeparator() + "\t... 11 more"+System.lineSeparator() + "[JOB_8][JOB_8] INFO 15 déc. 15:47:09 - Start : Add primary key column or constraint"+System.lineSeparator() + "[JOB_8][JOB_8] INFO 15 déc. 15:47:09 - inputs {pkName=ID, _progression=org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor@16c4f9e7, _configuration=org.noise_planet.noisemodelling.webserver.Configuration@30cb6bcc, tableName=test}"+System.lineSeparator(), lastLines); + } +} \ No newline at end of file diff --git a/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/TestParseWPSQueries.java b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/TestParseWPSQueries.java new file mode 100644 index 000000000..39f24265a --- /dev/null +++ b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/TestParseWPSQueries.java @@ -0,0 +1,184 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + *

    + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Contact: contact@noise-planet.org + * + */ + +package org.noise_planet.noisemodelling.webserver; + +import org.apache.log4j.PropertyConfigurator; +import org.jspecify.annotations.NonNull; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.locationtech.jts.geom.Geometry; +import org.noise_planet.noisemodelling.VersionUtils; +import org.noise_planet.noisemodelling.webserver.script.ExecutionPlan; +import org.noise_planet.noisemodelling.webserver.script.WpsXmlDocumentGenerator; +import org.noise_planet.noisemodelling.webserver.script.ScriptMetadata; +import org.noise_planet.noisemodelling.webserver.script.WpsScriptWrapper; +import org.xml.sax.SAXException; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.util.Map; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.*; + +public class TestParseWPSQueries { + static Map wrappers; + + @BeforeAll + public static void init() throws IOException { + PropertyConfigurator.configure( + Objects.requireNonNull(VersionUtils.class.getResource("log4j_tests.properties"))); + wrappers = getWrappers(); + } + + @Test + public void testDelaunayParse() throws IOException, ParserConfigurationException, SAXException { + + + + assertNotEquals(0, wrappers.size()); + // look for the script named Delaunay_Grid + ScriptMetadata scriptMetadata = wrappers.get("Receivers:Delaunay_Grid"); + assertNotNull(scriptMetadata); + assertEquals("Receivers:Delaunay_Grid", scriptMetadata.id); + + String requestBody = "Receivers:Delaunay_GridtableBuildingBUILDINGS_LOW_HEIGHTsourcesTableNameROADSexportTrianglesGeometriestrueisoSurfaceInBuildingsfalseresult"; + + // Provide request body as an input stream + ExecutionPlan executionPlan = OwsController.generateExecutionPlanFromWPS(new ByteArrayInputStream(requestBody.getBytes()), wrappers); + assertNotNull(executionPlan); + // Check inputs values and type + assertEquals("BUILDINGS_LOW_HEIGHT", executionPlan.getInputs().get("tableBuilding")); + assertEquals(Boolean.class, executionPlan.getInputs().get("exportTrianglesGeometries").getClass()); + assertEquals(true, executionPlan.getInputs().get("exportTrianglesGeometries")); + assertEquals(Boolean.class, executionPlan.getInputs().get("isoSurfaceInBuildings").getClass()); + assertEquals(false, executionPlan.getInputs().get("isoSurfaceInBuildings")); + assertEquals(600.0, (double) executionPlan.getInputs().get("maxCellDist"), 0.01); + } + + private static @NonNull Map getWrappers() throws IOException { + return WpsScriptWrapper.scanScriptsGrouped(ClassLoader.getSystemClassLoader(), "scripts"); + } + + + @Test + public void testGeometryReturnParse() throws IOException, ParserConfigurationException, SAXException { + + + + assertNotEquals(0, wrappers.size()); + // look for the script named Delaunay_Grid + ScriptMetadata scriptMetadata = wrappers.get("Database_Manager:Table_Visualization_Map"); + assertNotNull(scriptMetadata); + assertEquals("Database_Manager:Table_Visualization_Map", scriptMetadata.id); + + assertTrue(scriptMetadata.outputs.containsKey("result")); + assertEquals(Geometry.class, scriptMetadata.outputs.get("result").type); + + String describeProcessXML = WpsXmlDocumentGenerator.generateDescribeProcessXML(scriptMetadata); + + // Expect XML output with WKT Geometry type + assertTrue(describeProcessXML.contains("application/wkt")); + assertTrue(describeProcessXML.contains("Database_Manager:Table_Visualization_Map")); + } + + @Test + public void testGenerateCapabilitiesXML() throws IOException { + + + assertNotEquals(0, wrappers.size()); + + String capabilitiesXML = WpsXmlDocumentGenerator.generateCapabilitiesXML(wrappers); + + // Check that capabilities XML is not empty + assertNotNull(capabilitiesXML); + assertFalse(capabilitiesXML.isEmpty()); + + // Expect XML to contain WPS capabilities elements + assertTrue(capabilitiesXML.contains("Capabilities")); + assertTrue(capabilitiesXML.contains("ProcessOfferings")); + assertTrue(capabilitiesXML.contains("ows:Identifier")); + assertTrue(capabilitiesXML.contains("Receivers:Building_Grid")); + } + + @Test + public void testParseChainedExecuteQuery() throws IOException, ParserConfigurationException, SAXException { + + + assertNotEquals(0, wrappers.size()); + + try(InputStream inputStream = TestParseWPSQueries.class.getResourceAsStream("wps_parse/chainedExecute1.xml")) { + assertNotNull(inputStream); + ExecutionPlan executionPlan = OwsController.generateExecutionPlanFromWPS(inputStream, wrappers); + assertNotNull(executionPlan); + assertEquals("Database_Manager:Table_Visualization_Data", executionPlan.getScriptMetadata().id); + assertTrue(executionPlan.getInputs().containsKey("tableName")); + assertInstanceOf(ExecutionPlan.class, executionPlan.getInputs().get("tableName")); + ExecutionPlan chainedExecutionPlan = (ExecutionPlan) executionPlan.getInputs().get("tableName"); + assertEquals("Import_and_Export:Import_File", chainedExecutionPlan.getScriptMetadata().id); + assertEquals("src/test/resources/org/noise_planet/noisemodelling/webserver/wpsinput/BUILDINGS_LOW_HEIGHT.geojson", chainedExecutionPlan.getInputs().get("pathFile")); + assertEquals("outputTable", chainedExecutionPlan.getChainedOutputKey()); + } + + } + + @Test + public void testParseChainedExecuteQuery2() throws IOException, ParserConfigurationException, SAXException { + + assertNotEquals(0, wrappers.size()); + + try(InputStream inputStream = TestParseWPSQueries.class.getResourceAsStream("wps_parse/chainedExecute2.xml")) { + assertNotNull(inputStream); + ExecutionPlan executionPlan = OwsController.generateExecutionPlanFromWPS(inputStream, wrappers); + // Last process + assertNotNull(executionPlan); + assertEquals("Import_and_Export:Export_Table", executionPlan.getScriptMetadata().id); + assertTrue(executionPlan.getInputs().containsKey("tableToExport")); + assertInstanceOf(ExecutionPlan.class, executionPlan.getInputs().get("tableToExport")); + // Linked previous process + ExecutionPlan chainedExecutionPlan = (ExecutionPlan) executionPlan.getInputs().get("tableToExport"); + assertEquals("Acoustic_Tools:Create_Isosurface", chainedExecutionPlan.getScriptMetadata().id); + assertTrue(chainedExecutionPlan.getInputs().containsKey("resultTable")); + assertInstanceOf(ExecutionPlan.class, chainedExecutionPlan.getInputs().get("resultTable")); + // Linked previous process + ExecutionPlan chainedExecutionPlan2 = (ExecutionPlan) chainedExecutionPlan.getInputs().get("resultTable"); + assertEquals("NoiseModelling:Noise_level_from_source", chainedExecutionPlan2.getScriptMetadata().id); + assertTrue(chainedExecutionPlan2.getInputs().containsKey("tableReceivers")); + assertInstanceOf(ExecutionPlan.class, chainedExecutionPlan2.getInputs().get("tableReceivers")); + // Linked previous process + ExecutionPlan chainedExecutionPlan3 = (ExecutionPlan) chainedExecutionPlan2.getInputs().get("tableReceivers"); + assertEquals("Receivers:Delaunay_Grid", chainedExecutionPlan3.getScriptMetadata().id); + assertTrue(chainedExecutionPlan2.getInputs().containsKey("tableBuilding")); + assertInstanceOf(ExecutionPlan.class, chainedExecutionPlan2.getInputs().get("tableBuilding")); + // Linked previous process + ExecutionPlan chainedExecutionPlan4 = (ExecutionPlan) chainedExecutionPlan3.getInputs().get("tableBuilding"); + assertEquals("Import_and_Export:Import_File", chainedExecutionPlan4.getScriptMetadata().id); + } + } +} diff --git a/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/utilities/PgPassUtilitiesTest.java b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/utilities/PgPassUtilitiesTest.java new file mode 100644 index 000000000..58c8f0280 --- /dev/null +++ b/noisemodelling-scripts/src/test/java/org/noise_planet/noisemodelling/webserver/utilities/PgPassUtilitiesTest.java @@ -0,0 +1,64 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + *

    + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + *

    + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + *

    + * Contact: contact@noise-planet.org + * + */ +package org.noise_planet.noisemodelling.webserver.utilities; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.*; + +public class PgPassUtilitiesTest { + + @TempDir + Path tempDir; + + @Test + public void testParsePgPass() throws IOException { + Path pgPassPath = tempDir.resolve(".pgpass"); + String content = "localhost:5432:mydb:myuser:mypassword\n" + + "escaped\\:host:5432:db:user:pass\n" + + "host2:*:db2:user2:pass2\n" + + "*:5432:*:*:otherpass\n"; + Files.write(pgPassPath, content.getBytes()); + + File pgPassFile = pgPassPath.toFile(); + + // Exact match + PgPassUtilities.PgPassEntry entry = PgPassUtilities.getCredentials(pgPassFile, "localhost", "5432", "mydb", "myuser"); + assertNotNull(entry); + assertEquals("mypassword", entry.password); + + // Escaped character match + entry = PgPassUtilities.getCredentials(pgPassFile, "escaped:host", "5432", "db", "user"); + assertNotNull(entry); + assertEquals("pass", entry.password); + + // Wildcard match (port) + entry = PgPassUtilities.getCredentials(pgPassFile, "host2", "1234", "db2", "user2"); + assertNotNull(entry); + assertEquals("pass2", entry.password); + + // Wildcard match (host, database, username) - this one should match the last line + entry = PgPassUtilities.getCredentials(pgPassFile, "anyhost", "5432", "anydb", "anyuser"); + assertNotNull(entry); + assertEquals("otherpass", entry.password); + + // No match + entry = PgPassUtilities.getCredentials(pgPassFile, "localhost", "5433", "mydb", "myuser"); + assertNull(entry); + } +} diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/log4j_tests.properties b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/log4j_tests.properties new file mode 100644 index 000000000..d62bc586b --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/log4j_tests.properties @@ -0,0 +1,8 @@ +log4j.rootLogger=WARN, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%t][%c{1}] %-5p %d{yyyy-MM-dd HH:mm:ss} - %m%n + + diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/buildings.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/buildings.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/buildings.cpg rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/buildings.cpg diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/buildings.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/buildings.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/buildings.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/buildings.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/buildings.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/buildings.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/buildings.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/buildings.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/buildings.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/buildings.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/buildings.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/buildings.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/buildings.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/buildings.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/buildings.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/buildings.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/landuse.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/landuse.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/landuse.cpg rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/landuse.cpg diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/landuse.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/landuse.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/landuse.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/landuse.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/landuse.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/landuse.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/landuse.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/landuse.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/landuse.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/landuse.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/landuse.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/landuse.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/landuse.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/landuse.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/landuse.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/landuse.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/natural.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/natural.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/natural.cpg rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/natural.cpg diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/natural.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/natural.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/natural.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/natural.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/natural.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/natural.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/natural.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/natural.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/natural.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/natural.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/natural.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/natural.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/natural.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/natural.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/natural.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/natural.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/places.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/places.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/places.cpg rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/places.cpg diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/places.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/places.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/places.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/places.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/places.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/places.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/places.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/places.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/places.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/places.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/places.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/places.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/places.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/places.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/places.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/places.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/points.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/points.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/points.cpg rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/points.cpg diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/points.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/points.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/points.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/points.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/points.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/points.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/points.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/points.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/points.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/points.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/points.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/points.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/points.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/points.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/points.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/points.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/railways.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/railways.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/railways.cpg rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/railways.cpg diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/railways.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/railways.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/railways.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/railways.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/railways.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/railways.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/railways.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/railways.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/railways.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/railways.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/railways.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/railways.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/railways.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/railways.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/railways.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/railways.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/roads.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/roads.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/roads.cpg rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/roads.cpg diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/roads.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/roads.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/roads.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/roads.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/roads.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/roads.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/roads.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/roads.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/roads.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/roads.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/roads.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/roads.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/roads.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/roads.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/roads.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/roads.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/waterways.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/waterways.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/waterways.cpg rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/waterways.cpg diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/waterways.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/waterways.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/waterways.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/waterways.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/waterways.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/waterways.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/waterways.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/waterways.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/waterways.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/waterways.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/waterways.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/waterways.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/waterways.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/waterways.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/BBBike/waterways.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/BBBike/waterways.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/SUMO.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/SUMO.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/SUMO.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/SUMO.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/Z_EXPORT_TEST_BUILDINGS.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/Z_EXPORT_TEST_BUILDINGS.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/Z_EXPORT_TEST_BUILDINGS.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/Z_EXPORT_TEST_BUILDINGS.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/Z_EXPORT_TEST_TRAFFIC.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/Z_EXPORT_TEST_TRAFFIC.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/Z_EXPORT_TEST_TRAFFIC.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/Z_EXPORT_TEST_TRAFFIC.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/buildings_nm_ready_pop_heights.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/buildings_nm_ready_pop_heights.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/buildings_nm_ready_pop_heights.cpg rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/buildings_nm_ready_pop_heights.cpg diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/buildings_nm_ready_pop_heights.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/buildings_nm_ready_pop_heights.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/buildings_nm_ready_pop_heights.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/buildings_nm_ready_pop_heights.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/buildings_nm_ready_pop_heights.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/buildings_nm_ready_pop_heights.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/buildings_nm_ready_pop_heights.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/buildings_nm_ready_pop_heights.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/buildings_nm_ready_pop_heights.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/buildings_nm_ready_pop_heights.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/buildings_nm_ready_pop_heights.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/buildings_nm_ready_pop_heights.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/buildings_nm_ready_pop_heights.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/buildings_nm_ready_pop_heights.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/buildings_nm_ready_pop_heights.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/buildings_nm_ready_pop_heights.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/network_tartu_32635_.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/network_tartu_32635_.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/network_tartu_32635_.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/network_tartu_32635_.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/receivers_python_method0_50m_pop.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/receivers_python_method0_50m_pop.cpg similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/receivers_python_method0_50m_pop.cpg rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/receivers_python_method0_50m_pop.cpg diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/receivers_python_method0_50m_pop.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/receivers_python_method0_50m_pop.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/receivers_python_method0_50m_pop.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/receivers_python_method0_50m_pop.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/receivers_python_method0_50m_pop.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/receivers_python_method0_50m_pop.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/receivers_python_method0_50m_pop.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/receivers_python_method0_50m_pop.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/receivers_python_method0_50m_pop.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/receivers_python_method0_50m_pop.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/receivers_python_method0_50m_pop.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/receivers_python_method0_50m_pop.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/receivers_python_method0_50m_pop.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/receivers_python_method0_50m_pop.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Dynamic/receivers_python_method0_50m_pop.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Dynamic/receivers_python_method0_50m_pop.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ROADS2.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ROADS2.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ROADS2.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ROADS2.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ROADS2.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ROADS2.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ROADS2.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ROADS2.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ROADS2.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ROADS2.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ROADS2.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ROADS2.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ROADS2.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ROADS2.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ROADS2.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ROADS2.shx diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_SECTIONS.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_SECTIONS.dbf new file mode 100644 index 000000000..f2fa68e4a Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_SECTIONS.dbf differ diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RAIL_SECTIONS.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_SECTIONS.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RAIL_SECTIONS.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_SECTIONS.prj diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_SECTIONS.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_SECTIONS.shp new file mode 100644 index 000000000..cadd3aae3 Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_SECTIONS.shp differ diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_SECTIONS.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_SECTIONS.shx new file mode 100644 index 000000000..6f5cc641a Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_SECTIONS.shx differ diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RAIL_TRAFFIC.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_TRAFFIC.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RAIL_TRAFFIC.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RAIL_TRAFFIC.dbf diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrack.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrack.cpg new file mode 100644 index 000000000..3ad133c04 --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrack.cpg @@ -0,0 +1 @@ +UTF-8 \ No newline at end of file diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrack.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrack.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrack.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrack.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrack.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrack.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrack.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrack.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrack.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrack.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrack.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrack.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrack.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrack.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrack.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrack.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrain.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrain.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/RailTrain.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/RailTrain.dbf diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/buildings2.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/buildings2.cpg new file mode 100644 index 000000000..3ad133c04 --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/buildings2.cpg @@ -0,0 +1 @@ +UTF-8 \ No newline at end of file diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/buildings2.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/buildings2.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/buildings2.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/buildings2.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/buildings2.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/buildings2.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/buildings2.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/buildings2.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/buildings2.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/buildings2.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/buildings2.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/buildings2.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/buildings2.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/buildings2.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/buildings2.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/buildings2.shx diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/receivers_Railway_.cpg b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/receivers_Railway_.cpg new file mode 100644 index 000000000..3ad133c04 --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/receivers_Railway_.cpg @@ -0,0 +1 @@ +UTF-8 \ No newline at end of file diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/receivers_Railway_.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/receivers_Railway_.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/receivers_Railway_.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/receivers_Railway_.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/receivers_Railway_.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/receivers_Railway_.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/receivers_Railway_.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/receivers_Railway_.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/receivers_Railway_.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/receivers_Railway_.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/receivers_Railway_.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/receivers_Railway_.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/receivers_Railway_.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/receivers_Railway_.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/Train/receivers_Railway_.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/Train/receivers_Railway_.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSource/buildings.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSource/buildings.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSource/buildings.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSource/buildings.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSource/sources.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSource/sources.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSource/sources.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSource/sources.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSourceDirectivity/Buildings.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSourceDirectivity/Buildings.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSourceDirectivity/Buildings.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSourceDirectivity/Buildings.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSourceDirectivity/Buildings.qmd b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSourceDirectivity/Buildings.qmd similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSourceDirectivity/Buildings.qmd rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSourceDirectivity/Buildings.qmd diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSourceDirectivity/Directivity.csv b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSourceDirectivity/Directivity.csv similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSourceDirectivity/Directivity.csv rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSourceDirectivity/Directivity.csv diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSourceDirectivity/Point_Source.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSourceDirectivity/Point_Source.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/TutoPointSourceDirectivity/Point_Source.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/TutoPointSourceDirectivity/Point_Source.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/buildings.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/buildings.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/buildings.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/buildings.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/buildings.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/buildings.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/buildings.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/buildings.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/buildings.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/buildings.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/buildings.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/buildings.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/buildings.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/buildings.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/buildings.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/buildings.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/device_mapping_sf.csv b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/device_mapping_sf.csv similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/device_mapping_sf.csv rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/device_mapping_sf.csv diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/device_mapping_sf.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/device_mapping_sf.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/device_mapping_sf.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/device_mapping_sf.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/4a6.csv b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/4a6.csv similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/4a6.csv rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/4a6.csv diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/51b.csv b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/51b.csv similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/51b.csv rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/51b.csv diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/57a.csv b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/57a.csv similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/57a.csv rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/57a.csv diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/582.csv b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/582.csv similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/582.csv rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/582.csv diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/5c5.csv b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/5c5.csv similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/5c5.csv rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/5c5.csv diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/649.csv b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/649.csv similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/649.csv rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/649.csv diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/650.csv b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/650.csv similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/devices_data/650.csv rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/devices_data/650.csv diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/geneva.osm.pbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/geneva.osm.pbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dataAssimilation/geneva.osm.pbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dataAssimilation/geneva.osm.pbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dem.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dem.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/dem.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dem.geojson diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dem_test_height.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dem_test_height.geojson new file mode 100644 index 000000000..abd372909 --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/dem_test_height.geojson @@ -0,0 +1,10 @@ +{ +"type": "FeatureCollection", +"name": "dem_test_height", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::2154" } }, +"features": [ +{ "type": "Feature", "properties": { "ID": 41.0, "ELEVATION": 71.0 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 662041.858672207570635, 6862999.038258036598563 ], [ 662041.5, 6862998.71574748493731 ], [ 662041.299376411130652, 6862998.5 ], [ 662040.5, 6862997.719340613111854 ], [ 662040.258580839028582, 6862997.5 ], [ 662039.5, 6862996.757298030890524 ], [ 662038.5, 6862996.911415654234588 ], [ 662037.947040084982291, 6862997.5 ], [ 662037.56530069350265, 6862998.5 ], [ 662037.500762157840654, 6862999.363531076349318 ] ] ] } }, +{ "type": "Feature", "properties": { "ID": 67.0, "ELEVATION": 75.0 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 661904.763874526019208, 6862995.5 ], [ 661904.5, 6862995.467722893692553 ], [ 661903.960725607583299, 6862995.5 ], [ 661904.5, 6862995.714847039431334 ], [ 661904.763874526019208, 6862995.5 ] ] ] } }, +{ "type": "Feature", "properties": { "ID": 79.0, "ELEVATION": 71.0 }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 662035.882047869381495, 6862999.48435140401125 ], [ 662036.034715677029453, 6862998.5 ], [ 662035.690352020901628, 6862997.5 ], [ 662035.5, 6862997.172737461514771 ], [ 662035.216093177208677, 6862996.5 ], [ 662034.770955623360351, 6862995.5 ], [ 662034.871232998440973, 6862994.5 ], [ 662034.5, 6862994.259058388881385 ], [ 662033.5, 6862994.110604085028172 ], [ 662033.199295223224908, 6862994.5 ], [ 662032.830720830126666, 6862995.5 ], [ 662032.5, 6862996.478445460088551 ], [ 662032.489634050522, 6862996.5 ], [ 662032.131825525080785, 6862997.5 ], [ 662031.815020784153603, 6862998.5 ], [ 662031.5, 6862999.497155049815774 ], [ 662031.497532387380488, 6862999.5 ], [ 662031.497532387380488, 6862999.811610264703631 ] ] ] } } +] +} diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ground_type.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ground_type.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ground_type.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ground_type.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ground_type.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ground_type.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ground_type.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ground_type.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ground_type.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ground_type.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ground_type.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ground_type.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ground_type.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ground_type.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/ground_type.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/ground_type.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/map.osm.gz b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/map.osm.gz similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/map.osm.gz rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/map.osm.gz diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/map.osm.pbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/map.osm.pbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/map.osm.pbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/map.osm.pbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/multirun/MR_input.json b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/multirun/MR_input.json similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/multirun/MR_input.json rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/multirun/MR_input.json diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/multirun/Rays.zip b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/multirun/Rays.zip similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/multirun/Rays.zip rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/multirun/Rays.zip diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/multirun/buildings.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/multirun/buildings.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/multirun/buildings.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/multirun/buildings.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/multirun/receivers.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/multirun/receivers.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/multirun/receivers.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/multirun/receivers.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/multirun/sources.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/multirun/sources.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/multirun/sources.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/multirun/sources.geojson diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/receivers.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/receivers.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/receivers.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/receivers.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/receivers.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/receivers.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/receivers.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/receivers.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/receivers.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/receivers.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/receivers.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/receivers.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/receivers.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/receivers.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/receivers.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/receivers.shx diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/regression_receivers/BUILDINGS_RECEIVERS_TOO_CLOSE.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/regression_receivers/BUILDINGS_RECEIVERS_TOO_CLOSE.geojson new file mode 100644 index 000000000..60a4cf8cf --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/regression_receivers/BUILDINGS_RECEIVERS_TOO_CLOSE.geojson @@ -0,0 +1,16 @@ +{ +"type": "FeatureCollection", +"name": "BUILDINGS_SCREENS", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::2154" } }, +"features": [ +{ "type": "Feature", "properties": { "HEIGHT": 1.6, "IDBAT": "BATIMENT0000000214896786", "POP": 8, "ERPS": false, "PK": 1698 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491319.5, 6772710.900000000372529 ], [ 491319.799999999988358, 6772716.900000000372529 ], [ 491322.400000000023283, 6772716.900000000372529 ], [ 491322.200000000011642, 6772710.799999999813735 ], [ 491319.5, 6772710.900000000372529 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.7, "IDBAT": "BATIMENT0000000214896785", "POP": 8, "ERPS": false, "PK": 1699 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491317.099999999976717, 6772711.0 ], [ 491317.200000000011642, 6772716.900000000372529 ], [ 491319.799999999988358, 6772716.900000000372529 ], [ 491319.5, 6772710.900000000372529 ], [ 491317.099999999976717, 6772711.0 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.7, "IDBAT": "BATIMENT0000000214896784", "POP": 4, "ERPS": false, "PK": 1700 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491314.299999999988358, 6772711.0 ], [ 491314.599999999976717, 6772716.900000000372529 ], [ 491317.200000000011642, 6772716.900000000372529 ], [ 491317.099999999976717, 6772711.0 ], [ 491314.299999999988358, 6772711.0 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.7, "IDBAT": "BATIMENT0000000214896779", "POP": 5, "ERPS": false, "PK": 1701 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491311.599999999976717, 6772711.099999999627471 ], [ 491311.900000000023283, 6772716.900000000372529 ], [ 491314.599999999976717, 6772716.900000000372529 ], [ 491314.299999999988358, 6772711.0 ], [ 491311.599999999976717, 6772711.099999999627471 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.7, "IDBAT": "BATIMENT0000000214896778", "POP": 5, "ERPS": false, "PK": 1702 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491309.200000000011642, 6772711.200000000186265 ], [ 491309.400000000023283, 6772716.900000000372529 ], [ 491311.900000000023283, 6772716.900000000372529 ], [ 491311.599999999976717, 6772711.099999999627471 ], [ 491309.200000000011642, 6772711.200000000186265 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.8, "IDBAT": "BATIMENT0000000214896781", "POP": 1, "ERPS": false, "PK": 1703 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491306.599999999976717, 6772711.200000000186265 ], [ 491306.900000000023283, 6772716.900000000372529 ], [ 491309.400000000023283, 6772716.900000000372529 ], [ 491309.200000000011642, 6772711.200000000186265 ], [ 491306.599999999976717, 6772711.200000000186265 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.8, "IDBAT": "BATIMENT0000000214896780", "POP": 4, "ERPS": false, "PK": 1704 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491303.900000000023283, 6772711.299999999813735 ], [ 491304.099999999976717, 6772716.900000000372529 ], [ 491306.900000000023283, 6772716.900000000372529 ], [ 491306.599999999976717, 6772711.200000000186265 ], [ 491305.0, 6772711.299999999813735 ], [ 491303.900000000023283, 6772711.299999999813735 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.8, "IDBAT": "BATIMENT0000000214896776", "POP": 3, "ERPS": false, "PK": 1714 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491301.400000000023283, 6772711.400000000372529 ], [ 491301.599999999976717, 6772716.900000000372529 ], [ 491304.099999999976717, 6772716.900000000372529 ], [ 491303.900000000023283, 6772711.299999999813735 ], [ 491301.400000000023283, 6772711.400000000372529 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 5.0, "IDBAT": "BATIMENT0000000214896775", "POP": 3, "ERPS": false, "PK": 1715 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491295.700000000011642, 6772705.5 ], [ 491295.900000000023283, 6772711.5 ], [ 491301.400000000023283, 6772711.400000000372529 ], [ 491303.900000000023283, 6772711.299999999813735 ], [ 491305.0, 6772711.299999999813735 ], [ 491305.0, 6772710.799999999813735 ], [ 491308.0, 6772710.700000000186265 ], [ 491307.900000000023283, 6772705.700000000186265 ], [ 491304.900000000023283, 6772705.799999999813735 ], [ 491304.900000000023283, 6772705.299999999813735 ], [ 491295.700000000011642, 6772705.5 ] ] ] ] } } +] +} diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/regression_receivers/SMALL_BUILDING_NORECEIVER.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/regression_receivers/SMALL_BUILDING_NORECEIVER.geojson new file mode 100644 index 000000000..a61d55456 --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/regression_receivers/SMALL_BUILDING_NORECEIVER.geojson @@ -0,0 +1,11 @@ +{ +"type": "FeatureCollection", +"name": "BUILDINGS", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::2154" } }, +"features": [ +{ "type": "Feature", "properties": { "HEIGHT": 4.3, "IDBAT": "BATIMENT0000000297560132", "POP": 4, "ERPS": false, "PK": 1797 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491261.0, 6773703.5 ], [ 491262.099999999976717, 6773703.900000000372529 ], [ 491263.400000000023283, 6773700.200000000186265 ], [ 491266.099999999976717, 6773701.0 ], [ 491271.400000000023283, 6773685.299999999813735 ], [ 491267.799999999988358, 6773683.900000000372529 ], [ 491261.0, 6773703.5 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 6.2, "IDBAT": "BATIMENT0000000214269629", "POP": 8, "ERPS": false, "PK": 1798 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491262.099999999976717, 6773703.900000000372529 ], [ 491264.900000000023283, 6773704.700000000186265 ], [ 491266.099999999976717, 6773701.0 ], [ 491263.400000000023283, 6773700.200000000186265 ], [ 491262.099999999976717, 6773703.900000000372529 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 4.9, "IDBAT": "BATIMENT0000000214269628", "POP": 5, "ERPS": false, "PK": 1800 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491264.900000000023283, 6773704.700000000186265 ], [ 491270.099999999976717, 6773706.5 ], [ 491276.700000000011642, 6773687.0 ], [ 491271.400000000023283, 6773685.299999999813735 ], [ 491266.099999999976717, 6773701.0 ], [ 491264.900000000023283, 6773704.700000000186265 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 4.0, "IDBAT": "BATIMENT0000000214269630", "POP": 2, "ERPS": false, "PK": 1801 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491270.099999999976717, 6773706.5 ], [ 491278.5, 6773709.400000000372529 ], [ 491285.099999999976717, 6773689.799999999813735 ], [ 491276.700000000011642, 6773687.0 ], [ 491270.099999999976717, 6773706.5 ] ] ] ] } } +] +} diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/roads.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/roads.dbf similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/roads.dbf rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/roads.dbf diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/roads.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/roads.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/roads.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/roads.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/roads.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/roads.shp similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/roads.shp rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/roads.shp diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/roads.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/roads.shx similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/roads.shx rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/roads.shx diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/symuvia.xml b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/symuvia.xml similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/symuvia.xml rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/symuvia.xml diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testAscFolder/precip30min.asc b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testAscFolder/precip30min.asc similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testAscFolder/precip30min.asc rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testAscFolder/precip30min.asc diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testAscFolder/precip30min.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testAscFolder/precip30min.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testAscFolder/precip30min.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testAscFolder/precip30min.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testAscFolder/precip30min2.asc b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testAscFolder/precip30min2.asc similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testAscFolder/precip30min2.asc rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testAscFolder/precip30min2.asc diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testAscFolder/precip30min2.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testAscFolder/precip30min2.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testAscFolder/precip30min2.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testAscFolder/precip30min2.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testDem/dem.asc.gz b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testDem/dem.asc.gz similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testDem/dem.asc.gz rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testDem/dem.asc.gz diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testDem/dem.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testDem/dem.prj similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testDem/dem.prj rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testDem/dem.prj diff --git a/wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testDem/test_roads.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testDem/test_roads.geojson similarity index 100% rename from wps_scripts/src/test/resources/org/noise_planet/noisemodelling/wps/testDem/test_roads.geojson rename to noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/scripts/testDem/test_roads.geojson diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.dbf new file mode 100644 index 000000000..71e509c67 Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.dbf differ diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.prj new file mode 100644 index 000000000..4fd57ac61 --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.prj @@ -0,0 +1 @@ +PROJCS["RGF93 / Lambert-93",GEOGCS["RGF93",DATUM["Reseau_Geodesique_Francais_1993",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6171"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4171"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",44],PARAMETER["latitude_of_origin",46.5],PARAMETER["central_meridian",3],PARAMETER["false_easting",700000],PARAMETER["false_northing",6600000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],AUTHORITY["EPSG","2154"]] \ No newline at end of file diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.shp new file mode 100644 index 000000000..139c205f1 Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.shp differ diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.shx new file mode 100644 index 000000000..cce0b7593 Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/buildings.shx differ diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/exception_test.log b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/exception_test.log new file mode 100644 index 000000000..b17dcae36 --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/exception_test.log @@ -0,0 +1,109 @@ +[main][io.javalin.Javalin] INFO 15 déc. 15:46:54 - HikariPool-1 - Starting... +[main][io.javalin.Javalin] INFO 15 déc. 15:46:54 - HikariPool-1 - Added connection conn1: url=jdbc:h2:file:/Users/fortin/github/plamade/noisemodelling-webserver/target/server user=SA +[main][io.javalin.Javalin] INFO 15 déc. 15:46:54 - HikariPool-1 - Start completed. +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - Starting Javalin ... +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - jetty-11.0.25; built: 2025-03-13T00:15:57.301Z; git: a2e9fae3ad8320f2a713d4fa29bba356a99d1295; jvm 11.0.29+7-LTS +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - Session workerName=node0 +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - Started o.e.j.s.ServletContextHandler@2c34402{/,null,AVAILABLE} +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - Started ServerConnector@1de5cc88{HTTP/1.1, (http/1.1)}{0.0.0.0:8000} +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - Started Server@615e83ac{STARTING}[11.0.25,sto=0] @2050ms +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - + __ ___ _____ + / /___ __ ______ _/ (_)___ / ___/ + __ / / __ `/ | / / __ `/ / / __ \ / __ \ +/ /_/ / /_/ /| |/ / /_/ / / / / / / / /_/ / +\____/\__,_/ |___/\__,_/_/_/_/ /_/ \____/ + + https://javalin.io/documentation + +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - Javalin started in 89ms \o/ +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - Static file handler added: StaticFileConfig(hostedPath=/nmnoisemodelling/builder, directory=/Users/fortin/github/plamade/noisemodelling-webserver/target/classes/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/, location=EXTERNAL, precompress=false, aliasCheck=null, headers={Cache-Control=max-age=0}, mimeTypes={}, roles=[RUNNER]). File system location: '/Users/fortin/github/plamade/noisemodelling-webserver/target/classes/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/' +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - Static file handler added: StaticFileConfig(hostedPath=/nmnoisemodelling, directory=/Users/fortin/github/plamade/noisemodelling-webserver/target/classes/org/noise_planet/noisemodelling/webserver/static/root/, location=EXTERNAL, precompress=false, aliasCheck=null, headers={Cache-Control=max-age=0}, mimeTypes={}, roles=[ANYONE]). File system location: '/Users/fortin/github/plamade/noisemodelling-webserver/target/classes/org/noise_planet/noisemodelling/webserver/static/root/' +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - Listening on http://localhost:8000/ +[main][io.javalin.Javalin] INFO 15 déc. 15:46:55 - You are running Javalin 6.7.0 (released June 22, 2025. Your Javalin version is 175 days old. Consider checking for a newer version.). +[JettyServerThreadPool-42][io.javalin.Javalin] INFO 15 déc. 15:46:56 - 404 not found on /favicon.ico +[JettyServerThreadPool-42][io.javalin.Javalin] INFO 15 déc. 15:47:09 - HikariPool-2 - Starting... +[JettyServerThreadPool-42][io.javalin.Javalin] INFO 15 déc. 15:47:09 - HikariPool-2 - Added connection conn12: url=jdbc:h2:file:/Users/fortin/github/plamade/noisemodelling-webserver/target/user_001 user=SA +[JettyServerThreadPool-42][io.javalin.Javalin] INFO 15 déc. 15:47:09 - HikariPool-2 - Start completed. +[JOB_8][JOB_8] INFO 15 déc. 15:47:09 - inputs {pkName=ID, _progression=org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor@16c4f9e7, _configuration=org.noise_planet.noisemodelling.webserver.Configuration@30cb6bcc, tableName=test} +[JOB_8][JOB_8] INFO 15 déc. 15:47:09 - Start : Add primary key column or constraint +[JOB_8][JOB_8] ERROR 15 déc. 15:47:09 - Error executing WPS Database_Manager:Add_Primary_KeypkNameIDtableNametestresult +java.util.concurrent.ExecutionException: java.lang.RuntimeException: org.codehaus.groovy.runtime.InvokerInvocationException: java.sql.SQLException: Table TEST not found. + at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122) + at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:205) + at org.noise_planet.noisemodelling.webserver.OwsController.handleWPSPost(OwsController.java:381) + at io.javalin.router.Endpoint.handle(Endpoint.kt:52) + at io.javalin.router.ParsedEndpoint.handle(ParsedEndpoint.kt:15) + at io.javalin.http.servlet.DefaultTasks.HTTP$lambda$11$lambda$9$lambda$8(DefaultTasks.kt:55) + at io.javalin.http.servlet.JavalinServlet.handleTask(JavalinServlet.kt:99) + at io.javalin.http.servlet.JavalinServlet.handleSync(JavalinServlet.kt:64) + at io.javalin.http.servlet.JavalinServlet.handle(JavalinServlet.kt:50) + at io.javalin.http.servlet.JavalinServlet.service(JavalinServlet.kt:30) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587) + at io.javalin.jetty.JavalinJettyServlet.service(JavalinJettyServlet.kt:52) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587) + at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764) + at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:529) + at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221) + at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1580) + at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221) + at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1381) + at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176) + at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484) + at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553) + at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174) + at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1303) + at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129) + at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:173) + at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122) + at org.eclipse.jetty.server.Server.handle(Server.java:563) + at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598) + at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753) + at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501) + at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287) + at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314) + at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100) + at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53) + at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421) + at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390) + at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277) + at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199) + at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411) + at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969) + at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194) + at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149) + at java.base/java.lang.Thread.run(Thread.java:829) +Caused by: java.lang.RuntimeException: org.codehaus.groovy.runtime.InvokerInvocationException: java.sql.SQLException: Table TEST not found. + at org.noise_planet.noisemodelling.webserver.script.Job.call(Job.java:118) + at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) + ... 1 more +Caused by: org.codehaus.groovy.runtime.InvokerInvocationException: java.sql.SQLException: Table TEST not found. + at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343) + at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:274) + at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1240) + at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1013) + at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:798) + at groovy.lang.GroovyObject.invokeMethod(GroovyObject.java:39) + at groovy.lang.Script.invokeMethod(Script.java:101) + at org.noise_planet.noisemodelling.webserver.script.Job.call(Job.java:112) + ... 4 more +Caused by: java.sql.SQLException: Table TEST not found. + at org.h2gis.utilities.JDBCUtilities.getIntegerPrimaryKey(JDBCUtilities.java:446) + at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:344) + at org.noise_planet.noisemodelling.scripts.Database_Manager.Add_Primary_Key.exec(Add_Primary_Key.groovy:84) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:566) + at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:338) + ... 11 more +[JOB_9][JOB_9] INFO 15 déc. 16:23:25 - Start : Display database +[JOB_9][JOB_9] INFO 15 déc. 16:23:25 - inputs {_progression=org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor@34f93c74, _configuration=org.noise_planet.noisemodelling.webserver.Configuration@30cb6bcc, showColumns=true} +[JOB_9][JOB_9] INFO 15 déc. 16:23:25 - End : Display database +[Thread-2][io.javalin.Javalin] INFO 15 déc. 17:00:53 - Stopping Javalin ... +[Thread-2][io.javalin.Javalin] INFO 15 déc. 17:00:53 - Stopped Server@615e83ac{STOPPING}[11.0.25,sto=0] +[Thread-2][io.javalin.Javalin] INFO 15 déc. 17:00:53 - Stopped ServerConnector@1de5cc88{HTTP/1.1, (http/1.1)}{0.0.0.0:8000} +[Thread-2][io.javalin.Javalin] INFO 15 déc. 17:00:53 - Stopped o.e.j.s.ServletContextHandler@2c34402{/,null,STOPPED} +[Thread-2][io.javalin.Javalin] INFO 15 déc. 17:00:53 - Javalin has stopped diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.dbf new file mode 100644 index 000000000..58e9824e1 Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.dbf differ diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.prj new file mode 100644 index 000000000..52a60bf44 --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.prj @@ -0,0 +1 @@ +PROJCS["RGF93 / Lambert-93",GEOGCS["RGF93",DATUM["Reseau_Geodesique_Francais_1993",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6171"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4171"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",44],PARAMETER["latitude_of_origin",46.5],PARAMETER["central_meridian",3],PARAMETER["false_easting",700000],PARAMETER["false_northing",6600000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],AUTHORITY["EPSG","2154"]] diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.shp new file mode 100644 index 000000000..308fcfdbe Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.shp differ diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.shx new file mode 100644 index 000000000..3b9084ec8 Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/lw_roads.shx differ diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.dbf b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.dbf new file mode 100644 index 000000000..5d0c57218 Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.dbf differ diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.prj b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.prj new file mode 100644 index 000000000..4fd57ac61 --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.prj @@ -0,0 +1 @@ +PROJCS["RGF93 / Lambert-93",GEOGCS["RGF93",DATUM["Reseau_Geodesique_Francais_1993",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6171"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4171"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",44],PARAMETER["latitude_of_origin",46.5],PARAMETER["central_meridian",3],PARAMETER["false_easting",700000],PARAMETER["false_northing",6600000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],AUTHORITY["EPSG","2154"]] \ No newline at end of file diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.shp b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.shp new file mode 100644 index 000000000..62fd1623c Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.shp differ diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.shx b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.shx new file mode 100644 index 000000000..3a5256af0 Binary files /dev/null and b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/receivers.shx differ diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/test.log b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/test.log new file mode 100644 index 000000000..744d48c9f --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/test.log @@ -0,0 +1,26 @@ +[main][com.zaxxer.hikari.HikariDataSource] INFO 2026-02-24 12:06:02 - HikariPool-1 - Starting... +[main][com.zaxxer.hikari.pool.HikariPool] INFO 2026-02-24 12:06:02 - HikariPool-1 - Added connection conn1: url=jdbc:h2:file:/Users/user/github/plamade/noisemodelling-webserver/target/server user=SA +[main][com.zaxxer.hikari.HikariDataSource] INFO 2026-02-24 12:06:02 - HikariPool-1 - Start completed. +[main][org.noise_planet.noisemodelling.webserver.database.DatabaseManagement] WARN 2026-02-24 12:06:02 - The Administrator account has not been registered yet, please use this url to create the account (or run with -u option): + http://localhost:8000/nmnoisemodelling/register/_TmX8hNBgkxejZ_nAeiRQfk7s9bA2aONbjBAUhBAXMQ +[main][org.noise_planet.noisemodelling.webserver.script.WpsScriptWrapper] INFO 2026-02-24 12:06:02 - Scanning scripts in directory: /Users/user/github/plamade/scripts +[main][org.noise_planet.noisemodelling.webserver.script.WpsScriptWrapper] WARN 2026-02-24 12:06:02 - Directory does not exist scripts, will try to use ClassLoader resources package instead.. +[main][org.noise_planet.noisemodelling.webserver.script.WpsScriptWrapper] INFO 2026-02-24 12:06:02 - Found 43 scripts in directory/package: scripts +[main][org.eclipse.jetty.server.Server] INFO 2026-02-24 12:06:05 - jetty-11.0.25; built: 2025-03-13T00:15:57.301Z; git: a2e9fae3ad8320f2a713d4fa29bba356a99d1295; jvm 11.0.29+7-LTS +[main][org.eclipse.jetty.server.session.DefaultSessionIdManager] INFO 2026-02-24 12:06:05 - Session workerName=node0 +[main][org.eclipse.jetty.server.handler.ContextHandler] INFO 2026-02-24 12:06:05 - Started o.e.j.s.ServletContextHandler@29db9746{/nmnoisemodelling,null,AVAILABLE} +[main][org.eclipse.jetty.server.AbstractConnector] INFO 2026-02-24 12:06:05 - Started ServerConnector@40a0364a{HTTP/1.1, (http/1.1)}{0.0.0.0:8000} +[main][org.eclipse.jetty.server.Server] INFO 2026-02-24 12:06:05 - Started Server@5973d3ec{STARTING}[11.0.25,sto=0] @4506ms +[main][io.javalin.Javalin] INFO 2026-02-24 12:06:06 - Static file handler added: StaticFileConfig(hostedPath=/builder, directory=org/noise_planet/noisemodelling/webserver/static/wpsbuilder/, location=CLASSPATH, precompress=false, aliasCheck=null, headers={Cache-Control=max-age=0}, mimeTypes={}, roles=[ANYONE]). File system location: 'file:///Users/user/github/plamade/noisemodelling-webserver/target/classes/org/noise_planet/noisemodelling/webserver/static/wpsbuilder/' +[main][io.javalin.Javalin] INFO 2026-02-24 12:06:06 - Static file handler added: StaticFileConfig(hostedPath=/, directory=org/noise_planet/noisemodelling/webserver/static/root/, location=CLASSPATH, precompress=false, aliasCheck=null, headers={Cache-Control=max-age=0}, mimeTypes={}, roles=[ANYONE]). File system location: 'file:///Users/user/github/plamade/noisemodelling-webserver/target/classes/org/noise_planet/noisemodelling/webserver/static/root/' +[JettyServerThreadPool-41][com.zaxxer.hikari.HikariDataSource] INFO 2026-02-24 12:06:11 - HikariPool-2 - Starting... +[JettyServerThreadPool-41][com.zaxxer.hikari.pool.HikariPool] INFO 2026-02-24 12:06:11 - HikariPool-2 - Added connection conn3: url=jdbc:h2:file:/Users/user/github/plamade/noisemodelling-webserver/target/user_001 user=SA +[JettyServerThreadPool-41][com.zaxxer.hikari.HikariDataSource] INFO 2026-02-24 12:06:11 - HikariPool-2 - Start completed. +[JOB_16][org.apache.sshd.common.io.DefaultIoServiceFactoryFactory] INFO 2026-02-24 12:06:11 - No detected/configured IoServiceFactoryFactory; using Nio2ServiceFactoryFactory +[JOB_16][org.apache.sshd.client.config.hosts.DefaultConfigFileHostEntryResolver] INFO 2026-02-24 12:06:11 - resolveEffectiveResolver(testuser@localhost:2222) loaded 4 entries from /Users/user/.ssh/config +[sshd-SshClient[1e3d79ba]-nio2-thread-4][JOB_16] WARN 2026-02-24 12:06:11 - No server key configured. Trusting the server automatically (not recommended for production). +[sshd-SshClient[1e3d79ba]-nio2-thread-4][org.apache.sshd.common.kex.extension.parser.HostBoundPubkeyAuthentication] INFO 2026-02-24 12:06:11 - Server announced support for publickey-hostbound@openssh.com version 0 +[JOB_16][JOB_16] INFO 2026-02-24 12:06:11 - Successfully connected to the server localhost +[sshd-SshClient[1e3d79ba]-nio2-thread-1][JOB_16] ERROR 2026-02-24 12:06:11 - bash: line 1: java: command not found +[JOB_16][JOB_16] ERROR 2026-02-24 12:06:11 - Command java -v + exit-status: 127 diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_parse/asynchronousExecute.xml b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_parse/asynchronousExecute.xml new file mode 100644 index 000000000..e379b1b2f --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_parse/asynchronousExecute.xml @@ -0,0 +1,11 @@ + + ut:LongRunningProcess + + + waitTime + + 10 + + + + diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_parse/chainedExecute1.xml b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_parse/chainedExecute1.xml new file mode 100644 index 000000000..843cd97eb --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_parse/chainedExecute1.xml @@ -0,0 +1,35 @@ + + Database_Manager:Table_Visualization_Data + + + tableName + + + + Import_and_Export:Import_File + + + + pathFile + + src/test/resources/org/noise_planet/noisemodelling/webserver/wpsinput/BUILDINGS_LOW_HEIGHT.geojson + + + + + + outputTable + + + + + + + + + + result + + + diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_parse/chainedExecute2.xml b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_parse/chainedExecute2.xml new file mode 100644 index 000000000..a2fc234c4 --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_parse/chainedExecute2.xml @@ -0,0 +1,239 @@ + + Import_and_Export:Export_Table + + + tableToExport + + + + Acoustic_Tools:Create_Isosurface + + + + resultTable + + + + + NoiseModelling:Noise_level_from_source + + + + + tableSources + + + + + + Import_and_Export:Import_File + + + + + pathFile + + + roads_lw.shp + + + + + + + + outputTable + + + + + + + + + + tableReceivers + + + + + + Receivers:Delaunay_Grid + + + + + tableBuilding + + + + + + Import_and_Export:Import_File + + + + + pathFile + + + + buildings.shp + + + + + + + + outputTable + + + + + + + + + + sourcesTableName + + + + + + Import_and_Export:Import_File + + + + + pathFile + + + + roads_lw.shp + + + + + + + + outputTable + + + + + + + + + + + + result + + + + + + + + + + tableBuilding + + + + + + Import_and_Export:Import_File + + + + + pathFile + + + buildings.shp + + + + + + + + outputTable + + + + + + + + + + + result + + + + + + + + + + + result + + + + + + + + exportPath + + contouring.shp + + + + + + result + + + \ No newline at end of file diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_scripts/ut/LongRunningProcess.groovy b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_scripts/ut/LongRunningProcess.groovy new file mode 100644 index 000000000..7239a8d0e --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wps_scripts/ut/LongRunningProcess.groovy @@ -0,0 +1,60 @@ +/** + * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. + * + * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). + * + * + * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. + * + * Contact: contact@noise-planet.org + * + */ + +/** + * @Author Pierre Aumond, Université Gustave Eiffel + * @Author Nicolas Fortin, Université Gustave Eiffel + */ + +package org.noise_planet.noisemodelling.webserver.wps_scripts.ut + +import org.h2gis.api.ProgressVisitor + +import java.sql.Connection + +title = 'Long running process' +description = 'Long running process' + +inputs = [ + waitTime: [ + name : 'Wait time', + title : 'Wait time', + description: 'Time to wait (seconds)', + type : Integer.class + ] +] + +outputs = [ + result: [ + name : 'Result output string', + title : 'Result output string', + description: 'This type of result does not allow the blocks to be linked together.', + type : String.class + ] +] + +def exec(Connection connection, Map input, ProgressVisitor progressVisitor) { + int waitTime = input.waitTime as Integer + int count = 0 + ProgressVisitor progress = progressVisitor.subProcess(waitTime) + while (count < waitTime) { + Thread.sleep(1000) + count++ + progress.endStep() + } + String resultString = "Waited for ${waitTime} seconds" + + // print to WPS Builder + return resultString +} + + diff --git a/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wpsinput/BUILDINGS_LOW_HEIGHT.geojson b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wpsinput/BUILDINGS_LOW_HEIGHT.geojson new file mode 100644 index 000000000..60a4cf8cf --- /dev/null +++ b/noisemodelling-scripts/src/test/resources/org/noise_planet/noisemodelling/webserver/wpsinput/BUILDINGS_LOW_HEIGHT.geojson @@ -0,0 +1,16 @@ +{ +"type": "FeatureCollection", +"name": "BUILDINGS_SCREENS", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::2154" } }, +"features": [ +{ "type": "Feature", "properties": { "HEIGHT": 1.6, "IDBAT": "BATIMENT0000000214896786", "POP": 8, "ERPS": false, "PK": 1698 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491319.5, 6772710.900000000372529 ], [ 491319.799999999988358, 6772716.900000000372529 ], [ 491322.400000000023283, 6772716.900000000372529 ], [ 491322.200000000011642, 6772710.799999999813735 ], [ 491319.5, 6772710.900000000372529 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.7, "IDBAT": "BATIMENT0000000214896785", "POP": 8, "ERPS": false, "PK": 1699 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491317.099999999976717, 6772711.0 ], [ 491317.200000000011642, 6772716.900000000372529 ], [ 491319.799999999988358, 6772716.900000000372529 ], [ 491319.5, 6772710.900000000372529 ], [ 491317.099999999976717, 6772711.0 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.7, "IDBAT": "BATIMENT0000000214896784", "POP": 4, "ERPS": false, "PK": 1700 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491314.299999999988358, 6772711.0 ], [ 491314.599999999976717, 6772716.900000000372529 ], [ 491317.200000000011642, 6772716.900000000372529 ], [ 491317.099999999976717, 6772711.0 ], [ 491314.299999999988358, 6772711.0 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.7, "IDBAT": "BATIMENT0000000214896779", "POP": 5, "ERPS": false, "PK": 1701 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491311.599999999976717, 6772711.099999999627471 ], [ 491311.900000000023283, 6772716.900000000372529 ], [ 491314.599999999976717, 6772716.900000000372529 ], [ 491314.299999999988358, 6772711.0 ], [ 491311.599999999976717, 6772711.099999999627471 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.7, "IDBAT": "BATIMENT0000000214896778", "POP": 5, "ERPS": false, "PK": 1702 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491309.200000000011642, 6772711.200000000186265 ], [ 491309.400000000023283, 6772716.900000000372529 ], [ 491311.900000000023283, 6772716.900000000372529 ], [ 491311.599999999976717, 6772711.099999999627471 ], [ 491309.200000000011642, 6772711.200000000186265 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.8, "IDBAT": "BATIMENT0000000214896781", "POP": 1, "ERPS": false, "PK": 1703 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491306.599999999976717, 6772711.200000000186265 ], [ 491306.900000000023283, 6772716.900000000372529 ], [ 491309.400000000023283, 6772716.900000000372529 ], [ 491309.200000000011642, 6772711.200000000186265 ], [ 491306.599999999976717, 6772711.200000000186265 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.8, "IDBAT": "BATIMENT0000000214896780", "POP": 4, "ERPS": false, "PK": 1704 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491303.900000000023283, 6772711.299999999813735 ], [ 491304.099999999976717, 6772716.900000000372529 ], [ 491306.900000000023283, 6772716.900000000372529 ], [ 491306.599999999976717, 6772711.200000000186265 ], [ 491305.0, 6772711.299999999813735 ], [ 491303.900000000023283, 6772711.299999999813735 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 1.8, "IDBAT": "BATIMENT0000000214896776", "POP": 3, "ERPS": false, "PK": 1714 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491301.400000000023283, 6772711.400000000372529 ], [ 491301.599999999976717, 6772716.900000000372529 ], [ 491304.099999999976717, 6772716.900000000372529 ], [ 491303.900000000023283, 6772711.299999999813735 ], [ 491301.400000000023283, 6772711.400000000372529 ] ] ] ] } }, +{ "type": "Feature", "properties": { "HEIGHT": 5.0, "IDBAT": "BATIMENT0000000214896775", "POP": 3, "ERPS": false, "PK": 1715 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 491295.700000000011642, 6772705.5 ], [ 491295.900000000023283, 6772711.5 ], [ 491301.400000000023283, 6772711.400000000372529 ], [ 491303.900000000023283, 6772711.299999999813735 ], [ 491305.0, 6772711.299999999813735 ], [ 491305.0, 6772710.799999999813735 ], [ 491308.0, 6772710.700000000186265 ], [ 491307.900000000023283, 6772705.700000000186265 ], [ 491304.900000000023283, 6772705.799999999813735 ], [ 491304.900000000023283, 6772705.299999999813735 ], [ 491295.700000000011642, 6772705.5 ] ] ] ] } } +] +} diff --git a/noisemodelling-tutorial-01/Readme.md b/noisemodelling-tutorial-01/Readme.md deleted file mode 100644 index 2a40b5fbf..000000000 --- a/noisemodelling-tutorial-01/Readme.md +++ /dev/null @@ -1,5 +0,0 @@ -This tutorial cover the computation of Lday, Levening, lnight and Lden noise levels from road traffic. - - The results csv files are placed into the target subdirectory. Its contains the levels for each specified evaluation point. - - \ No newline at end of file diff --git a/noisemodelling-tutorial-01/pom.xml b/noisemodelling-tutorial-01/pom.xml deleted file mode 100644 index bcf56caf2..000000000 --- a/noisemodelling-tutorial-01/pom.xml +++ /dev/null @@ -1,163 +0,0 @@ - - - 4.0.0 - - UTF-8 - org.noise_planet.nmtutorial01.Main - - jar - noisemodelling-tutorial-01 - noisemodelling-tutorial-01 - - org.noise-planet - noisemodelling-parent - 5.0.2-SNAPSHOT - ../pom.xml - - Test case with OpenStreetMap buildings and roads - - - org.slf4j - slf4j-simple - compile - - - ${project.groupId} - noisemodelling-emission - ${project.version} - - - ${project.groupId} - noisemodelling-propagation - ${project.version} - - - ${project.groupId} - noisemodelling-jdbc - ${project.version} - - - ${project.groupId} - noisemodelling-pathfinder - ${project.version} - - - org.orbisgis - h2gis - - - org.orbisgis - h2gis-api - - - org.orbisgis - h2gis-utilities - - - org.orbisgis - postgis-jts-osgi - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.core - jackson-core - - - org.junit.jupiter - junit-jupiter-api - - - org.junit.jupiter - junit-jupiter-engine - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.0.1 - - - attach-sources - - jar - - package - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - 11 - 11 - - - - org.apache.felix - maven-bundle-plugin - 5.1.1 - true - - - org.noise_planet.noisemodelling.propagation.* - UMRAE team (Eiffel University), DECIDE team (Lab-STICC) - org.slf4j;version="[1.6.0,2)",!org.h2.*,* - ${buildNumber} - - - - - - org.codehaus.mojo - exec-maven-plugin - 1.6.0 - - - - java - - - - - ${main.class} - - - - org.apache.maven.plugins - maven-jar-plugin - - - - ${main.class} - - - - - - maven-assembly-plugin - 2.3 - - - jar-with-dependencies - - - - - make-assembly - package - - single - - - - - - - diff --git a/noisemodelling-tutorial-01/postgis_docker/postgis_docker_arm64/docker-compose.yml b/noisemodelling-tutorial-01/postgis_docker/postgis_docker_arm64/docker-compose.yml deleted file mode 100644 index 7360373d3..000000000 --- a/noisemodelling-tutorial-01/postgis_docker/postgis_docker_arm64/docker-compose.yml +++ /dev/null @@ -1,28 +0,0 @@ -# docker-compose build -volumes: - postgis-data: - driver: local - -services: - db: - image: tobi312/rpi-postgresql-postgis:15-3.4-alpine-arm - #image: postgis/postgis:15-3.3 - volumes: - - postgis-data:/var/lib/postgresql/data - - ./:/data - environment: - # If you need to create multiple database you can add coma separated databases eg gis,data - - POSTGRES_DB=noisemodelling_db - - POSTGRES_USER=noisemodelling - - POSTGRES_PASSWORD=noisemodelling - ports: - - 5432:5432 - command: postgres -c max_wal_size=4GB - restart: on-failure - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 60s - timeout: 5s - retries: 5 - - diff --git a/noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/DbUtilities.java b/noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/DbUtilities.java deleted file mode 100644 index c4c864de9..000000000 --- a/noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/DbUtilities.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.noise_planet.nmtutorial01; - -import org.h2.Driver; -import org.h2gis.functions.factory.H2GISFunctions; - -import java.io.File; -import java.net.URI; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - - -public class DbUtilities { - - - private static String getDataBasePath(String dbName) { - return dbName.startsWith("file:/") ? (new File(URI.create(dbName))).getAbsolutePath() : (new File(dbName)).getAbsolutePath(); - } - - - static Connection createSpatialDataBase(String dbName, boolean initSpatial) throws SQLException { - String dbFilePath = getDataBasePath(dbName); - File dbFile = new File(dbFilePath + ".mv.db"); - - String databasePath = "jdbc:h2:" + dbFilePath + ";DB_CLOSE_DELAY=5"; - - if (dbFile.exists()) { - dbFile.delete(); - } - - dbFile = new File(dbFilePath + ".mv.db"); - if (dbFile.exists()) { - dbFile.delete(); - } - Driver.load(); - Connection connection = DriverManager.getConnection(databasePath, "sa", "sa"); - if (initSpatial) { - H2GISFunctions.load(connection); - } - - return connection; - } -} diff --git a/noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/main.java b/noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/main.java deleted file mode 100644 index 6f78a72f7..000000000 --- a/noisemodelling-tutorial-01/src/main/java/org/noise_planet/nmtutorial01/main.java +++ /dev/null @@ -1,181 +0,0 @@ -package org.noise_planet.nmtutorial01; - -import org.h2.value.ValueBoolean; -import org.h2gis.api.EmptyProgressVisitor; -import org.h2gis.functions.io.geojson.GeoJsonRead; -import org.h2gis.functions.io.shp.SHPWrite; -import org.h2gis.utilities.GeometryTableUtilities; -import org.h2gis.utilities.JDBCUtilities; -import org.h2gis.utilities.TableLocation; -import org.h2gis.utilities.dbtypes.DBTypes; -import org.h2gis.utilities.dbtypes.DBUtils; -import org.noise_planet.noisemodelling.jdbc.NoiseMapByReceiverMaker; -import org.noise_planet.noisemodelling.jdbc.input.DefaultTableLoader; -import org.noise_planet.noisemodelling.jdbc.utils.IsoSurface; -import org.noise_planet.noisemodelling.jdbc.DelaunayReceiversMaker; -import org.noise_planet.noisemodelling.pathfinder.delaunay.LayerDelaunayError; -import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; - -import org.noise_planet.noisemodelling.propagation.AttenuationParameters; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Paths; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; - -class Main { - public final static int MAX_OUTPUT_PROPAGATION_PATHS = 50000; - - public static NoiseMapByReceiverMaker mainWithConnection(Connection connection, String workingDir) throws SQLException, IOException, LayerDelaunayError { - - if(!new File(workingDir).exists()) { - new File(workingDir).mkdir(); - } - - DBTypes dbType = DBUtils.getDBType(connection.unwrap(Connection.class)); - - TableLocation tableLwRoads = TableLocation.parse("LW_ROADS", dbType); - TableLocation tableBuildings = TableLocation.parse("BUILDINGS", dbType); - TableLocation tableDemLorient = TableLocation.parse("DEM", dbType); - String heightField = dbType.equals(DBTypes.POSTGIS) ? "height" : "HEIGHT"; - - // Init output logger - Logger logger = LoggerFactory.getLogger(Main.class); - - Statement sql = connection.createStatement(); - - // Import BUILDINGS - - logger.info("Import buildings"); - - GeoJsonRead.importTable(connection, Main.class.getResource("buildings.geojson").getFile(), tableBuildings.toString(), - ValueBoolean.TRUE); - - // Import noise source - - logger.info("Import noise source"); - - GeoJsonRead.importTable(connection, Main.class.getResource("lw_roads.geojson").getFile(), tableLwRoads.toString(), - ValueBoolean.TRUE); - // Set primary key - sql.execute("ALTER TABLE "+tableLwRoads+" ALTER COLUMN PK SET NOT NULL"); - sql.execute("ALTER TABLE "+tableLwRoads+" ADD PRIMARY KEY (PK)"); - - // Import BUILDINGS - - logger.info("Generate receivers grid for noise map rendering"); - - DelaunayReceiversMaker noiseMap = new DelaunayReceiversMaker(tableBuildings.toString(), - tableLwRoads.toString()); - - noiseMap.setGridDim(1); - noiseMap.setMaximumArea(0); - noiseMap.setIsoSurfaceInBuildings(false); - noiseMap.setHeightField(heightField); - sql.execute("DROP TABLE IF EXISTS RECEIVERS;"); - sql.execute("DROP TABLE IF EXISTS TRIANGLES;"); - - noiseMap.run(connection, "RECEIVERS", "TRIANGLES"); - - // Import MNT - - logger.info("Import digital elevation model"); - - GeoJsonRead.importTable(connection, Main.class.getResource("dem_lorient.geojson").getFile(), - tableDemLorient.toString(), - ValueBoolean.TRUE); - - // Init NoiseModelling - NoiseMapByReceiverMaker noiseMapByReceiverMaker = new NoiseMapByReceiverMaker(tableBuildings.toString(), - tableLwRoads.toString(), "RECEIVERS"); - noiseMapByReceiverMaker.setMaximumPropagationDistance(100.0); - noiseMapByReceiverMaker.setFrequencyFieldPrepend("LW"); - noiseMapByReceiverMaker.setSoundReflectionOrder(0); - //noiseMapByReceiverMaker.setThreadCount(1); - noiseMapByReceiverMaker.setComputeHorizontalDiffraction(false); - noiseMapByReceiverMaker.setComputeVerticalDiffraction(true); - noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().setMaximumError(3.0); - noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().exportReceiverPosition = true; - - // Building height field name - noiseMapByReceiverMaker.setHeightField(heightField); - // Point cloud height above sea level POINT(X Y Z) - noiseMapByReceiverMaker.setDemTable(tableDemLorient.toString()); - - RootProgressVisitor progressLogger = new RootProgressVisitor(1, true, 1); - - String atmosphericSettingsTableName = "ATMOSPHERIC_SETTINGS"; - - sql.execute("DROP TABLE IF EXISTS " + atmosphericSettingsTableName + ";"); - - AttenuationParameters defaultParameters = new AttenuationParameters(); - defaultParameters.setTemperature(20); - defaultParameters.writeToDatabase(connection, atmosphericSettingsTableName, "D"); - defaultParameters.setTemperature(16); - defaultParameters.writeToDatabase(connection, atmosphericSettingsTableName, "E"); - defaultParameters.setTemperature(10); - defaultParameters.writeToDatabase(connection, atmosphericSettingsTableName, "N"); - - noiseMapByReceiverMaker.setGridDim(1); - noiseMapByReceiverMaker.getSceneInputSettings().setPeriodAtmosphericSettingsTableName(atmosphericSettingsTableName); - - noiseMapByReceiverMaker.run(connection, progressLogger); - - logger.info("Create iso contours"); - int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse("LW_ROADS", DBTypes.H2GIS)); - List isoLevels = IsoSurface.NF31_133_ISO; // default values - IsoSurface isoSurface = new IsoSurface(isoLevels, srid); - isoSurface.setSmoothCoefficient(0.5); - isoSurface.setPointTable(TableLocation.parse(noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().receiversLevelTable, dbType).toString()); - isoSurface.createTable(connection, "IDRECEIVER"); - logger.info("Export iso contours"); - - SHPWrite.exportTable(connection, Paths.get(workingDir, isoSurface.getOutputTable()+".shp").toString(), - isoSurface.getOutputTable(), ValueBoolean.TRUE); - - SHPWrite.exportTable(connection, Paths.get(workingDir, noiseMapByReceiverMaker.getSourcesTableName()+".shp").toString(), - noiseMapByReceiverMaker.getSourcesTableName(), ValueBoolean.TRUE); - - SHPWrite.exportTable(connection, Paths.get(workingDir, noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().getReceiversLevelTable()+".shp").toString(), - noiseMapByReceiverMaker.getNoiseMapDatabaseParameters().getReceiversLevelTable(), ValueBoolean.TRUE); - - return noiseMapByReceiverMaker; - } - - public static void main(String[] args) throws SQLException, IOException, LayerDelaunayError { - // Init output logger - Logger logger = LoggerFactory.getLogger(Main.class); - - // Read working directory argument - String workingDir = "target"; - if (args.length > 0) { - workingDir = args[0]; - } - File workingDirPath = new File(workingDir).getAbsoluteFile(); - if(!workingDirPath.exists()) { - if(!workingDirPath.mkdirs()) { - logger.error("Cannot create working directory {}", workingDir); - return; - } - } - - logger.info("Working directory is {}", workingDirPath.getAbsolutePath()); - - // Create spatial database named to current time - DateFormat df = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.getDefault()); - - // Open connection to database - String dbName = Paths.get(workingDir, "db_" + df.format(new Date())).toFile().toURI().toString(); - Connection connection = JDBCUtilities.wrapConnection(DbUtilities.createSpatialDataBase(dbName, true)); - mainWithConnection(connection, workingDir); - } - -} \ No newline at end of file diff --git a/noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/buildings.geojson b/noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/buildings.geojson deleted file mode 100644 index fea21e1d4..000000000 --- a/noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/buildings.geojson +++ /dev/null @@ -1 +0,0 @@ -{"type":"FeatureCollection","crs":{"type":"name","properties":{"name":"urn:ogc:def:crs:EPSG::2154"}},"features":[{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223859.54740430193,6758170.165471713],[223850.02396973874,6758172.277860589],[223853.00495847373,6758185.794532781],[223862.52447974018,6758183.7261641715],[223859.54740430193,6758170.165471713]]]]},"properties":{"pk":1,"id_way":69924152,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224034.16572043946,6758392.246513416],[224043.17979402497,6758396.052101915],[224046.34431292352,6758388.428692888],[224037.35855855464,6758384.609854282],[224034.16572043946,6758392.246513416]]]]},"properties":{"pk":2,"id_way":69924156,"height":6.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223908.6914025318,6757857.816858964],[223922.16934852864,6757851.757781981],[223917.41890721346,6757841.072266301],[223903.910656816,6757847.122772091],[223908.6914025318,6757857.816858964]]]]},"properties":{"pk":3,"id_way":69924159,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224024.4799910012,6757538.56580543],[224028.99023907035,6757535.94709761],[224025.0525102664,6757529.045223801],[224020.47929240591,6757531.701623864],[224024.4799910012,6757538.56580543]]]]},"properties":{"pk":4,"id_way":69924166,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224080.51364570754,6758041.656982586],[224064.30648725608,6758035.691864877],[224061.19550641792,6758044.065378081],[224077.48648142267,6758050.067387354],[224080.51364570754,6758041.656982586]]]]},"properties":{"pk":5,"id_way":69924217,"height":12.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223970.75727462143,6757812.588891271],[223976.77703712566,6757802.147158863],[223960.5608620103,6757792.658147811],[223954.51566990727,6757803.057904905],[223970.75727462143,6757812.588891271]]]]},"properties":{"pk":6,"id_way":69924277,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223936.87741493052,6758115.754255564],[223936.10696724954,6758115.752400438],[223935.40426354425,6758116.010959244],[223934.7163218784,6758116.6239331905],[223932.59228889458,6758122.259067299],[223948.60355054183,6758127.6544997785],[223945.75226571682,6758135.356247716],[223948.75550266428,6758136.369447456],[223954.37007887175,6758121.595999898],[223936.87741493052,6758115.754255564]]]]},"properties":{"pk":7,"id_way":69924344,"height":10.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223993.51317971537,6758023.856356537],[223990.83252108807,6758032.270254051],[223997.26937873074,6758034.240386023],[223999.176986586,6758028.112813128],[223999.442105539,6758028.2250748975],[224000.18939233627,6758025.855726817],[223993.51317971537,6758023.856356537]]]]},"properties":{"pk":8,"id_way":69924350,"height":10.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223708.7380274739,6757889.96382689],[223720.02176254027,6757905.826106686],[223731.97882912162,6757897.901619229],[223720.46111404413,6757881.6183660235],[223708.7380274739,6757889.96382689]]]]},"properties":{"pk":9,"id_way":69924431,"height":15.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223595.1415186031,6757546.758602015],[223592.7115342331,6757548.243732764],[223595.6409135292,6757552.823158417],[223598.02071805528,6757551.350942831],[223595.1415186031,6757546.758602015]]]]},"properties":{"pk":10,"id_way":69924506,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223795.59624134222,6758585.639878385],[223799.93001208728,6758573.442713352],[223787.45569708783,6758570.114485506],[223783.50333472548,6758581.260078275],[223795.59624134222,6758585.639878385]]]]},"properties":{"pk":11,"id_way":69924553,"height":10.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223724.45840230517,6757270.338135132],[223732.68113529528,6757264.694214384],[223732.184749126,6757264.064792771],[223730.78490105967,6757265.015576358],[223723.63850815917,6757255.242869744],[223717.0152065126,6757259.853162923],[223724.45840230517,6757270.338135132]]]]},"properties":{"pk":12,"id_way":69924564,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223806.56138853697,6758129.792698493],[223801.85633180075,6758131.835744977],[223802.9516308741,6758134.376663264],[223807.65983363587,6758132.290660718],[223806.56138853697,6758129.792698493]]]]},"properties":{"pk":13,"id_way":69924610,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223638.34798780823,6758135.347257016],[223632.98298626774,6758138.436902914],[223634.24092464923,6758140.639338637],[223639.60592453604,6758137.549693898],[223638.34798780823,6758135.347257016]]]]},"properties":{"pk":14,"id_way":69924611,"height":3.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224040.92450966637,6757583.603107879],[224039.54240970014,6757581.166568641],[224034.05045054934,6757584.226175302],[224035.2635315566,6757586.655363125],[224040.92450966637,6757583.603107879]]]]},"properties":{"pk":15,"id_way":69924621,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224049.128441533,6757970.584354519],[224051.46927101447,6757964.101328885],[224042.24845234794,6757960.744883408],[224039.8770154198,6757967.23457928],[224049.128441533,6757970.584354519]]]]},"properties":{"pk":16,"id_way":69924668,"height":9.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223920.37176301342,6757754.186041906],[223926.21387843354,6757769.4248435255],[223939.04163215,6757760.610062483],[223934.54260449627,6757753.8045930825],[223932.84243390546,6757749.379501506],[223920.37176301342,6757754.186041906]]]]},"properties":{"pk":17,"id_way":69924730,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223656.04350378027,6757285.40978055],[223648.10907656554,6757290.965172576],[223656.49895672407,6757302.745134113],[223664.4886788927,6757297.229562803],[223656.04350378027,6757285.40978055]]]]},"properties":{"pk":18,"id_way":69924733,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223598.93254300888,6758491.609668919],[223598.13969926137,6758500.260079782],[223609.5746188429,6758501.3303050585],[223610.37130322482,6758492.635762975],[223598.93254300888,6758491.609668919]]]]},"properties":{"pk":19,"id_way":69924750,"height":7.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223629.41499584535,6758356.217603228],[223619.47848920268,6758353.340955132],[223618.61156489176,6758357.967431775],[223627.72653462953,6758360.883702747],[223629.41499584535,6758356.217603228]]]]},"properties":{"pk":20,"id_way":69924818,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224138.86965165145,6758601.999525967],[224175.87897996293,6758619.599938112],[224179.80520154905,6758611.054250306],[224142.83062872913,6758593.538606535],[224138.86965165145,6758601.999525967]]]]},"properties":{"pk":21,"id_way":69924821,"height":16.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223743.5402591221,6758410.7728138855],[223744.34462993874,6758414.013544211],[223749.3167365697,6758415.789333885],[223760.35750380615,6758385.618662965],[223733.23836732173,6758375.7676660465],[223724.3224737803,6758406.7208236],[223733.81116872124,6758410.381875221],[223740.06980397372,6758389.2232587375],[223753.07475559178,6758393.977617561],[223752.1322334781,6758396.597298092],[223747.6904713955,6758399.11841954],[223743.5402591221,6758410.7728138855]]]]},"properties":{"pk":22,"id_way":69924926,"height":13.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223634.92947030463,6757827.368137563],[223648.63980031194,6757817.956104225],[223642.933956559,6757809.729079619],[223629.25387853407,6757819.149759075],[223634.92947030463,6757827.368137563]]]]},"properties":{"pk":23,"id_way":69924933,"height":12.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223860.96592776966,6757342.3889095485],[223866.6404655193,6757350.537271479],[223870.9280431602,6757347.404884932],[223891.22010041043,6757376.0767105445],[223896.15305390867,6757372.647171008],[223892.99595982584,6757368.176735493],[223914.31145992278,6757353.013666824],[223911.6029471984,6757349.231858556],[223910.97676231558,6757349.76251576],[223910.83153085926,6757349.67199528],[223907.8725359776,6757345.498859071],[223908.6444682398,6757344.913064508],[223894.37822524097,6757324.97726845],[223893.54582514812,6757325.568399011],[223891.54916169733,6757322.7624378335],[223892.43485039123,6757322.088808074],[223888.62080525653,6757316.714167329],[223865.2706374599,6757333.22118764],[223865.9499803412,6757334.165193825],[223868.02971794838,6757332.70277555],[223870.06261647402,6757335.71143701],[223868.07161842586,6757337.131957167],[223868.31312132475,6757337.494117347],[223860.96592776966,6757342.3889095485]]]]},"properties":{"pk":24,"id_way":69924939,"height":10.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223675.53699446763,6758181.997870608],[223683.14867401135,6758178.7425188115],[223684.47419413805,6758181.545751991],[223681.92577784794,6758192.10411376],[223694.23407937717,6758195.529345843],[223682.32921337712,6758168.33837815],[223671.66633858476,6758172.936563132],[223675.53699446763,6758181.997870608]]]]},"properties":{"pk":25,"id_way":69924994,"height":10.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223853.29619276675,6758064.440709521],[223866.2784475611,6758057.101093468],[223863.57217615054,6758052.329332909],[223855.9588548634,6758056.62188385],[223854.17411416088,6758053.564097405],[223871.9852858515,6758043.581205199],[223873.7090451978,6758046.67845587],[223866.47641947045,6758050.773886302],[223869.06134458637,6758055.498366132],[223879.32526922371,6758049.693902039],[223869.65312837297,6758032.398862157],[223843.5368593164,6758047.174639586],[223853.29619276675,6758064.440709521]]]]},"properties":{"pk":26,"id_way":69924996,"height":13.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224105.00149793472,6757484.514108932],[224089.84302718105,6757495.249546107],[224093.1502040629,6757499.948648882],[224111.25461545153,6757487.1867233515],[224107.96863661005,6757482.485194544],[224105.00149793472,6757484.514108932]]]]},"properties":{"pk":27,"id_way":69925004,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223732.14558674538,6757897.791027428],[223739.63074884893,6757892.823415028],[223734.48980095726,6757885.031950909],[223726.7381443606,6757890.162964249],[223732.14558674538,6757897.791027428]]]]},"properties":{"pk":28,"id_way":69925056,"height":6.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224025.780846915,6757706.511040996],[224033.04205307656,6757701.689294776],[224033.59141347522,6757701.26647079],[224034.04380498882,6757700.547829132],[224034.12968610117,6757698.918949723],[224028.82088171202,6757688.626703333],[224019.0391683265,6757693.762018631],[224025.780846915,6757706.511040996]]]]},"properties":{"pk":29,"id_way":69925155,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223649.92532904277,6757576.503363924],[223656.75451418647,6757571.695375913],[223647.8052358394,6757559.125213162],[223640.976040794,6757563.93321154],[223649.92532904277,6757576.503363924]]]]},"properties":{"pk":30,"id_way":69925163,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223828.72537926957,6758647.917441464],[223839.78280122005,6758619.015038624],[223821.98469458192,6758612.3789227875],[223821.330577338,6758614.237247635],[223817.5360854436,6758612.835585743],[223816.79707910802,6758614.579222431],[223814.27912293727,6758613.624248532],[223813.64319072163,6758615.23291868],[223807.33982247286,6758617.468846675],[223806.72142987855,6758619.297223928],[223795.39040848106,6758615.016291213],[223788.52851238177,6758633.133989032],[223828.72537926957,6758647.917441464]]]]},"properties":{"pk":31,"id_way":69925221,"height":18.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223905.74647490017,6757922.640041301],[223901.42052771457,6757914.945569456],[223891.90122721094,6757920.399321167],[223896.22360324266,6757928.050321245],[223905.74647490017,6757922.640041301]]]]},"properties":{"pk":32,"id_way":69925235,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224047.01081391185,6757594.262031437],[224041.910419275,6757597.001799528],[224043.31591219042,6757599.513660113],[224048.3902246538,6757596.733329823],[224047.01081391185,6757594.262031437]]]]},"properties":{"pk":33,"id_way":69925242,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223823.66302851785,6758175.330595925],[223824.23194427055,6758177.9662451735],[223829.23727325114,6758175.390303654],[223828.66472069937,6758172.712025625],[223823.66302851785,6758175.330595925]]]]},"properties":{"pk":34,"id_way":69925284,"height":3.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224004.29873805653,6758016.039312304],[224006.01725632165,6758011.133266033],[223998.2833318629,6758008.538671628],[223996.78563192373,6758013.478390625],[224004.29873805653,6758016.039312304]]]]},"properties":{"pk":35,"id_way":69925286,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224216.54590764202,6757649.880190256],[224219.4798152034,6757649.51829012],[224218.83946639602,6757644.097299229],[224215.98562591724,6757644.463066073],[224216.54590764202,6757649.880190256]]]]},"properties":{"pk":36,"id_way":69925295,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224016.9208171845,6758563.785849378],[224021.03456756522,6758554.304082932],[224012.6088407917,6758550.579044492],[224008.8418037401,6758559.834953805],[224016.9208171845,6758563.785849378]]]]},"properties":{"pk":37,"id_way":69925338,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224042.6443413726,6757859.131296448],[224034.28343673007,6757856.023022084],[224031.43311516233,6757863.8172698105],[224039.79783804683,6757866.8816311965],[224042.6443413726,6757859.131296448]]]]},"properties":{"pk":38,"id_way":69925395,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223933.91197551572,6758008.605187262],[223936.90589903272,6758006.912932735],[223931.51627947605,6757997.397498989],[223924.90314822874,6758001.124133188],[223934.72226947814,6758018.307321136],[223941.04059177145,6758014.704331871],[223937.26879492248,6758007.601333478],[223934.310777169,6758009.253009709],[223933.91197551572,6758008.605187262]]]]},"properties":{"pk":39,"id_way":69925440,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223713.21033883616,6758521.280537148],[223703.16298497276,6758520.364960003],[223702.24241395766,6758530.59139199],[223712.40787028585,6758530.961813613],[223713.21033883616,6758521.280537148]]]]},"properties":{"pk":40,"id_way":69925441,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224122.05250204733,6757437.836176784],[224126.98227293126,6757444.8749239985],[224129.62204809373,6757443.0491271885],[224129.40590832854,6757442.592125993],[224130.48216226403,6757442.126283329],[224130.59680590886,6757442.419149997],[224133.42512837198,6757440.484261035],[224132.5035628525,6757437.444796614],[224129.27814490272,6757438.584109959],[224127.230066499,6757433.01251831],[224121.71730201103,6757437.321396609],[224122.05250204733,6757437.836176784]]]]},"properties":{"pk":41,"id_way":69925449,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223741.96780304643,6758345.48401956],[223747.78936202655,6758347.096732157],[223748.8077458007,6758343.546336395],[223742.9355268184,6758341.927215604],[223741.96780304643,6758345.48401956]]]]},"properties":{"pk":42,"id_way":69925496,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223991.60419129865,6758563.268894169],[223985.51391362445,6758586.385041222],[223996.48029806738,6758589.2788707],[224002.18929369823,6758567.749005368],[223991.60419129865,6758563.268894169]]]]},"properties":{"pk":43,"id_way":69925499,"height":9.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223671.33609144276,6757938.243083842],[223671.45373951312,6757938.397017789],[223691.46070358192,6757925.06645682],[223675.70840461517,6757900.4039235115],[223674.14591867206,6757901.463212335],[223668.683772818,6757893.958151033],[223665.26879783766,6757896.351688939],[223660.7781673756,6757890.105813909],[223648.99591725523,6757898.421747163],[223650.8911775,6757900.953893948],[223652.4040287411,6757899.927753986],[223655.02881071816,6757903.609676685],[223651.88205576877,6757905.815719404],[223656.78280122712,6757913.056692813],[223655.2708394812,6757914.082355886],[223671.33609144276,6757938.243083842]]]]},"properties":{"pk":44,"id_way":69925503,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223564.7468562691,6757440.978326032],[223556.78034087844,6757446.341048233],[223558.24494969257,6757448.666864405],[223566.48591366663,6757443.491316022],[223564.7468562691,6757440.978326032]]]]},"properties":{"pk":45,"id_way":69925555,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223928.8503500337,6757963.5768496785],[223932.82753786026,6757972.465760466],[223919.64459114196,6757979.874568655],[223906.99267924082,6757957.422800645],[223903.79368572275,6757959.307663622],[223900.63013459544,6757953.932391712],[223884.44969410007,6757963.096140115],[223884.03505592595,6757962.427423899],[223877.68425879697,6757966.034728455],[223878.06447549377,6757966.739563961],[223862.23937919887,6757975.752505031],[223877.4704994647,6758003.169275231],[223876.93821428381,6758003.399788745],[223877.52223357838,6758004.3367944285],[223876.39752256605,6758008.197492942],[223875.58918657835,6758008.649016086],[223875.84046591975,6758009.062193031],[223876.62642807214,6758008.620650796],[223880.55496169406,6758009.71560677],[223880.87793874895,6758010.376565598],[223881.23934753085,6758010.160124924],[223880.94036008182,6758009.620614459],[223882.15610243054,6758005.588552209],[223882.96010033682,6758005.146935776],[223882.69680812157,6758004.678306238],[223895.41002175232,6757997.6060833745],[223895.75950210256,6757998.203003698],[223902.11774746556,6757994.757209658],[223901.78961116783,6757994.038240483],[223907.6231514451,6757990.755846146],[223909.65838106806,6757994.359669505],[223945.8629382424,6757974.2612057235],[223939.073146964,6757959.0174041195],[223928.8503500337,6757963.5768496785]]]]},"properties":{"pk":46,"id_way":69925595,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223914.6708518802,6758263.275864828],[223924.36392071508,6758266.857152307],[223929.47952939558,6758252.961178064],[223919.72713595096,6758249.450899526],[223918.76818482936,6758252.090724857],[223910.4557889758,6758249.2388941385],[223907.07039267546,6758258.204236929],[223915.41631748856,6758261.1410083575],[223914.6708518802,6758263.275864828]]]]},"properties":{"pk":47,"id_way":69925638,"height":10.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223600.78257540741,6758112.627877911],[223603.9061369283,6758118.344467556],[223606.42863216152,6758116.942164763],[223603.279077989,6758111.270013856],[223600.78257540741,6758112.627877911]]]]},"properties":{"pk":48,"id_way":69925639,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223511.3872831051,6757456.212597961],[223510.0425843303,6757449.775260881],[223503.66633875406,6757451.02576109],[223505.00348291185,6757457.550224921],[223511.3872831051,6757456.212597961]]]]},"properties":{"pk":49,"id_way":69925642,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223913.09040054696,6757266.076570603],[223911.46398572883,6757263.828730593],[223905.9324017005,6757267.686099704],[223910.96060625458,6757274.886700431],[223916.5776928635,6757270.902867945],[223913.09040054696,6757266.076570603]]]]},"properties":{"pk":50,"id_way":69925645,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223970.41272212513,6758450.586586708],[223973.27830669246,6758462.013340529],[223981.15015578133,6758464.001627364],[223983.06763012902,6758456.535739657],[223977.65215044733,6758455.224465656],[223978.2287335701,6758452.380695531],[223978.76828463035,6758452.488403528],[223977.83260942172,6758448.673286841],[223970.41272212513,6758450.586586708]]]]},"properties":{"pk":51,"id_way":69925675,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224146.65758756208,6757864.523328429],[224149.78046643324,6757855.592104919],[224145.19679751515,6757853.89053821],[224145.46853153207,6757852.978102338],[224139.16000373117,6757850.7333358945],[224138.77956542253,6757851.611471883],[224127.34571764618,6757847.492783156],[224127.6737973522,6757846.618921273],[224121.0933949752,6757844.2274575895],[224120.85996014156,6757845.059780879],[224113.48123761395,6757842.397141214],[224110.27873151348,6757851.246171181],[224119.2993231999,6757854.587035837],[224118.79365520435,6757855.966428189],[224121.8054607889,6757857.120432836],[224122.36712748624,6757855.7057534745],[224136.48824063595,6757860.811253956],[224135.9492668087,6757862.4406999145],[224138.906428562,6757863.63022017],[224139.53080511504,6757861.978362949],[224146.65758756208,6757864.523328429]]]]},"properties":{"pk":52,"id_way":69925682,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223905.12828207025,6757742.306467712],[223900.69532526695,6757730.689238929],[223890.866921147,6757736.328106842],[223896.29240494958,6757745.931083318],[223899.64808496626,6757744.663189719],[223899.58823753678,6757744.468322952],[223905.12828207025,6757742.306467712]]]]},"properties":{"pk":53,"id_way":69925729,"height":12.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223787.34700436468,6757922.025189164],[223781.41355710727,6757925.319312319],[223783.17320662056,6757928.427209048],[223789.05011371546,6757925.061703656],[223787.34700436468,6757922.025189164]]]]},"properties":{"pk":54,"id_way":69925773,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223730.23271332067,6758522.737094761],[223723.59479384386,6758522.147662158],[223722.73107570826,6758531.299839107],[223729.4292920278,6758531.548928682],[223730.23271332067,6758522.737094761]]]]},"properties":{"pk":55,"id_way":69925775,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223971.65553450302,6757673.714518391],[223972.05320871124,6757674.289972934],[223973.01760094517,6757674.971567323],[223973.96564945715,6757675.165067788],[223974.6850723542,6757675.096253722],[223983.36876132828,6757670.355497119],[223979.39739945682,6757663.411025923],[223976.45375046058,6757665.022510363],[223974.2682903083,6757660.511900857],[223967.01323647276,6757663.968962639],[223971.65553450302,6757673.714518391]]]]},"properties":{"pk":56,"id_way":69925778,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223775.91681646378,6758366.386196576],[223776.82176116752,6758363.968627749],[223773.61582152423,6758362.925923134],[223771.71078849485,6758368.210498094],[223764.63704820967,6758365.626315113],[223761.1362158295,6758374.723735724],[223770.47527014482,6758378.143760997],[223775.0309887244,6758366.023103237],[223775.91681646378,6758366.386196576]]]]},"properties":{"pk":57,"id_way":69925818,"height":12.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224092.36132484293,6758402.38592886],[224096.9090867849,6758404.301152193],[224100.0422569134,6758396.983007842],[224097.56764178397,6758396.022047058],[224096.95807104622,6758397.471990291],[224095.93302588924,6758397.855853116],[224094.4825756393,6758397.285878181],[224092.36132484293,6758402.38592886]]]]},"properties":{"pk":58,"id_way":69925820,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223871.40362118447,6757892.036270868],[223882.0749224011,6757911.001067518],[223890.6484394643,6757906.135943632],[223879.79755265152,6757887.252090169],[223871.40362118447,6757892.036270868]]]]},"properties":{"pk":59,"id_way":69925824,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223961.9554065906,6757585.465334421],[223967.73846990187,6757596.9175120555],[223978.2872153198,6757591.418910681],[223971.94925676082,6757578.830668066],[223970.82285356394,6757579.435237665],[223970.01837352585,6757581.205904029],[223961.9554065906,6757585.465334421]]]]},"properties":{"pk":60,"id_way":69925829,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224098.87628237222,6758042.644306944],[224103.8748284933,6758028.670414348],[224087.5472360013,6758022.780978265],[224085.62467759877,6758028.115847863],[224096.74510971858,6758032.245447302],[224093.74285474268,6758040.692376828],[224098.87628237222,6758042.644306944]]]]},"properties":{"pk":61,"id_way":69925867,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223974.98925763977,6757893.535928981],[223976.97385761983,6757888.151396103],[223974.2853477596,6757887.149077241],[223972.27920000514,6757892.535080192],[223974.98925763977,6757893.535928981]]]]},"properties":{"pk":62,"id_way":69925925,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223628.14619320247,6758097.290784238],[223614.57018119338,6758104.91389387],[223617.71605299975,6758110.629798619],[223631.32554056944,6758102.971278737],[223628.14619320247,6758097.290784238]]]]},"properties":{"pk":63,"id_way":69925969,"height":3.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223758.5852800179,6758060.835103087],[223766.48959097356,6758075.561824409],[223792.16155466996,6758060.978460698],[223783.99479026193,6758046.325648107],[223772.90912606366,6758052.485157432],[223773.0891572756,6758052.760367678],[223758.5852800179,6758060.835103087]]]]},"properties":{"pk":64,"id_way":69925970,"height":12.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223545.93292690403,6757502.421000477],[223549.18479484954,6757517.2722450225],[223562.14024014122,6757514.534572778],[223560.9810195924,6757509.083592843],[223558.40325802713,6757509.545151294],[223551.36192486732,6757498.973473684],[223545.93292690403,6757502.421000477]]]]},"properties":{"pk":65,"id_way":69925975,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224007.8994906623,6757454.472443049],[224011.56124081224,6757451.872366968],[224007.07875178833,6757445.784656445],[224003.50462261157,6757448.387703878],[224007.8994906623,6757454.472443049]]]]},"properties":{"pk":66,"id_way":69925979,"height":3.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223654.92827938276,6757933.379083717],[223637.9571377343,6757905.581301547],[223641.19201754645,6757903.415768658],[223635.80939163567,6757895.3114053765],[223624.88063508048,6757903.004894266],[223646.71229384042,6757938.542516877],[223654.92827938276,6757933.379083717]]]]},"properties":{"pk":67,"id_way":69926028,"height":13.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223949.21318986532,6757726.507727882],[223957.21644423978,6757721.96877582],[223948.1017187171,6757705.532939118],[223938.9999961069,6757710.827688259],[223944.24225852016,6757719.588724765],[223945.1397959959,6757719.078444467],[223947.89600694555,6757723.8768076785],[223949.21318986532,6757726.507727882]]]]},"properties":{"pk":68,"id_way":69926081,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223861.16949821252,6758597.095622616],[223881.4573202391,6758604.923164689],[223887.21720342772,6758589.765728802],[223879.04707056575,6758587.32540516],[223877.67151585894,6758592.659438749],[223864.70028550056,6758587.894272133],[223861.16949821252,6758597.095622616]]]]},"properties":{"pk":69,"id_way":69926156,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223758.47420995947,6757951.294061736],[223759.30101202594,6757950.837199032],[223754.02525496366,6757941.436558721],[223743.79526969162,6757947.205630685],[223749.09622771136,6757956.63809208],[223758.47420995947,6757951.294061736]]]]},"properties":{"pk":70,"id_way":69926168,"height":9.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224152.31921508702,6757640.09152144],[224151.981537625,6757634.350646662],[224151.2238642447,6757628.58921429],[224150.0760545974,6757622.959838611],[224139.9637592802,6757625.503365099],[224140.87828589365,6757629.545582778],[224140.51641628842,6757629.586067049],[224141.44767279935,6757635.997837835],[224141.8741486845,6757635.997099331],[224142.15938574038,6757640.463009313],[224152.31921508702,6757640.09152144]]]]},"properties":{"pk":71,"id_way":69926181,"height":16.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223661.73246537114,6758161.184520274],[223664.25951495662,6758158.721942359],[223660.70161403212,6758154.9955926305],[223658.0912070111,6758157.497480843],[223661.73246537114,6758161.184520274]]]]},"properties":{"pk":72,"id_way":69926230,"height":3.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224038.56283057015,6758072.472994938],[224039.57295610278,6758069.584375291],[224035.24798551726,6758067.993047094],[224038.9359701529,6758058.088149935],[224030.5746530268,6758055.1332992185],[224025.7969020035,6758068.286753312],[224038.56283057015,6758072.472994938]]]]},"properties":{"pk":73,"id_way":69926232,"height":10.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223583.6654049423,6757327.207824699],[223591.09524487067,6757321.929100008],[223586.72223829394,6757315.921399991],[223579.3598467722,6757321.129461592],[223583.6654049423,6757327.207824699]]]]},"properties":{"pk":74,"id_way":69926237,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224135.90191515224,6757455.597241684],[224138.8890687482,6757459.941936596],[224141.25829899823,6757458.272114001],[224139.1276973361,6757453.321377587],[224135.90191515224,6757455.597241684]]]]},"properties":{"pk":75,"id_way":69926242,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223942.26274202135,6758574.951349969],[223948.6813834476,6758550.913097565],[223935.17302926906,6758547.3442803],[223928.8996417832,6758571.426083923],[223942.26274202135,6758574.951349969]]]]},"properties":{"pk":76,"id_way":69926294,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224076.84342635787,6757893.697889636],[224079.81051023823,6757885.46981952],[224071.62370862244,6757882.371216126],[224068.71649599637,6757890.703430968],[224076.84342635787,6757893.697889636]]]]},"properties":{"pk":77,"id_way":69926300,"height":9.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223859.98850215023,6757813.352948014],[223864.06229796156,6757810.667895666],[223861.87388462582,6757807.3119507665],[223857.85629862567,6757810.1528545525],[223859.98850215023,6757813.352948014]]]]},"properties":{"pk":78,"id_way":69926353,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223591.57398285193,6757993.983876426],[223593.74960154583,6757994.723681579],[223591.33658874995,6758002.969607106],[223612.68529176104,6758008.221450868],[223606.50224199946,6758033.728692378],[223569.68395861713,6758022.834710112],[223566.6132683142,6758033.451332352],[223615.86946137942,6758048.148844119],[223619.03000983244,6758037.519251547],[223618.37980155798,6758037.282038963],[223625.5909707713,6758012.61919375],[223672.60806053944,6758026.533185372],[223675.59845810797,6758015.634706888],[223621.06714724086,6757999.621347638],[223620.65462458148,6758000.84791945],[223616.6895305675,6757999.653424186],[223615.9127097393,6758002.223111902],[223612.67375421166,6758001.288397733],[223614.7353368705,6757994.143956262],[223595.54101105256,6757988.596417623],[223595.41784804556,6757988.9551035175],[223593.27769143795,6757988.248975585],[223596.7633008972,6757976.689438502],[223594.29012075302,6757975.948104791],[223592.14747914055,6757983.299934815],[223588.9803543841,6757982.340849322],[223587.75444039647,6757986.564918007],[223590.91822126228,6757987.479798437],[223587.7035665667,6757998.495908513],[223590.0284741427,6757999.162818538],[223591.57398285193,6757993.983876426]]]]},"properties":{"pk":79,"id_way":69926396,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224288.56777369493,6757222.179646835],[224291.62595588714,6757230.724524208],[224298.89837984362,6757228.23714697],[224295.697082609,6757219.649627354],[224288.56777369493,6757222.179646835]]]]},"properties":{"pk":80,"id_way":69926406,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223637.63668841327,6758550.103154478],[223641.82065728292,6758550.7977918675],[223643.2839186209,6758542.068601951],[223639.07167375353,6758541.386748286],[223637.63668841327,6758550.103154478]]]]},"properties":{"pk":81,"id_way":69926452,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223578.0799861324,6757884.252339194],[223570.40249458194,6757888.687907846],[223577.70917619002,6757901.203410865],[223585.3914587747,6757896.734698099],[223578.0799861324,6757884.252339194]]]]},"properties":{"pk":82,"id_way":69926456,"height":10.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223853.75772024223,6758616.554033007],[223862.0659776839,6758619.742811863],[223864.85086762757,6758612.58671079],[223856.48090435128,6758609.359409269],[223853.75772024223,6758616.554033007]]]]},"properties":{"pk":83,"id_way":69926501,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223735.67717733924,6757811.220978211],[223747.0318663333,6757804.859090254],[223739.01336256784,6757790.719007966],[223727.7432359987,6757797.117920435],[223735.67717733924,6757811.220978211]]]]},"properties":{"pk":84,"id_way":69926504,"height":10.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223832.3491370888,6757719.008640718],[223824.29993936088,6757722.862004479],[223818.66160816292,6757726.822169745],[223822.78862480208,6757733.937376223],[223836.2243530853,6757727.878168627],[223832.3491370888,6757719.008640718]]]]},"properties":{"pk":85,"id_way":69926506,"height":9.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223754.40331958138,6758202.692723531],[223764.33145075978,6758198.41075155],[223752.76270196008,6758171.913647947],[223742.90454914002,6758176.233578677],[223754.40331958138,6758202.692723531]]]]},"properties":{"pk":86,"id_way":69926528,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223889.78605932466,6758043.788901067],[223885.51487394876,6758036.212302235],[223883.11509841203,6758037.57010045],[223887.37912950048,6758045.147368553],[223889.78605932466,6758043.788901067]]]]},"properties":{"pk":87,"id_way":69926529,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224367.90880745352,6757470.764256033],[224368.62327411803,6757472.077290721],[224369.56931999698,6757472.887508146],[224371.27017938113,6757473.348780711],[224372.73944757227,6757473.090885368],[224373.9837415635,6757472.240398697],[224374.7629501474,6757470.942457417],[224374.97118316457,6757469.712536689],[224374.65584995245,6757468.250696216],[224373.760704994,6757467.052499549],[224372.69867203874,6757466.4014218105],[224371.72671884875,6757466.166851122],[224370.7085901619,6757466.205381761],[224369.75912810725,6757466.509965416],[224368.92332859072,6757467.085496872],[224368.05607165818,6757468.317246304],[224367.82249809918,6757469.039064209],[224367.76413319702,6757470.045328962],[224367.90880745352,6757470.764256033]]]]},"properties":{"pk":88,"id_way":69926533,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223837.88491154677,6758434.313839797],[223856.22212038378,6758441.075582337],[223859.72216446244,6758431.554912755],[223856.47953502284,6758430.30931752],[223855.10787014334,6758433.986614275],[223848.950472854,6758431.655874908],[223852.13432304977,6758423.050088376],[223843.23631037454,6758419.707529275],[223837.88491154677,6758434.313839797]]]]},"properties":{"pk":89,"id_way":69926551,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224195.7270661101,6757766.412220666],[224178.89969398206,6757760.207595755],[224175.7569347993,6757768.861817101],[224192.55019724538,6757775.102341141],[224195.7270661101,6757766.412220666]]]]},"properties":{"pk":90,"id_way":69926556,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223896.10522121948,6757829.583252493],[223904.93549370533,6757825.5390262185],[223901.42028246354,6757817.497938463],[223892.58864942825,6757821.706059844],[223896.10522121948,6757829.583252493]]]]},"properties":{"pk":91,"id_way":69926609,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223630.04105945237,6757341.1340569025],[223638.77888039354,6757353.232011358],[223643.9842636187,6757349.525498435],[223638.28281799305,6757341.5386794675],[223637.51322535798,6757342.045815509],[223634.46944067796,6757337.936863004],[223630.04105945237,6757341.1340569025]]]]},"properties":{"pk":92,"id_way":69926613,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223689.50531691872,6758008.744729881],[223697.8165753263,6758003.64936628],[223694.46406263125,6757998.002663096],[223686.07196423638,6758003.093343218],[223689.50531691872,6758008.744729881]]]]},"properties":{"pk":93,"id_way":69926659,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223955.58310032636,6757618.391303635],[223960.35262691168,6757627.591603249],[223964.92647925063,6757625.313788632],[223966.30851344275,6757628.225501609],[223970.25410860346,6757625.814624111],[223964.00008118557,6757613.616473459],[223955.58310032636,6757618.391303635]]]]},"properties":{"pk":94,"id_way":69926662,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223849.82635342597,6758196.370980565],[223843.4309727272,6758197.778942522],[223844.18265821613,6758201.108595935],[223865.37051818366,6758196.449189237],[223862.56775433954,6758183.921428085],[223847.83193670338,6758187.124410222],[223849.82635342597,6758196.370980565]]]]},"properties":{"pk":95,"id_way":69926701,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224037.23367040098,6758534.697125867],[224027.5948105898,6758529.839278428],[224022.18631292862,6758540.504235706],[224031.79790432434,6758545.298616374],[224037.23367040098,6758534.697125867]]]]},"properties":{"pk":96,"id_way":69926703,"height":7.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223861.62335255445,6757842.036822837],[223870.32205560175,6757836.668578021],[223871.5962984842,6757839.45377459],[223883.65597670508,6757834.066844188],[223879.87391750762,6757825.58976697],[223859.22370633966,6757838.327729638],[223861.62335255445,6757842.036822837]]]]},"properties":{"pk":97,"id_way":69926706,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224036.66755262253,6757511.776941564],[224040.51023734437,6757518.456365386],[224049.8540567266,6757513.039706241],[224044.8195097782,6757504.118805146],[224035.3040284362,6757509.417608834],[224036.66755262253,6757511.776941564]]]]},"properties":{"pk":98,"id_way":69926708,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224114.54191253046,6757935.67854008],[224117.62870495286,6757927.373390812],[224101.2769519187,6757921.407389543],[224098.19373336274,6757929.823402604],[224114.54191253046,6757935.67854008]]]]},"properties":{"pk":99,"id_way":69926739,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223805.54040928252,6757832.994543194],[223800.0122638603,6757824.8818820035],[223796.1170710913,6757827.459081234],[223800.8743207526,6757834.583729831],[223796.70030390174,6757836.79320293],[223805.20181599015,6757849.510722135],[223817.6621753348,6757841.311499452],[223812.40363072863,6757833.440619806],[223805.99853327498,6757837.73711365],[223803.70089931015,6757834.212185204],[223805.54040928252,6757832.994543194]]]]},"properties":{"pk":100,"id_way":69926762,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223919.9973636343,6758118.359411729],[223905.23225066578,6758112.790276244],[223894.58684888692,6758094.378589665],[223885.9809378211,6758099.23665052],[223900.48876312442,6758125.261080735],[223915.45052276124,6758130.651170363],[223919.9973636343,6758118.359411729]]]]},"properties":{"pk":101,"id_way":69926785,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223529.29997267172,6758013.824230206],[223546.93851520133,6757955.033825232],[223541.2739451249,6757953.410486974],[223512.05520735588,6758051.233067947],[223514.30344173862,6758053.060931649],[223513.84129672058,6758054.326490225],[223517.02020532952,6758055.342892265],[223529.29997267172,6758013.824230206]]]]},"properties":{"pk":102,"id_way":69926786,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223540.5678858618,6757567.070772743],[223539.32005321883,6757560.739682317],[223536.5855367307,6757561.293565333],[223537.74492110757,6757567.611333212],[223540.5678858618,6757567.070772743]]]]},"properties":{"pk":103,"id_way":69926788,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223986.27199964144,6758613.440842351],[223982.5894068678,6758627.540804023],[223998.18581207725,6758631.67035377],[224003.96620319344,6758618.01631009],[224002.68574822496,6758617.772731775],[224002.81479444285,6758617.474413805],[223999.0056759542,6758615.921983541],[223998.65645488258,6758616.742386242],[223986.27199964144,6758613.440842351]]]]},"properties":{"pk":104,"id_way":69926817,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223712.6092093207,6757926.135299483],[223712.72930994278,6757926.215926195],[223694.59590455418,6757938.45363909],[223702.53493076027,6757952.752599105],[223725.0301940787,6757940.339834815],[223716.0177744392,6757924.113844134],[223715.13445704183,6757924.692490259],[223714.9925355623,6757924.493830215],[223712.6092093207,6757926.135299483]]]]},"properties":{"pk":105,"id_way":69926819,"height":9.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223620.4850662612,6757524.932321779],[223617.64892835924,6757520.864946395],[223610.25385414308,6757526.1077622855],[223613.12321994742,6757530.1401666],[223620.4850662612,6757524.932321779]]]]},"properties":{"pk":106,"id_way":69926847,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223568.15200100557,6758374.597595264],[223566.6853462924,6758383.283013561],[223576.22810067996,6758384.892942886],[223577.72398163416,6758376.2051528],[223568.15200100557,6758374.597595264]]]]},"properties":{"pk":107,"id_way":69926875,"height":7.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223836.68934483358,6757238.984173605],[223832.0261337247,6757232.388133558],[223760.96402109356,6757282.60920569],[223765.74800503167,6757289.252920013],[223836.68934483358,6757238.984173605]]]]},"properties":{"pk":108,"id_way":69926879,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223940.22646145,6758141.396545789],[223942.93894229186,6758142.354996818],[223945.56838412693,6758135.277467501],[223942.89468451907,6758134.350711896],[223940.22646145,6758141.396545789]]]]},"properties":{"pk":109,"id_way":69926900,"height":9.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223797.44113731536,6758073.267915397],[223806.2019689315,6758088.856055125],[223806.00207360252,6758088.972132711],[223808.88033331354,6758093.932757908],[223824.5307944295,6758085.183530108],[223812.82859057284,6758064.51918775],[223797.44113731536,6758073.267915397]]]]},"properties":{"pk":110,"id_way":69926901,"height":13.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224136.03296985905,6757591.1156421965],[224131.91057954612,6757585.698859181],[224127.33609041318,6757580.56746832],[224122.47806483626,6757575.846509522],[224115.28340785208,6757583.899913636],[224119.11411704388,6757587.434858368],[224123.84736724765,6757592.869735426],[224124.17478162138,6757592.638538681],[224127.3672757093,6757597.139586654],[224136.03296985905,6757591.1156421965]]]]},"properties":{"pk":111,"id_way":69926905,"height":18.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224113.95570144636,6757953.089039301],[224128.9806958985,6757958.57805002],[224131.11501298097,6757952.602720764],[224104.34610143906,6757942.81888334],[224102.17962712795,6757948.75292424],[224113.95570144636,6757953.089039301]]]]},"properties":{"pk":112,"id_way":69926927,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223897.48414550867,6757804.114954757],[223902.8070751192,6757812.370217766],[223908.57155872343,6757808.579702316],[223903.16348604547,6757800.364185267],[223897.48414550867,6757804.114954757]]]]},"properties":{"pk":113,"id_way":69926951,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223656.42656491048,6757284.894292515],[223652.2935544047,6757278.925739669],[223643.82659479463,6757284.956692166],[223647.99301992313,6757290.802281334],[223656.42656491048,6757284.894292515]]]]},"properties":{"pk":114,"id_way":69926953,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223656.20393864228,6758406.29391718],[223659.24990068548,6758407.051316413],[223661.94807997585,6758396.299550337],[223658.839965184,6758395.503073909],[223662.39659697295,6758380.902814197],[223661.22352583107,6758380.595802186],[223650.46503400046,6758425.476670215],[223651.45375487546,6758425.675954013],[223656.20393864228,6758406.29391718]]]]},"properties":{"pk":115,"id_way":69926981,"height":16.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223646.36009543153,6758333.296482714],[223657.8542791312,6758337.503105928],[223661.62930328757,6758335.571719299],[223664.78983606046,6758322.402814479],[223656.0457129473,6758320.306561105],[223654.39805219945,6758327.024642213],[223649.11862600833,6758325.272741828],[223646.36009543153,6758333.296482714]]]]},"properties":{"pk":116,"id_way":69927058,"height":10.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223562.9754632885,6757857.694722111],[223553.663503755,6757854.6892497465],[223549.87767971997,6757867.601937355],[223559.3364867779,6757870.410117185],[223562.9754632885,6757857.694722111]]]]},"properties":{"pk":117,"id_way":69927061,"height":13.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224152.57530822363,6757720.627892377],[224160.82337471913,6757723.659147164],[224164.77268904026,6757712.873952994],[224156.59187287095,6757709.721756065],[224152.57530822363,6757720.627892377]]]]},"properties":{"pk":118,"id_way":69927064,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223831.00024888536,6758545.633668852],[223839.33061969027,6758547.815142647],[223841.57445640705,6758539.28531217],[223833.24749170546,6758537.147106999],[223831.00024888536,6758545.633668852]]]]},"properties":{"pk":119,"id_way":69927109,"height":6.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223598.0645704507,6758388.929133026],[223607.94019779185,6758391.775525199],[223610.81147580198,6758381.265538846],[223599.91770336038,6758378.150949984],[223598.0645704507,6758388.929133026]]]]},"properties":{"pk":120,"id_way":69927111,"height":6.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224011.48125515346,6757872.310257596],[224014.5377055911,6757864.096585171],[224000.6687190324,6757858.880949878],[223997.58246072437,6757867.185008436],[224011.48125515346,6757872.310257596]]]]},"properties":{"pk":121,"id_way":69927112,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224045.16023239272,6758248.2196657425],[224050.44916841656,6758249.343949072],[224049.5531109214,6758253.88488804],[224058.17367141694,6758255.597911598],[224065.79340969367,6758217.967807646],[224049.20755905978,6758214.613290854],[224044.21356932123,6758239.171043492],[224043.0592743336,6758238.940682332],[224042.72668123172,6758240.522813836],[224042.3947604582,6758240.435538056],[224041.76652819864,6758241.19143298],[224041.05888503228,6758244.7336635245],[224041.35716956577,6758245.730653052],[224041.68866748453,6758245.866450915],[224040.46899336475,6758251.608286918],[224044.32187764923,6758252.368723494],[224045.16023239272,6758248.2196657425]]]]},"properties":{"pk":122,"id_way":69927153,"height":7.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223800.4863664194,6758115.9936777875],[223795.87145816558,6758118.039082639],[223796.9700072639,6758120.537265455],[223801.6167216786,6758118.532314988],[223800.4863664194,6758115.9936777875]]]]},"properties":{"pk":123,"id_way":69927154,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223506.24389286575,6757539.541445917],[223491.52920220856,6757542.63954696],[223492.71785777333,6757548.016564955],[223496.04211609293,6757547.275925464],[223501.0285961518,6757551.286179016],[223508.77169592946,6757542.046203376],[223506.24389286575,6757539.541445917]]]]},"properties":{"pk":124,"id_way":69927156,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224070.5024137846,6757316.5305822],[224065.7850005408,6757319.903074547],[224066.58731087853,6757321.046938622],[224086.05542773037,6757306.937224195],[224085.44986803053,6757305.957919774],[224083.58882569362,6757307.207059988],[224082.9425966834,6757306.348463144],[224081.5898542397,6757307.334952564],[224082.20909724437,6757308.200019036],[224070.5024137846,6757316.5305822]]]]},"properties":{"pk":125,"id_way":69927158,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223802.40358894292,6757877.054218368],[223798.4091829114,6757869.87254369],[223797.80412292073,6757871.932913014],[223801.010763996,6757877.819658696],[223802.40358894292,6757877.054218368]]]]},"properties":{"pk":126,"id_way":69927180,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224005.5570508606,6757744.6727428045],[224021.58532690344,6757737.1296961205],[224016.8691121196,6757727.264927265],[224009.75582965088,6757730.692467728],[224007.51425544257,6757726.023721507],[223998.65581769357,6757730.190582754],[224005.5570508606,6757744.6727428045]]]]},"properties":{"pk":127,"id_way":69927213,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223566.67538028106,6757555.465282247],[223567.77999027088,6757561.829248477],[223570.55021033096,6757561.282901304],[223569.38274206565,6757554.954935626],[223566.67538028106,6757555.465282247]]]]},"properties":{"pk":128,"id_way":69927216,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223859.93936992146,6757898.475567004],[223856.5552749618,6757900.424867227],[223862.24321695094,6757910.902120533],[223858.9318278331,6757912.7341030445],[223853.11853054617,6757902.369241232],[223849.70413845248,6757904.277825099],[223860.4678002841,6757923.279216571],[223870.69557257718,6757917.477519606],[223859.93936992146,6757898.475567004]]]]},"properties":{"pk":129,"id_way":69927247,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224144.4579577832,6757606.226491284],[224142.05262966364,6757601.113183146],[224139.25364789637,6757596.017339266],[224136.14846424086,6757591.278932428],[224127.4771175052,6757597.306806272],[224130.5548919862,6757602.169755766],[224133.98677511307,6757608.231237588],[224134.94877084933,6757610.470424431],[224144.4579577832,6757606.226491284]]]]},"properties":{"pk":130,"id_way":69927253,"height":15.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224021.02439126407,6758109.447920875],[224025.3575801992,6758097.288682311],[224016.22836666735,6758094.564514791],[224011.8605776349,6758106.573518699],[224021.02439126407,6758109.447920875]]]]},"properties":{"pk":131,"id_way":69927286,"height":12.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224210.53781665734,6757650.685555783],[224209.91992520922,6757645.2734141825],[224207.00748601835,6757645.633565895],[224207.6541953072,6757651.043345806],[224210.53781665734,6757650.685555783]]]]},"properties":{"pk":132,"id_way":69927291,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223983.1251679855,6758510.461839372],[223974.9033152676,6758506.314163691],[223970.74650782451,6758514.304586762],[223978.99758071988,6758518.449890621],[223983.1251679855,6758510.461839372]]]]},"properties":{"pk":133,"id_way":69927314,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224032.6411058909,6757815.358450904],[224038.88109509376,6757798.529337418],[224032.35592492018,6757796.097706824],[224028.27519416506,6757806.989857508],[224025.90502511789,6757806.233199185],[224023.683749228,6757811.93283641],[224032.6411058909,6757815.358450904]]]]},"properties":{"pk":134,"id_way":69927353,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223713.15440911613,6758511.801837633],[223713.59087528594,6758506.826108563],[223700.44334941267,6758505.670031945],[223700.0322709064,6758510.599701712],[223713.15440911613,6758511.801837633]]]]},"properties":{"pk":135,"id_way":69927379,"height":9.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223927.55609991838,6758061.856713508],[223933.9614718766,6758058.258031324],[223922.14503403287,6758037.390000473],[223915.82349567546,6758040.915950012],[223927.55609991838,6758061.856713508]]]]},"properties":{"pk":136,"id_way":69927380,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224131.1093873277,6757239.234547966],[224132.48095084832,6757236.115819523],[224129.64099913245,6757234.60818632],[224130.773828268,6757231.698181867],[224127.72212546808,6757230.148531912],[224128.94555492475,6757227.228946586],[224122.39844425188,6757223.82451254],[224121.416866924,6757225.719328848],[224120.33304221026,6757225.17606874],[224118.10221893623,6757225.997220823],[224128.12423857074,6757252.851234548],[224130.2128989424,6757253.796301298],[224131.37499685126,6757251.340641651],[224132.61131019736,6757251.8806861695],[224137.60274959326,6757250.011896336],[224135.85245021718,6757245.360306902],[224132.9142501389,6757243.865327346],[224134.0416973289,6757240.862192688],[224131.1093873277,6757239.234547966]]]]},"properties":{"pk":137,"id_way":69927384,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223704.9500032991,6758343.008439612],[223698.68059895997,6758340.672680529],[223699.43771781595,6758338.618667224],[223695.0895090238,6758338.491409844],[223691.00912435786,6758349.420866579],[223701.2061929165,6758353.128322572],[223704.9500032991,6758343.008439612]]]]},"properties":{"pk":138,"id_way":69927420,"height":9.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223823.4146783114,6757914.444201438],[223841.58430152797,6757904.222078293],[223837.76388181912,6757897.478151416],[223819.61236214405,6757907.654915616],[223823.4146783114,6757914.444201438]]]]},"properties":{"pk":139,"id_way":69927423,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223944.8976235971,6757772.4065385],[223951.12925699446,6757781.382446848],[223957.07217055772,6757777.236054084],[223950.9291659514,6757768.263517909],[223944.8976235971,6757772.4065385]]]]},"properties":{"pk":140,"id_way":69927497,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223878.66273662983,6757617.674325753],[223882.14619301175,6757622.536655773],[223884.3925283814,6757620.920790827],[223880.93320103435,6757616.098156304],[223878.66273662983,6757617.674325753]]]]},"properties":{"pk":141,"id_way":69927499,"height":3.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223978.54051377636,6758053.95752275],[223976.17815982507,6758064.103472074],[223982.51225695692,6758065.685380148],[223984.18948929434,6758058.4707585],[223989.83707293464,6758059.976992159],[223990.55710501282,6758056.976137292],[224007.57897207703,6758061.480421379],[224009.33354537762,6758056.138186292],[223989.97458592095,6758050.783851456],[223988.63358033617,6758056.7112605255],[223978.54051377636,6758053.95752275]]]]},"properties":{"pk":142,"id_way":69927526,"height":6.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223821.16791304748,6758163.426889335],[223821.77340325958,6758166.315159562],[223826.77029555754,6758163.729312543],[223826.16910496043,6758160.808584115],[223821.16791304748,6758163.426889335]]]]},"properties":{"pk":143,"id_way":69927527,"height":3.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223558.58697343676,6757425.872461807],[223541.51723407122,6757437.774532752],[223549.73821145645,6757450.778888067],[223556.5076013208,6757446.282826142],[223552.34725921266,6757439.641060034],[223563.07590586896,6757432.511649533],[223558.58697343676,6757425.872461807]]]]},"properties":{"pk":144,"id_way":69927529,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223969.6029011347,6758415.830396875],[223962.2391914409,6758417.706475503],[223962.40294103834,6758418.419412502],[223969.76311893386,6758416.51119824],[223969.6029011347,6758415.830396875]]]]},"properties":{"pk":145,"id_way":69927550,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224083.22312533093,6757827.696506551],[224087.64125621956,6757815.772966247],[224057.82707836208,6757804.686921981],[224054.98811898567,6757812.111542371],[224056.2540456372,6757812.543686197],[224054.56629916397,6757817.408468109],[224055.15320047695,6757818.654805426],[224056.88599419154,6757819.412392047],[224058.71831865126,6757818.5857299445],[224083.22312533093,6757827.696506551]]]]},"properties":{"pk":146,"id_way":69927553,"height":15.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223672.05119490201,6757801.29639043],[223683.33165882106,6757793.529663636],[223670.12787874497,6757774.471824265],[223658.78940484137,6757782.353459975],[223672.05119490201,6757801.29639043]]]]},"properties":{"pk":147,"id_way":69927579,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223637.9457163751,6758468.206141989],[223638.95153874805,6758458.880169561],[223619.22718706343,6758456.809794762],[223618.25197572945,6758466.243570281],[223637.9457163751,6758468.206141989]]]]},"properties":{"pk":148,"id_way":69927588,"height":7.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223877.74511088373,6758440.452718191],[223878.48255854446,6758438.424303105],[223874.73620220466,6758437.06033115],[223873.99875558235,6758439.08874672],[223877.74511088373,6758440.452718191]]]]},"properties":{"pk":149,"id_way":69927602,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223718.65888692837,6758426.258202741],[223716.39116722372,6758434.155309931],[223727.80442128304,6758438.134938891],[223730.04503607546,6758430.360629565],[223718.65888692837,6758426.258202741]]]]},"properties":{"pk":150,"id_way":69927604,"height":13.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223762.73143949427,6757922.281481738],[223761.0537467133,6757919.28668687],[223755.06655257058,6757922.466383298],[223756.80046218078,6757925.607983111],[223762.73143949427,6757922.281481738]]]]},"properties":{"pk":151,"id_way":69927605,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224001.7459503658,6757659.937665762],[224011.32227698003,6757654.488403797],[224005.66304439638,6757643.511688197],[223995.413533726,6757648.774951963],[224001.7459503658,6757659.937665762]]]]},"properties":{"pk":152,"id_way":69927609,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223892.73021600544,6758264.769127439],[223902.07093610134,6758268.199995909],[223905.83615013494,6758257.968700626],[223896.5016035477,6758254.613836864],[223892.73021600544,6758264.769127439]]]]},"properties":{"pk":153,"id_way":69927636,"height":12.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224080.37310182123,6758408.63839363],[224084.04438112612,6758410.231215767],[224084.79788822605,6758408.410289179],[224081.13599843677,6758406.8585934015],[224080.37310182123,6758408.63839363]]]]},"properties":{"pk":154,"id_way":69927637,"height":9.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223927.674386882,6757866.977169008],[223924.19562695522,6757859.174548507],[223918.48257571209,6757861.763672864],[223925.94702346832,6757878.0703636315],[223935.42471617387,6757873.716885296],[223936.42721756568,6757871.9839448845],[223927.674386882,6757866.977169008]]]]},"properties":{"pk":155,"id_way":69927639,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223985.2429716436,6757575.077977029],[223989.81437937802,6757583.875693664],[223999.98224499135,6757578.1142039895],[223995.09077614348,6757569.5500151655],[223985.2429716436,6757575.077977029]]]]},"properties":{"pk":156,"id_way":69927641,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224071.18880982324,6758006.084071192],[224078.39372202745,6758008.674360428],[224082.25544935637,6757998.1337361885],[224078.59260266848,6757996.806258586],[224077.70734465975,6757999.061813846],[224076.25457528498,6757998.544813691],[224074.97447771713,6758002.059011224],[224072.96120988642,6758001.340615194],[224071.18880982324,6758006.084071192]]]]},"properties":{"pk":157,"id_way":69927664,"height":6.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223964.481269146,6757758.938604178],[223969.2878498057,6757768.298949683],[223974.8481190397,6757764.743811935],[223973.31991815128,6757761.423449864],[223969.36895385585,6757755.584133701],[223964.481269146,6757758.938604178]]]]},"properties":{"pk":158,"id_way":69927696,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223742.94896012044,6758104.212532959],[223749.271430418,6758118.669931129],[223758.30045629866,6758114.696050234],[223755.94600833385,6758109.332965084],[223760.26548073388,6758106.892714468],[223754.87972381074,6758097.421961334],[223742.94896012044,6758104.212532959]]]]},"properties":{"pk":159,"id_way":69927720,"height":14.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223526.0598765082,6757497.403345598],[223522.91548563403,6757492.164276899],[223517.33790245163,6757495.55728761],[223520.41916880713,6757500.725250478],[223526.0598765082,6757497.403345598]]]]},"properties":{"pk":160,"id_way":69927724,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223998.27025419674,6757323.722316615],[224004.9396684935,6757333.012408022],[224018.50881923188,6757323.480308163],[223972.38422127505,6757257.861225349],[223969.7759836139,6757259.554567389],[223968.5071508316,6757257.77724035],[223956.7837947038,6757266.208928424],[223963.127970066,6757274.976025814],[223969.3255308187,6757270.409624787],[224003.81365254382,6757319.664107636],[223998.27025419674,6757323.722316615]]]]},"properties":{"pk":161,"id_way":69927726,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223659.87411611187,6758505.928164876],[223660.78928530894,6758496.28729461],[223651.54340305727,6758495.419245037],[223650.65751653496,6758505.057757037],[223659.87411611187,6758505.928164876]]]]},"properties":{"pk":162,"id_way":69927751,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223602.84070984364,6757933.266376143],[223602.39553264025,6757934.776461916],[223606.13655878988,6757935.873213108],[223606.55985738154,6757934.333827645],[223602.84070984364,6757933.266376143]]]]},"properties":{"pk":163,"id_way":69927754,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223579.24409991782,6757320.966358069],[223585.9290616932,6757316.237685648],[223584.18215149335,6757313.8265545415],[223583.69418201395,6757314.138249628],[223583.01038315025,6757312.945544365],[223588.2173381471,6757309.286299569],[223586.08935759717,6757306.320378942],[223574.66050885967,6757314.519397588],[223579.24409991782,6757320.966358069]]]]},"properties":{"pk":164,"id_way":69927781,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223946.19126613907,6758586.60902774],[223925.67099412208,6758581.199434953],[223923.60528751952,6758582.679609269],[223920.83261680705,6758602.604869323],[223943.3691284776,6758605.780098931],[223946.19126613907,6758586.60902774]]]]},"properties":{"pk":165,"id_way":69927799,"height":3.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223772.0523112583,6757938.92935316],[223770.29574255104,6757935.786850782],[223764.35910891902,6757939.146778304],[223766.1237594626,6757942.299477937],[223772.0523112583,6757938.92935316]]]]},"properties":{"pk":166,"id_way":69927802,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223742.3652935114,6757280.11853333],[223737.43005326905,6757273.473139295],[223730.32638925585,6757278.528785312],[223735.0892269192,6757285.240031902],[223742.3652935114,6757280.11853333]]]]},"properties":{"pk":167,"id_way":69927804,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223640.8906636395,6758152.399460426],[223642.09040922936,6758154.518226007],[223647.45578610132,6758151.428365314],[223646.22781275795,6758149.2365216],[223640.8906636395,6758152.399460426]]]]},"properties":{"pk":168,"id_way":69927835,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223849.12680042675,6758081.8870390225],[223840.49809651176,6758086.823328164],[223846.80003940748,6758098.037429806],[223855.46121313647,6758093.142384132],[223849.12680042675,6758081.8870390225]]]]},"properties":{"pk":169,"id_way":69927836,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224139.4441335577,6757482.342737762],[224132.99600659343,6757486.841430269],[224138.66780259254,6757494.860585696],[224145.0914477262,6757490.331269584],[224139.4441335577,6757482.342737762]]]]},"properties":{"pk":170,"id_way":69927844,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223911.55292800735,6758541.091459343],[223905.01974155346,6758565.094744636],[223928.70628833317,6758571.374946898],[223934.97967509838,6758547.293146041],[223911.55292800735,6758541.091459343]]]]},"properties":{"pk":171,"id_way":69927878,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224143.6853636175,6757876.083384972],[224154.03329243432,6757879.900521513],[224161.07850464908,6757859.876434857],[224155.97429946164,6757858.084277358],[224150.8514765162,6757872.208369196],[224145.81942774646,6757870.417987532],[224143.6853636175,6757876.083384972]]]]},"properties":{"pk":172,"id_way":69927883,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223833.71616545753,6757768.641725041],[223838.3103872466,6757776.772209761],[223846.11648978974,6757772.343735645],[223845.46504776386,6757770.881702441],[223853.2956649824,6757766.281284958],[223850.16473838722,6757759.265921595],[223833.71616545753,6757768.641725041]]]]},"properties":{"pk":173,"id_way":69927921,"height":13.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223643.96636872852,6758372.221770865],[223652.23578448847,6758374.211281733],[223653.74742535347,6758367.813949322],[223639.58163587988,6758364.239997017],[223639.03996900716,6758366.289515539],[223642.171929084,6758367.049591396],[223642.08431966644,6758367.4449302275],[223644.92484948153,6758368.074095782],[223643.96636872852,6758372.221770865]]]]},"properties":{"pk":174,"id_way":69928003,"height":7.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223570.81331133534,6757873.756786749],[223585.84424713394,6757858.223869089],[223576.409760426,6757849.059680616],[223566.82084321626,6757858.805160119],[223567.52891775343,6757861.473573138],[223570.85663138388,6757858.131519563],[223575.6996374639,6757863.025211068],[223574.17944671543,6757864.405093615],[223568.85628162484,6757866.43138925],[223570.81331133534,6757873.756786749]]]]},"properties":{"pk":175,"id_way":69928010,"height":13.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223995.9324838484,6758503.593811954],[224001.2115296358,6758504.026969165],[224001.4134034833,6758500.83322647],[223996.13310147004,6758500.475343517],[223995.9324838484,6758503.593811954]]]]},"properties":{"pk":176,"id_way":69928031,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223773.03488310907,6758433.1900144555],[223770.6898577057,6758432.327265761],[223771.0214900955,6758431.232214088],[223763.6212244574,6758428.674552522],[223762.5551523348,6758431.514447026],[223752.96942261216,6758428.209913496],[223749.82209452218,6758437.299510401],[223780.02077523657,6758448.232398046],[223786.92148756856,6758429.354400548],[223775.77475238036,6758425.410101831],[223773.03488310907,6758433.1900144555]]]]},"properties":{"pk":177,"id_way":69928059,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223723.65397646686,6757820.024156322],[223731.26114040878,6757815.006830538],[223730.18856650955,6757814.949315493],[223724.14131769558,6757809.168358179],[223718.318199869,6757813.027988419],[223723.38068853808,6757817.858820358],[223724.02463242324,6757819.047820873],[223723.65397646686,6757820.024156322]]]]},"properties":{"pk":178,"id_way":69928062,"height":13.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223785.4303135315,6757452.026883712],[223785.36731773635,6757451.915222694],[223734.45536491004,6757487.48714747],[223738.29668886817,6757493.011867828],[223782.05898770856,6757462.627894461],[223781.91035554322,6757462.272053508],[223783.80907557707,6757460.946157607],[223802.34936554558,6757487.573514417],[223807.75739853305,6757483.903166659],[223785.4303135315,6757452.026883712]]]]},"properties":{"pk":179,"id_way":69928064,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223497.0314971616,6757418.249825817],[223499.12341842306,6757428.57626308],[223477.6276256784,6757432.607729415],[223476.3435785151,6757426.545715419],[223470.9880411485,6757428.668978285],[223474.0912997215,6757443.540366279],[223507.15626758468,6757436.968528766],[223502.8325810823,6757415.967496412],[223497.0314971616,6757418.249825817]]]]},"properties":{"pk":180,"id_way":69928082,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223732.32399056046,6758180.652857324],[223723.1474773173,6758159.847926081],[223717.61138476935,6758162.279820529],[223726.84849144582,6758183.014876867],[223732.32399056046,6758180.652857324]]]]},"properties":{"pk":181,"id_way":69928098,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223893.65073111746,6758036.531230619],[223886.13710941977,6758023.064740787],[223880.25757354006,6758026.386676277],[223887.75065248107,6758039.77901965],[223893.65073111746,6758036.531230619]]]]},"properties":{"pk":182,"id_way":69928100,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224153.45582661606,6757472.539157451],[224159.0397863693,6757480.565452966],[224169.1959354263,6757473.453101767],[224166.79174734256,6757458.951861029],[224157.03621498495,6757460.601960119],[224158.49760407457,6757468.974008428],[224153.45582661606,6757472.539157451]]]]},"properties":{"pk":183,"id_way":69928109,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224092.3962600225,6757917.359391746],[224091.0573723335,6757916.9011815535],[224094.5704027715,6757907.508915146],[224085.73387814336,6757904.271090849],[224078.62921426567,6757923.622245688],[224084.30148404348,6757925.667126538],[224084.5707229631,6757924.910741777],[224087.67334631932,6757925.987420129],[224090.11678534074,6757919.395470657],[224091.36229794315,6757919.774505637],[224091.93784876727,6757919.5702497065],[224092.61683990504,6757917.76024455],[224092.3962600225,6757917.359391746]]]]},"properties":{"pk":184,"id_way":69928163,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223878.0291121981,6757789.140017295],[223886.35676704042,6757785.096213562],[223883.93728930617,6757779.7169218],[223888.7113723496,6757777.481032175],[223886.11107603257,6757771.64693802],[223872.77594475824,6757777.506434212],[223878.0291121981,6757789.140017295]]]]},"properties":{"pk":185,"id_way":69928209,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223632.82683908395,6757345.358948752],[223620.775019381,6757353.832517993],[223626.62190696932,6757361.893936695],[223638.61597418453,6757353.348046781],[223632.82683908395,6757345.358948752]]]]},"properties":{"pk":186,"id_way":69928211,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223668.73093313695,6757974.730725301],[223681.31390154047,6757966.992589106],[223671.99513946334,6757953.247365819],[223662.37280366544,6757959.684590176],[223661.73413213142,6757960.63456595],[223661.4797238132,6757961.441235511],[223661.47755369896,6757962.316901896],[223661.67343640138,6757963.120875517],[223668.73093313695,6757974.730725301]]]]},"properties":{"pk":187,"id_way":69928233,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223995.1314132968,6757511.978410132],[223985.24615705205,6757518.8619389245],[223996.58175837755,6757535.235592695],[223990.47480633482,6757539.48450879],[224001.08192668023,6757554.559133458],[224024.3555433148,6757541.429504932],[224007.793579085,6757518.0332586225],[224002.06708766436,6757521.975256734],[223995.1314132968,6757511.978410132]]]]},"properties":{"pk":188,"id_way":69928236,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223833.51885911278,6758196.012635992],[223832.94952399633,6758193.29070607],[223828.03422844794,6758195.954749163],[223828.60690656686,6758198.633615413],[223833.51885911278,6758196.012635992]]]]},"properties":{"pk":189,"id_way":69928256,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224031.4745394073,6758019.373796595],[224041.9723351313,6757990.350447839],[224031.66099605005,6757986.728008062],[224020.88943405886,6758015.859208324],[224031.4745394073,6758019.373796595]]]]},"properties":{"pk":190,"id_way":69928257,"height":13.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224280.9124801747,6757682.69185631],[224280.99235999552,6757683.176647997],[224308.51712062015,6757678.134464477],[224305.12750281362,6757658.532683947],[224278.51707529314,6757663.428913367],[224277.76200649943,6757664.507514265],[224280.8323944657,6757682.317443134],[224281.02447687404,6757682.703937601],[224280.9124801747,6757682.69185631]]]]},"properties":{"pk":191,"id_way":69928262,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224028.70688844795,6757924.118647777],[224037.13165129276,6757927.26627482],[224040.60463318293,6757917.983338476],[224032.12395758618,6757914.872900313],[224028.70688844795,6757924.118647777]]]]},"properties":{"pk":192,"id_way":69928282,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223789.38149749942,6758385.054188866],[223791.54898224122,6758379.043266558],[223786.74977055908,6758377.334930628],[223788.688354543,6758372.078507477],[223785.5610874609,6758370.730272817],[223781.28336933767,6758382.102729987],[223789.38149749942,6758385.054188866]]]]},"properties":{"pk":193,"id_way":69928304,"height":6.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223792.14031395374,6757764.637575437],[223801.51291166607,6757759.229768432],[223798.5719390514,6757754.1418705685],[223789.23275565848,6757759.514454966],[223792.14031395374,6757764.637575437]]]]},"properties":{"pk":194,"id_way":69928307,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223944.23253953573,6758090.83602252],[223961.6772162887,6758097.278543553],[223964.56423731023,6758088.6694914615],[223947.3793574318,6758082.348042978],[223944.23253953573,6758090.83602252]]]]},"properties":{"pk":195,"id_way":69928336,"height":9.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223950.19510813846,6757999.862943822],[223953.87420190827,6758006.362507383],[223954.46614838374,6758004.86359794],[223951.2650125846,6757999.258833317],[223950.19510813846,6757999.862943822]]]]},"properties":{"pk":196,"id_way":69928337,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223986.64516325967,6758613.325408747],[223998.5403709475,6758616.50433205],[223998.89886137893,6758615.6624531625],[224003.07977055816,6758617.366409065],[224002.96838507496,6758617.62281032],[224004.04100470134,6758617.826956546],[224008.5725895796,6758607.08448884],[224006.31585029326,6758602.458575462],[223991.74304300747,6758598.644551291],[223989.4172859098,6758607.169009616],[223988.44218920032,6758606.924341173],[223986.64516325967,6758613.325408747]]]]},"properties":{"pk":197,"id_way":69928405,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223681.89846821973,6757874.739430305],[223676.28811292004,6757866.837260667],[223664.76582965496,6757874.867542178],[223670.4346476043,6757882.852671674],[223681.89846821973,6757874.739430305]]]]},"properties":{"pk":198,"id_way":69928412,"height":15.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223605.47328428808,6757535.572714027],[223612.9600501479,6757530.255820193],[223609.53021631032,6757525.432470975],[223605.5543358601,6757528.227562028],[223603.01840920787,6757524.739665211],[223607.0202373698,6757521.862961635],[223601.46817973474,6757513.9562965],[223594.06961315183,6757519.16724245],[223605.47328428808,6757535.572714027]]]]},"properties":{"pk":199,"id_way":69928457,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223731.52980967998,6758480.915440564],[223747.76343619204,6758481.069222033],[223748.03428737554,6758475.338203874],[223731.5700098966,6758475.115206055],[223731.52980967998,6758480.915440564]]]]},"properties":{"pk":200,"id_way":69928476,"height":7.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223938.18260237187,6757993.643071424],[223943.48348072605,6758003.233909661],[223949.92142747788,6757999.78521388],[223944.44214090274,6757990.078979771],[223938.18260237187,6757993.643071424]]]]},"properties":{"pk":201,"id_way":69928479,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223584.36703438993,6758121.877368798],[223587.48433900697,6758127.518395223],[223590.063942986,6758126.078409826],[223586.88910093636,6758120.442807478],[223584.36703438993,6758121.877368798]]]]},"properties":{"pk":202,"id_way":69928504,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223919.19671270894,6758158.689396392],[223933.62973843783,6758164.026971356],[223936.06184218117,6758157.181175858],[223921.68717747676,6758151.93738527],[223919.19671270894,6758158.689396392]]]]},"properties":{"pk":203,"id_way":69928505,"height":9.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224070.93763542993,6757522.581605075],[224064.5218602898,6757527.110063532],[224070.22014601855,6757535.172150766],[224076.6092186097,6757530.678570258],[224070.93763542993,6757522.581605075]]]]},"properties":{"pk":204,"id_way":69928509,"height":9.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223968.1259575567,6758471.323251738],[223965.59397272978,6758478.834447513],[223970.2260938587,6758480.011499182],[223972.72251796367,6758472.428014683],[223968.1259575567,6758471.323251738]]]]},"properties":{"pk":205,"id_way":69928535,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223996.65026218083,6757949.888292271],[224016.6488665652,6757956.719810903],[224016.5560961261,6757957.074441716],[224016.88977281543,6757957.18330771],[224021.09927582304,6757945.62114703],[224010.94709864634,6757941.814239131],[224010.56656621318,6757942.589390507],[224010.2194340457,6757942.530381678],[224000.4531821209,6757939.539244499],[223996.65026218083,6757949.888292271]]]]},"properties":{"pk":206,"id_way":69928539,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223829.20753143958,6757796.902341971],[223834.6975406524,6757793.7796056485],[223830.63958361835,6757786.677431892],[223827.30886464886,6757788.664724443],[223828.72182462167,6757791.269799388],[223826.7093770146,6757792.490431098],[223829.20753143958,6757796.902341971]]]]},"properties":{"pk":207,"id_way":69928563,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223642.37081209497,6758377.714190145],[223640.03335549549,6758387.265272449],[223648.5973718964,6758389.374516803],[223650.87541300143,6758379.817295091],[223642.37081209497,6758377.714190145]]]]},"properties":{"pk":208,"id_way":69928586,"height":6.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224040.26539088105,6757616.483174655],[224045.72874072616,6757618.445061736],[224046.67511116812,6757615.710688991],[224041.2076627763,6757613.792087359],[224040.26539088105,6757616.483174655]]]]},"properties":{"pk":209,"id_way":69928589,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223632.82616050655,6758308.940577463],[223633.84480890684,6758311.130681292],[223635.43836278038,6758315.7500790525],[223644.90809907034,6758312.787912472],[223643.2175535817,6758306.307046796],[223641.61876310175,6758306.077318265],[223632.82616050655,6758308.940577463]]]]},"properties":{"pk":210,"id_way":69928617,"height":9.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223660.96645972403,6757809.452108112],[223655.29781482473,6757801.2288385015],[223643.09865475167,6757809.615612028],[223648.80452821727,6757817.8426794745],[223660.96645972403,6757809.452108112]]]]},"properties":{"pk":211,"id_way":69928620,"height":12.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224141.85404559484,6757644.4923585355],[224141.70500493623,6757648.190660834],[224141.31072656738,6757651.986017731],[224140.69740788554,6757655.640662823],[224151.21715127336,6757657.373339057],[224151.98137901595,6757651.753281798],[224152.3722467998,6757645.988333471],[224152.3258867425,6757640.291411146],[224142.1684897086,6757640.662810083],[224142.27429981364,6757644.492421138],[224141.85404559484,6757644.4923585355]]]]},"properties":{"pk":212,"id_way":69928624,"height":15.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224099.49637136632,6757984.17378486],[224097.5730407852,6757989.386212005],[224099.93238141353,6757990.23847973],[224101.854713975,6757985.01573544],[224099.49637136632,6757984.17378486]]]]},"properties":{"pk":213,"id_way":69928645,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223749.3498566029,6758532.923864173],[223752.2287590233,6758525.102328926],[223751.97544487184,6758524.63405219],[223730.4319440086,6758522.754631145],[223729.62948410548,6758531.555920651],[223741.96786388135,6758532.00817437],[223749.3498566029,6758532.923864173]]]]},"properties":{"pk":214,"id_way":69928670,"height":9.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223595.5235713094,6758454.374139191],[223589.5654724745,6758453.754962611],[223588.44019272798,6758463.937526265],[223594.54321489,6758464.599556019],[223595.5235713094,6758454.374139191]]]]},"properties":{"pk":215,"id_way":69928672,"height":7.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223997.70755397677,6757823.655486581],[224003.81662120175,6757813.09272071],[223990.38258318903,6757805.387896197],[223984.42609451886,6757815.791936244],[223997.70755397677,6757823.655486581]]]]},"properties":{"pk":216,"id_way":69928673,"height":16.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223790.8914027589,6758120.236195057],[223791.95840508,6758122.702876615],[223796.78638992313,6758120.616552592],[223795.6885419464,6758118.119964179],[223790.8914027589,6758120.236195057]]]]},"properties":{"pk":217,"id_way":69928695,"height":3.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223985.5066471837,6758143.387826186],[223974.2761180331,6758140.217796656],[223970.08417338275,6758151.913821794],[223981.1377695073,6758155.547411042],[223985.5066471837,6758143.387826186]]]]},"properties":{"pk":218,"id_way":69928696,"height":13.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223531.75036153928,6757550.696557548],[223528.70710682034,6757534.812550302],[223518.65390041814,6757536.959333253],[223519.39971136735,6757542.52739883],[223519.89836153566,6757548.41647235],[223515.47185401153,6757549.469487225],[223517.7293591793,6757553.602517837],[223531.75036153928,6757550.696557548]]]]},"properties":{"pk":219,"id_way":69928698,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224039.3898295288,6757324.319031612],[224043.12317887813,6757329.783134949],[224044.9614144146,6757330.193163607],[224044.057587356,6757328.903937051],[224045.154501184,6757322.684434924],[224046.90283818165,6757322.9332041275],[224047.03160453602,6757322.156466555],[224046.22848173985,6757321.078116716],[224079.74481205075,6757297.291814989],[224082.69761014593,6757301.447163768],[224087.2789954437,6757298.334283775],[224083.4714329703,6757292.996973491],[224039.3898295288,6757324.319031612]]]]},"properties":{"pk":220,"id_way":69928700,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223773.1276353102,6757864.215807309],[223766.0869693416,6757864.166051514],[223758.87450857606,6757868.943004863],[223764.04709483337,6757876.676542934],[223776.1349099567,6757868.639164314],[223774.03301594933,6757865.12406947],[223773.1276353102,6757864.215807309]]]]},"properties":{"pk":221,"id_way":69928734,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224008.16827771792,6757709.1614858685],[223992.19369967104,6757716.634190134],[223995.0552694001,6757722.692145719],[224011.11457957892,6757715.268070249],[224008.16827771792,6757709.1614858685]]]]},"properties":{"pk":222,"id_way":69928777,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223587.55521151895,6757551.424351695],[223590.4844753969,6757556.0035897195],[223592.89155145836,6757554.4969216],[223589.99158678285,6757549.925438338],[223587.55521151895,6757551.424351695]]]]},"properties":{"pk":223,"id_way":69928779,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223909.07258595526,6758612.617147239],[223910.24468075568,6758604.213715977],[223883.36616500918,6758600.470577712],[223880.28684793785,6758608.525747273],[223909.07258595526,6758612.617147239]]]]},"properties":{"pk":224,"id_way":69928802,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223860.11321864135,6757898.376689355],[223870.8694620064,6757917.378713875],[223881.90103909306,6757911.099887155],[223871.22954540697,6757892.134748452],[223860.11321864135,6757898.376689355]]]]},"properties":{"pk":225,"id_way":69928806,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224134.10270727988,6757709.375244129],[224123.93893180424,6757705.63145623],[224119.21467033259,6757718.626192851],[224129.3822103092,6757722.325870748],[224134.10270727988,6757709.375244129]]]]},"properties":{"pk":226,"id_way":69928808,"height":15.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224051.02253153667,6758090.753018577],[224052.85838834246,6758085.84472379],[224046.80466865757,6758083.641633589],[224044.9105836205,6758088.824785285],[224051.02253153667,6758090.753018577]]]]},"properties":{"pk":227,"id_way":69928832,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223614.54642482946,6757358.170789543],[223620.3963929487,6757366.353259385],[223626.45916805044,6757362.010204007],[223620.61113483392,6757353.947205766],[223614.54642482946,6757358.170789543]]]]},"properties":{"pk":228,"id_way":69928834,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224204.81360707787,6757651.438186228],[224207.45589361686,6757651.069464356],[224206.80913030845,6757645.659232566],[224204.1372116396,6757646.020028266],[224204.81360707787,6757651.438186228]]]]},"properties":{"pk":229,"id_way":69928838,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223961.95826343776,6758489.53907924],[223966.50340846414,6758491.291793015],[223968.91664717803,6758483.982202523],[223964.40088113054,6758482.313205249],[223961.95826343776,6758489.53907924]]]]},"properties":{"pk":230,"id_way":69928865,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224034.09350804327,6757749.934094571],[224026.18834209457,6757746.786900851],[224024.70812231392,6757743.642074409],[224008.7059545206,6757751.226949057],[224012.01351245804,6757758.163053118],[224020.91200651595,6757754.008306132],[224030.7408994452,6757758.314973066],[224034.09350804327,6757749.934094571]]]]},"properties":{"pk":231,"id_way":69928904,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223903.6263669224,6758035.960825377],[223900.7182772631,6758030.671812588],[223895.55174949474,6758033.612427719],[223898.43729468295,6758038.892476517],[223903.6263669224,6758035.960825377]]]]},"properties":{"pk":232,"id_way":69928950,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223678.38629249757,6758544.297580743],[223676.26125323173,6758556.547463261],[223730.32469515986,6758565.586141739],[223732.38715276952,6758553.385011804],[223678.38629249757,6758544.297580743]]]]},"properties":{"pk":233,"id_way":69928951,"height":37.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223755.0082145256,6758339.669241287],[223752.6536549687,6758348.421935265],[223757.67757659947,6758349.810224141],[223763.31012182395,6758331.832337315],[223750.23948981182,6758326.949669902],[223746.55189062032,6758328.764311799],[223744.68123391748,6758335.611521591],[223751.37352311937,6758337.437545212],[223752.35095921086,6758336.576719404],[223754.72342408734,6758337.312132474],[223755.7239494338,6758338.999423039],[223755.0082145256,6758339.669241287]]]]},"properties":{"pk":234,"id_way":69928975,"height":13.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223854.83097118002,6757832.3895839285],[223858.25830548778,6757837.017925413],[223865.1048560494,6757832.917751661],[223865.81811398774,6757834.029564288],[223869.81776481753,6757831.571302778],[223865.30061429212,6757825.411166972],[223854.83097118002,6757832.3895839285]]]]},"properties":{"pk":235,"id_way":69928978,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223792.23789133335,6757831.428102986],[223779.30562301708,6757838.489383002],[223782.36216343218,6757843.704583054],[223795.67100948756,6757836.916041312],[223792.23789133335,6757831.428102986]]]]},"properties":{"pk":236,"id_way":69929024,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223861.2806679851,6757605.478374944],[223868.57061172908,6757615.752388196],[223884.42153072133,6757604.56299772],[223877.23974719542,6757594.281961643],[223861.2806679851,6757605.478374944]]]]},"properties":{"pk":237,"id_way":69929026,"height":13.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223807.83980884185,6758158.626973371],[223809.02866140165,6758161.251094382],[223813.8886000935,6758159.053111565],[223812.75584513182,6758156.425015845],[223807.83980884185,6758158.626973371]]]]},"properties":{"pk":238,"id_way":69929047,"height":3.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223615.9923960791,6757294.491091524],[223612.7730771119,6757289.864908201],[223608.51691583,6757292.935590793],[223611.73749123566,6757297.486462856],[223615.9923960791,6757294.491091524]]]]},"properties":{"pk":239,"id_way":69929050,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223959.9647992214,6758408.54065835],[223968.5085356697,6758406.390481829],[223965.8802151464,6758395.954763376],[223957.336463464,6758398.104943731],[223959.9647992214,6758408.54065835]]]]},"properties":{"pk":240,"id_way":69929070,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224146.85383261376,6757784.681551077],[224156.3123883194,6757788.380079564],[224157.8203496102,6757784.384544694],[224148.12844317468,6757780.848960747],[224146.85383261376,6757784.681551077]]]]},"properties":{"pk":241,"id_way":69929075,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223662.1866428096,6757763.034333027],[223653.97713880445,6757751.175173025],[223639.0808712642,6757761.46317003],[223647.17158937626,6757773.320708733],[223662.1866428096,6757763.034333027]]]]},"properties":{"pk":242,"id_way":69929105,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223735.2400577761,6757958.688028527],[223731.88901128824,6757952.654246547],[223709.47362592508,6757965.226530184],[223712.77417032787,6757971.186878935],[223735.2400577761,6757958.688028527]]]]},"properties":{"pk":243,"id_way":69929130,"height":10.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223960.61143092165,6757649.552176872],[223970.50623720876,6757644.918689052],[223966.17640711096,6757636.162243919],[223956.22492979522,6757640.840617894],[223960.61143092165,6757649.552176872]]]]},"properties":{"pk":244,"id_way":69929135,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223902.8507278766,6758165.02252062],[223887.95089950762,6758159.566560781],[223887.78978366472,6758160.038288296],[223871.65520326365,6758163.753340723],[223873.37442475275,6758171.340990969],[223882.75762555495,6758169.155998857],[223899.10895865844,6758175.174416129],[223902.8507278766,6758165.02252062]]]]},"properties":{"pk":245,"id_way":69929167,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224058.71278419215,6758498.148058033],[224060.96545703543,6758466.420588321],[224051.42721626934,6758465.7490839455],[224048.46066131076,6758504.201815497],[224078.455866105,6758519.317349886],[224083.11516991374,6758510.3834483065],[224058.71278419215,6758498.148058033]]]]},"properties":{"pk":246,"id_way":69929168,"height":15.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223840.88525441932,6757865.844410531],[223829.13250727256,6757849.35456432],[223823.22153983868,6757853.300999664],[223827.73856662065,6757859.616367562],[223829.42984896616,6757858.398432547],[223836.6689290837,6757868.607668186],[223840.88525441932,6757865.844410531]]]]},"properties":{"pk":247,"id_way":69929170,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224013.6553012994,6757556.06348478],[224019.7513701483,6757566.959065885],[224025.74463013958,6757563.5508144945],[224019.61429125955,6757552.690776455],[224013.6553012994,6757556.06348478]]]]},"properties":{"pk":248,"id_way":69929172,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224070.17106561837,6757999.210201786],[224067.079221402,6757998.125412898],[224064.9766201124,6758003.821205875],[224068.07228060623,6758004.9479103545],[224070.17106561837,6757999.210201786]]]]},"properties":{"pk":249,"id_way":69929195,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223975.33315034807,6757861.331993656],[223978.329937947,6757855.628963518],[223965.58070616593,6757848.278381226],[223962.2630650243,6757854.139371605],[223975.33315034807,6757861.331993656]]]]},"properties":{"pk":250,"id_way":69929218,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223888.12205471948,6757625.8663457045],[223890.39039029725,6757624.2480092095],[223886.93932866567,6757619.348989197],[223884.6709917422,6757620.967327072],[223888.12205471948,6757625.8663457045]]]]},"properties":{"pk":251,"id_way":69929220,"height":3.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223965.58770717547,6758137.940767977],[223969.85721750418,6758139.216083732],[223971.61004059744,6758134.203654813],[223972.2634930547,6758134.395987674],[223974.31834096168,6758128.313602879],[223967.0783871971,6758125.86936338],[223962.24978740548,6758142.933235917],[223964.24353729517,6758143.543873275],[223965.58770717547,6758137.940767977]]]]},"properties":{"pk":252,"id_way":69929242,"height":11.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223739.38244782944,6758030.626742126],[223736.7470515616,6758025.93080162],[223728.15035431646,6758030.798861443],[223735.60198594283,6758044.226725257],[223744.29309874293,6758039.320152648],[223739.38244782944,6758030.626742126]]]]},"properties":{"pk":253,"id_way":69929243,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223533.92268097927,6757461.9346326925],[223544.5011033623,6757478.814304996],[223549.76118583902,6757475.495354361],[223539.1219846693,6757458.697111542],[223533.92268097927,6757461.9346326925]]]]},"properties":{"pk":254,"id_way":69929245,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223547.54095555804,6757918.590676804],[223552.4809851799,6757915.7564358525],[223547.83464392865,6757907.920004727],[223538.91112270823,6757905.181767529],[223535.98634140292,6757915.172620894],[223547.54095555804,6757918.590676804]]]]},"properties":{"pk":255,"id_way":69929272,"height":13.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223574.54490023525,6757314.356192086],[223581.7398617063,6757309.195593532],[223579.93514302993,6757306.498134275],[223580.4398136782,6757306.145293781],[223579.39714829533,6757304.605827742],[223578.77752850312,6757305.000187817],[223576.24048878645,6757301.486034695],[223569.04865095296,6757306.568843534],[223574.54490023525,6757314.356192086]]]]},"properties":{"pk":256,"id_way":69929308,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223887.64830309225,6758589.671837924],[223898.08187918382,6758592.484693557],[223902.80043852318,6758575.148961475],[223892.42950151916,6758572.374986366],[223887.64830309225,6758589.671837924]]]]},"properties":{"pk":257,"id_way":69929334,"height":8.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223890.2784131901,6757270.111403797],[223879.86403886325,6757277.43660089],[223888.98955511843,6757290.32667121],[223910.7972186285,6757275.002050087],[223901.6960698484,6757261.955623562],[223899.19447714317,6757263.769773511],[223902.8263847257,6757268.984146847],[223892.34374325562,6757276.385213129],[223891.047141581,6757274.609139295],[223892.50716385114,6757273.385994531],[223890.2784131901,6757270.111403797]]]]},"properties":{"pk":258,"id_way":69929349,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223839.09049882204,6758110.931330656],[223820.05967648956,6758121.65785253],[223823.47213159958,6758127.702430058],[223842.94593205146,6758117.757537348],[223839.09049882204,6758110.931330656]]]]},"properties":{"pk":259,"id_way":69929379,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223640.97654178605,6758139.972226604],[223635.60823108093,6758143.03009243],[223636.805266161,6758145.191964146],[223642.20846677333,6758142.131906598],[223640.97654178605,6758139.972226604]]]]},"properties":{"pk":260,"id_way":69929380,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224040.33639019428,6757594.247115461],[224045.4093488997,6757591.4787018],[224044.02696563464,6757589.041656342],[224038.9902016639,6757591.818278932],[224040.33639019428,6757594.247115461]]]]},"properties":{"pk":261,"id_way":69929384,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224061.50736371937,6757970.352621349],[224059.04894663778,6757977.033745284],[224061.66947957978,6757977.955888079],[224064.16081972487,6757971.314467321],[224061.50736371937,6757970.352621349]]]]},"properties":{"pk":262,"id_way":69929413,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223827.0956975974,6757757.245569047],[223844.49860771812,6757747.312005946],[223844.56754380016,6757747.007410294],[223839.95742968403,6757736.43782839],[223825.54651031538,6757742.808713537],[223826.81102768268,6757747.03584851],[223822.68013223488,6757749.467325389],[223827.0956975974,6757757.245569047]]]]},"properties":{"pk":263,"id_way":69929457,"height":10.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223694.45498604112,6757302.1589862425],[223699.77619875365,6757309.737911456],[223707.85582807753,6757304.027081385],[223702.5320044684,6757296.514255243],[223694.45498604112,6757302.1589862425]]]]},"properties":{"pk":264,"id_way":69929462,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223592.25971009486,6758362.720577718],[223592.7721063347,6758359.718440641],[223587.04767054663,6758358.758375562],[223586.50956315585,6758361.795058808],[223592.25971009486,6758362.720577718]]]]},"properties":{"pk":265,"id_way":69929521,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223560.29985255786,6757884.103860432],[223565.31861093367,6757885.555568723],[223566.54774649945,6757883.956008495],[223562.309470883,6757880.879711721],[223560.29985255786,6757884.103860432]]]]},"properties":{"pk":266,"id_way":69929524,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223746.07086169263,6758430.158042692],[223744.28734769032,6758435.316141],[223749.6339244789,6758437.231699385],[223752.92641636173,6758427.752287003],[223747.58510825006,6758425.870101472],[223746.07086169263,6758430.158042692]]]]},"properties":{"pk":267,"id_way":69929570,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223621.973437216,6757836.2732244795],[223634.76461642372,6757827.481378224],[223629.0891215988,6757819.263140116],[223616.27142361365,6757828.090153687],[223621.973437216,6757836.2732244795]]]]},"properties":{"pk":268,"id_way":69929573,"height":15.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223770.8482699665,6757428.131078912],[223771.54184407977,6757426.825027807],[223768.92228363303,6757425.428192212],[223763.67777711668,6757418.088414159],[223764.3695790761,6757416.71211402],[223755.24184221006,6757412.821648321],[223754.22280158693,6757412.743965308],[223753.7225520324,6757412.889792199],[223752.8430072181,6757413.727255585],[223752.61615466906,6757414.889430087],[223752.98427622623,6757415.874061084],[223754.69288270344,6757418.280685048],[223749.8154932618,6757421.7419756185],[223747.45016551277,6757418.422326589],[223739.398885649,6757424.218717825],[223740.61114989672,6757425.915521252],[223734.12979519158,6757430.567094981],[223732.8621705297,6757428.741058784],[223724.78250955365,6757434.539204732],[223726.08655994746,6757436.351097591],[223722.85287014212,6757438.674665903],[223724.0660492498,6757440.382620546],[223722.31047445364,6757441.639039473],[223727.53807309462,6757448.992204278],[223739.7716524704,6757440.24922821],[223739.0936479848,6757439.300885452],[223751.53077078582,6757430.3902743105],[223752.20996465543,6757431.350344151],[223756.3347074572,6757428.431391397],[223758.18797091025,6757431.03814321],[223757.06046287122,6757431.875863859],[223763.64737489834,6757441.081242579],[223764.65456215956,6757440.330928678],[223768.2350381014,6757445.36143598],[223776.51735411788,6757439.566850992],[223775.33093431877,6757437.934995809],[223777.0636078786,6757434.694967733],[223774.6507852538,6757433.426446163],[223770.8482699665,6757428.131078912]]]]},"properties":{"pk":269,"id_way":69929575,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223695.2017438122,6758215.413673774],[223695.4893909305,6758214.583359923],[223690.76401834673,6758212.862570337],[223690.4750042811,6758213.62005144],[223695.2017438122,6758215.413673774]]]]},"properties":{"pk":270,"id_way":69929595,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223882.93007255174,6758037.44499448],[223885.41709553325,6758036.037831471],[223880.08351588293,6758026.485191687],[223869.82715669833,6758032.3002978135],[223875.15713216862,6758041.809237034],[223882.93007255174,6758037.44499448]]]]},"properties":{"pk":271,"id_way":69929596,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224108.17562734455,6757474.977476219],[224111.28033835356,6757479.402665424],[224113.63518312675,6757477.742959716],[224110.5376126517,6757473.317097149],[224108.17562734455,6757474.977476219]]]]},"properties":{"pk":272,"id_way":69929600,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224060.67487989087,6757896.229986555],[224063.39783391744,6757888.912506528],[224058.20153396597,6757886.997730491],[224055.53583773383,6757894.386222284],[224060.67487989087,6757896.229986555]]]]},"properties":{"pk":273,"id_way":69929624,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223559.14319593515,6757604.791814619],[223587.0536572393,6757585.094304881],[223583.71627000332,6757580.386991121],[223555.88455673796,6757600.221987406],[223559.14319593515,6757604.791814619]]]]},"properties":{"pk":274,"id_way":69929671,"height":3.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223915.6684090516,6758639.28203459],[223949.6030245315,6758643.989668673],[223950.04390900675,6758640.958018216],[223952.27919062568,6758632.496556758],[223917.32295788196,6758627.640167909],[223915.6684090516,6758639.28203459]]]]},"properties":{"pk":275,"id_way":69929710,"height":18.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223895.75472860076,6757941.52034509],[223901.713925357,6757938.158378369],[223891.72746136194,6757920.49834635],[223885.7338008002,6757923.895969746],[223895.75472860076,6757941.52034509]]]]},"properties":{"pk":276,"id_way":69929715,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224051.4211317142,6757602.2230562465],[224045.00431648866,6757602.708536112],[224044.1891453331,6757605.11938143],[224049.71347077054,6757607.077747462],[224051.4211317142,6757602.2230562465]]]]},"properties":{"pk":277,"id_way":69929719,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223826.15397069772,6758187.101559023],[223826.7264301025,6758189.857400828],[223831.69806615854,6758187.241806503],[223831.12832368608,6758184.517934218],[223826.15397069772,6758187.101559023]]]]},"properties":{"pk":278,"id_way":69929759,"height":3.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224010.46271593837,6758032.224098713],[224008.7379844799,6758037.75810264],[224023.1966804805,6758042.19237806],[224024.97369856483,6758037.279093018],[224010.46271593837,6758032.224098713]]]]},"properties":{"pk":279,"id_way":69929761,"height":7.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224225.437910525,6757648.736265389],[224224.76172587456,6757643.31964006],[224222.0890836739,6757643.690951347],[224222.70355808898,6757649.060721917],[224225.437910525,6757648.736265389]]]]},"properties":{"pk":280,"id_way":69929767,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224011.8113423003,6758494.861490839],[224011.24375991756,6758503.583103999],[224020.75324732816,6758504.267731083],[224021.4062576351,6758495.418031572],[224011.8113423003,6758494.861490839]]]]},"properties":{"pk":281,"id_way":69929800,"height":7.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223795.6973443501,6758398.5548411785],[223769.8025720804,6758389.064338468],[223766.83864509745,6758397.525087395],[223794.78432621347,6758407.736453389],[223797.03697174112,6758401.607450296],[223797.07043698756,6758400.578692358],[223796.84610077765,6758399.857795205],[223796.29512852058,6758399.012903344],[223795.6973443501,6758398.5548411785]]]]},"properties":{"pk":282,"id_way":69929879,"height":13.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223784.21019973693,6757807.817083897],[223790.40996693258,6757818.983839797],[223794.38321416182,6757816.719292751],[223783.5935505684,6757797.240727656],[223779.58354638593,6757799.508716676],[223784.21019973693,6757807.817083897]]]]},"properties":{"pk":283,"id_way":69929886,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223948.0920030722,6758042.430563962],[223934.91752648304,6758038.628016529],[223933.46989894003,6758042.918808327],[223936.57441709505,6758045.684709873],[223945.66942847185,6758049.057966057],[223948.0920030722,6758042.430563962]]]]},"properties":{"pk":284,"id_way":69929936,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223713.6169155691,6758368.654908963],[223708.68525543265,6758382.237744014],[223717.9000125217,6758384.956332088],[223721.7741540989,6758371.605029857],[223713.6169155691,6758368.654908963]]]]},"properties":{"pk":285,"id_way":69929939,"height":9.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223703.80170914155,6758346.630078577],[223701.39403000212,6758353.197004881],[223707.89199735486,6758355.586405955],[223710.2970695951,6758348.987190701],[223703.80170914155,6758346.630078577]]]]},"properties":{"pk":286,"id_way":69929985,"height":10.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224038.4333155419,6758588.906208716],[224028.79781203347,6758584.860065579],[224025.57507954448,6758592.488310108],[224035.2990064151,6758596.53805608],[224038.4333155419,6758588.906208716]]]]},"properties":{"pk":287,"id_way":69929987,"height":6.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223748.25493331737,6757507.681035405],[223742.22863704705,6757499.032015095],[223719.8705680098,6757514.426094755],[223714.15439670163,6757505.919432457],[223718.56882284128,6757502.764901898],[223716.8586564448,6757500.19601881],[223718.48941709666,6757498.98331953],[223709.74533849562,6757486.011482216],[223708.17899811006,6757487.239028527],[223705.96270372928,6757484.2250177385],[223693.93471212147,6757492.543113879],[223695.99900224514,6757495.505381969],[223694.58058987334,6757496.567761237],[223703.38200126425,6757509.376321189],[223704.9261376093,6757508.358598878],[223706.6693178051,6757511.048660104],[223708.68603959653,6757509.705606811],[223714.52217032772,6757518.179703088],[223706.11362024394,6757523.91786968],[223679.07266309168,6757485.54459809],[223694.28679406494,6757475.074957672],[223683.94404306897,6757460.166890939],[223655.99873053748,6757479.711025904],[223673.3339858422,6757504.499434213],[223682.0825671539,6757498.319733423],[223687.75114973114,6757506.473151272],[223679.0065370802,6757512.696861235],[223707.4996316783,6757553.505492765],[223716.233171898,6757547.317859333],[223708.14202788912,6757535.575050824],[223739.4432961223,6757513.970288974],[223748.25493331737,6757507.681035405]]]]},"properties":{"pk":288,"id_way":69930033,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223994.01232038083,6757986.35121792],[223984.52691210114,6757982.919004891],[223982.27169782203,6757989.049875676],[223991.8500248808,6757992.550612699],[223994.01232038083,6757986.35121792]]]]},"properties":{"pk":289,"id_way":69930073,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223913.08985383826,6758228.898292394],[223920.36782511548,6758243.440144672],[223938.25789064352,6758249.941038447],[223941.01546897978,6758242.399409596],[223927.56475449388,6758237.582368181],[223926.22851013133,6758241.322810404],[223922.9877279747,6758240.212859411],[223920.94766765894,6758235.964963219],[223931.73652675218,6758230.691518102],[223927.3442093417,6758221.825196219],[223913.08985383826,6758228.898292394]]]]},"properties":{"pk":290,"id_way":69930111,"height":10.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223592.60802357196,6758117.232831649],[223595.7831616099,6758122.868969953],[223598.15401650773,6758121.546221055],[223594.92341932395,6758115.946802054],[223592.60802357196,6758117.232831649]]]]},"properties":{"pk":291,"id_way":69930113,"height":3.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224094.97114837196,6757513.6974698175],[224083.00552113308,6757522.1297596125],[224085.01279100138,6757524.970986061],[224084.77263121487,6757525.169202014],[224088.294393185,6757530.235452268],[224100.5852916236,6757521.566079343],[224094.97114837196,6757513.6974698175]]]]},"properties":{"pk":292,"id_way":69930120,"height":13.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223948.96329415555,6758466.578521934],[223937.76612831958,6758463.800794674],[223935.63247750144,6758472.33274255],[223946.8626920497,6758475.151686292],[223948.96329415555,6758466.578521934]]]]},"properties":{"pk":293,"id_way":69930154,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224045.63567879391,6757930.432449411],[224052.010992283,6757932.787326679],[224055.1273883051,6757924.491700121],[224048.748359337,6757922.180462935],[224045.63567879391,6757930.432449411]]]]},"properties":{"pk":294,"id_way":69930158,"height":11.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223915.87975381064,6757742.4516932275],[223928.3163657162,6757737.692068685],[223927.05140786848,6757734.406092887],[223927.22829789238,6757734.337505011],[223925.02808440416,6757729.44563942],[223920.20610594112,6757720.253125508],[223909.43733517895,6757725.676939981],[223915.87975381064,6757742.4516932275]]]]},"properties":{"pk":295,"id_way":69930197,"height":13.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223824.7208748122,6757943.4937791545],[223817.68238033328,6757930.979290412],[223798.40817161038,6757941.798677008],[223796.61213805992,6757938.59691812],[223790.7439554706,6757941.810542235],[223799.69964204577,6757957.69084237],[223824.7208748122,6757943.4937791545]]]]},"properties":{"pk":296,"id_way":69930253,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223626.5899989629,6758435.748451005],[223619.4438019685,6758435.164510898],[223619.41381070297,6758435.356458674],[223616.54429122197,6758435.121013575],[223615.68822663862,6758444.000973811],[223625.7035908755,6758444.995214129],[223626.5899989629,6758435.748451005]]]]},"properties":{"pk":297,"id_way":69930255,"height":6.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224046.74091194678,6757615.521822747],[224047.62838349745,6757612.991172767],[224042.16504931124,6757611.029290999],[224041.27344287233,6757613.603213857],[224046.74091194678,6757615.521822747]]]]},"properties":{"pk":298,"id_way":69930260,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223619.94443312235,6758291.896151459],[223612.43509465747,6758286.379040642],[223608.10459536433,6758284.678391787],[223604.47853321224,6758284.345458839],[223604.45325114575,6758283.460481477],[223600.058283824,6758282.071303284],[223600.15324229604,6758281.418097702],[223599.76365276283,6758281.245701109],[223599.02665737056,6758283.316583654],[223598.05620391088,6758293.150034197],[223596.7570437075,6758301.543602704],[223604.04359367295,6758302.74622662],[223605.62880131614,6758293.833286516],[223609.42752986428,6758294.040396688],[223612.51371464756,6758294.439612898],[223615.0136424483,6758295.088924652],[223617.0521911647,6758295.922973186],[223619.94443312235,6758291.896151459]]]]},"properties":{"pk":299,"id_way":69930322,"height":10.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224137.37366529356,6758551.553479434],[224209.87792770346,6758586.048259051],[224213.80776216998,6758577.667982151],[224140.59078194384,6758542.810767133],[224136.3715720954,6758551.073135485],[224137.37366529356,6758551.553479434]]]]},"properties":{"pk":300,"id_way":69930326,"height":16.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223622.4730567266,6757790.58148556],[223626.22308984224,6757795.991530722],[223628.31124098922,6757794.572252424],[223627.51524738173,6757793.376702285],[223629.6170567903,6757791.959330668],[223627.51803672733,6757788.925377811],[223624.9669126643,6757790.658368798],[223624.11681375577,6757789.435141304],[223622.4730567266,6757790.58148556]]]]},"properties":{"pk":301,"id_way":69930332,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223967.40656746968,6757596.69176814],[223962.6318045531,6757587.264280433],[223946.03325439076,6757596.560848715],[223951.15805667473,6757605.812757471],[223967.40656746968,6757596.69176814]]]]},"properties":{"pk":302,"id_way":69930337,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224094.2297990503,6757982.258333302],[224092.30707626636,6757987.4821546925],[224094.6915523823,6757988.364217899],[224096.58978056555,6757983.110830008],[224094.2297990503,6757982.258333302]]]]},"properties":{"pk":303,"id_way":69930399,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223808.83589116207,6758513.026163875],[223831.54574508214,6758521.451370422],[223832.29133118913,6758519.356192428],[223839.56774062646,6758521.613088717],[223861.8774343281,6758527.991412113],[223862.77547099747,6758524.904996831],[223858.21697442912,6758523.478117405],[223861.6472495119,6758512.067249708],[223814.3075628496,6758498.202498688],[223808.83589116207,6758513.026163875]]]]},"properties":{"pk":304,"id_way":69930444,"height":12.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223990.55380766094,6757766.776131961],[223987.6342009761,6757760.63554655],[223981.3863559066,6757763.729816373],[223983.03101233434,6757767.252157923],[223980.46380806962,6757768.559524652],[223980.65495349665,6757769.487204559],[223981.60180741388,6757771.020468889],[223990.55380766094,6757766.776131961]]]]},"properties":{"pk":305,"id_way":69930451,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223608.9084183797,6758108.057177788],[223612.08789525635,6758113.7378662545],[223614.6678726497,6758112.297689689],[223611.4596204007,6758106.619710569],[223608.9084183797,6758108.057177788]]]]},"properties":{"pk":306,"id_way":69930502,"height":3.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223802.54334909836,6758082.768297154],[223797.26724964075,6758073.366729497],[223787.81037862564,6758078.73793688],[223793.19384962966,6758088.097996351],[223802.54334909836,6758082.768297154]]]]},"properties":{"pk":307,"id_way":69930503,"height":13.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223532.2540486585,6757520.83913379],[223530.23557466108,6757511.001372848],[223520.36634161382,6757513.033748272],[223522.37632496541,6757522.948703348],[223532.2540486585,6757520.83913379]]]]},"properties":{"pk":308,"id_way":69930508,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224025.48695575813,6757220.9536194075],[224017.52039605027,6757226.588318394],[224063.3239464676,6757291.962285917],[224071.3769424447,6757286.287098562],[224025.48695575813,6757220.9536194075]]]]},"properties":{"pk":309,"id_way":69930514,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223624.61105783834,6758538.756188034],[223628.64799673966,6758514.235674755],[223617.8681052755,6758512.468430654],[223613.851319852,6758536.986863006],[223624.61105783834,6758538.756188034]]]]},"properties":{"pk":310,"id_way":69930569,"height":21.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223644.9220202079,6757887.72982518],[223654.18941769353,6757881.179779714],[223653.21890616525,6757880.808903699],[223651.5975958195,6757880.688980309],[223650.8171939763,6757880.839055725],[223649.30800587434,6757881.575049656],[223648.41052800717,6757881.159735565],[223647.6265521111,6757881.307348847],[223646.90678629008,6757882.043892828],[223646.7989900052,6757882.408776204],[223646.89114163732,6757883.264231045],[223646.15243715153,6757884.038821241],[223645.59734361432,6757884.9254269805],[223645.068466754,6757886.36442936],[223644.9220202079,6757887.72982518]]]]},"properties":{"pk":311,"id_way":69930576,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223966.9625196483,6757717.316613687],[223963.10079760637,6757709.278129124],[223953.12316220402,6757714.143673052],[223957.39378780633,6757721.876194448],[223966.9625196483,6757717.316613687]]]]},"properties":{"pk":312,"id_way":69930634,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223883.43905675088,6758600.278798655],[223910.2726515177,6758604.0156811625],[223911.62322529117,6758594.571960571],[223898.1324072904,6758592.70543916],[223887.4112445888,6758589.818115617],[223883.43905675088,6758600.278798655]]]]},"properties":{"pk":313,"id_way":69930685,"height":3.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223769.943207128,6757949.150442165],[223771.58509706435,6757952.103436416],[223777.71874003758,6757948.738326116],[223775.90326364522,6757945.787824348],[223769.943207128,6757949.150442165]]]]},"properties":{"pk":314,"id_way":69930690,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224136.61633560018,6757670.900343572],[224128.82605155368,6757692.302900086],[224138.99759059722,6757696.046256147],[224141.69671422322,6757688.683890555],[224140.74823805454,6757688.292214587],[224144.63047937254,6757677.609413966],[224145.6009364403,6757677.998911137],[224146.81901698533,6757674.564845212],[224136.61633560018,6757670.900343572]]]]},"properties":{"pk":315,"id_way":69930694,"height":16.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223653.51860178262,6758160.363553483],[223657.93329823294,6758164.858543338],[223659.6254059806,6758163.253087416],[223655.24970881263,6758158.690970788],[223653.51860178262,6758160.363553483]]]]},"properties":{"pk":316,"id_way":69930744,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224059.0000596464,6758077.872429756],[224066.3205910598,6758080.5852248985],[224070.36530348114,6758069.329123147],[224063.120782382,6758066.730122551],[224059.0000596464,6758077.872429756]]]]},"properties":{"pk":317,"id_way":69930749,"height":6.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223611.5027479826,6757354.15492838],[223622.64210654082,6757346.211264661],[223616.50434918088,6757337.701158355],[223621.48395405436,6757334.076440149],[223618.853562997,6757330.248921404],[223596.92444190226,6757346.005180697],[223605.66716391785,6757358.335514203],[223611.5027479826,6757354.15492838]]]]},"properties":{"pk":318,"id_way":69930755,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224182.03462576916,6757667.520921669],[224173.22773344134,6757664.368294169],[224167.4005519511,6757680.284984635],[224176.15219211526,6757683.552019556],[224178.5874262757,6757676.870922021],[224179.5973775012,6757677.315855784],[224180.61230365172,6757674.593501291],[224179.594572173,6757674.199483303],[224182.03462576916,6757667.520921669]]]]},"properties":{"pk":319,"id_way":69930761,"height":12.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223942.44038357632,6758528.226995866],[223948.8266108656,6758531.507270265],[223954.18047842686,6758520.913378953],[223947.82036355688,6758517.674867514],[223942.44038357632,6758528.226995866]]]]},"properties":{"pk":320,"id_way":69930810,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224017.6387916827,6757855.739895803],[224020.03794715335,6757849.251575163],[224006.14276398168,6757844.081932912],[224003.71214412566,6757850.638825908],[224017.6387916827,6757855.739895803]]]]},"properties":{"pk":321,"id_way":69930871,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223667.25310631245,6758440.71258216],[223666.28174214653,6758449.434204166],[223677.6980081491,6758450.628128896],[223679.47721042656,6758441.895259899],[223667.25310631245,6758440.71258216]]]]},"properties":{"pk":322,"id_way":69930925,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223668.74604726364,6758058.840246963],[223684.6358732011,6758049.787748937],[223679.5718917692,6758040.947981912],[223650.5169470267,6758057.422764354],[223653.3415955239,6758062.509373294],[223654.5868043526,6758061.84075212],[223659.78243191622,6758070.893758139],[223670.342728122,6758064.88495074],[223669.87243607652,6758063.978443401],[223671.2012467714,6758063.159467477],[223668.74604726364,6758058.840246963]]]]},"properties":{"pk":323,"id_way":69930928,"height":10.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223685.93251068552,6758323.000566317],[223685.18488013942,6758322.803784884],[223685.4711538843,6758321.718883204],[223684.7150375067,6758320.241549684],[223683.56536586056,6758319.960491356],[223683.84265621856,6758318.849662883],[223684.98903431674,6758318.553617268],[223685.7673943104,6758318.686579273],[223686.73967899734,6758320.5526684215],[223693.4125859897,6758322.30661213],[223694.5140777143,6758318.200506379],[223694.05999188678,6758318.124925147],[223694.30396811577,6758317.487576106],[223677.22795800614,6758313.944717712],[223675.00193282557,6758323.235761662],[223685.22894704613,6758325.99794048],[223685.93251068552,6758323.000566317]]]]},"properties":{"pk":324,"id_way":69930989,"height":12.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223585.56447247753,6757896.6343610985],[223592.4725622863,6757892.640340863],[223587.93923741905,6757885.027518297],[223581.0895397981,6757889.016769894],[223585.56447247753,6757896.6343610985]]]]},"properties":{"pk":325,"id_way":69930995,"height":10.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223770.63388854585,6757846.892406512],[223768.22954446092,6757842.600832178],[223755.2926571302,6757850.104158354],[223757.3273775973,6757854.158921623],[223770.63388854585,6757846.892406512]]]]},"properties":{"pk":326,"id_way":69931118,"height":6.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223854.2755077522,6757626.705011634],[223858.2530426624,6757623.919339578],[223857.3822639572,6757622.802326319],[223853.45230688463,6757625.560971028],[223854.2755077522,6757626.705011634]]]]},"properties":{"pk":327,"id_way":69931125,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223964.41665470912,6758080.915200213],[223965.32310145127,6758078.430865907],[223967.957108264,6758078.864277433],[223969.67727108079,6758073.769932921],[223963.77404732656,6758072.591945298],[223952.6743201987,6758068.057309514],[223947.44886266044,6758082.1605087],[223956.72907960095,6758085.584858397],[223958.63105491115,6758080.370913303],[223962.4750938405,6758081.779973074],[223964.41665470912,6758080.915200213]]]]},"properties":{"pk":328,"id_way":69931178,"height":10.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223960.10069614972,6758003.493373016],[223959.60225143112,6758002.36957799],[223956.18117800495,6758000.960962375],[223955.8682911215,6758001.7955841],[223960.10069614972,6758003.493373016]]]]},"properties":{"pk":329,"id_way":69931182,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223602.38715446595,6757268.521526902],[223594.87309673365,6757273.873531149],[223599.8346841923,6757280.833666809],[223607.14538901905,6757275.4310962735],[223602.38715446595,6757268.521526902]]]]},"properties":{"pk":330,"id_way":69931186,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224412.98545845094,6757463.659806489],[224413.36313860523,6757464.433772505],[224414.11167009146,6757465.322432131],[224415.35198094393,6757466.059623459],[224416.793704895,6757466.367748361],[224418.50329167844,6757466.066604385],[224419.9471394088,6757465.07034676],[224420.62016242108,6757464.098661831],[224421.05885027442,6757462.715495783],[224421.0857473201,6757461.861498998],[224420.7135989646,6757460.435159696],[224419.90497888712,6757459.237146024],[224419.2128529615,6757458.661938865],[224418.4330812188,6757458.278526067],[224417.59949165228,6757458.041139419],[224416.43211288835,6757458.004151557],[224415.02369436467,6757458.422182487],[224414.0608200177,6757459.078218532],[224413.19592016816,6757460.231374091],[224412.79097811837,6757461.348488587],[224412.6986715192,6757462.203591253],[224412.98545845094,6757463.659806489]]]]},"properties":{"pk":331,"id_way":69931191,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223857.6122757323,6758380.268288473],[223853.5706733468,6758391.369713727],[223861.72912343423,6758394.394077703],[223863.90233738415,6758388.485026401],[223864.73309128854,6758388.719026942],[223866.6274551232,6758383.58040584],[223857.6122757323,6758380.268288473]]]]},"properties":{"pk":332,"id_way":69931234,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224076.7948151414,6757782.349863098],[224078.86760718073,6757776.5342751155],[224078.18381659978,6757776.298149454],[224078.39002264297,6757775.77937878],[224073.49414276544,6757774.05951494],[224073.31188340162,6757774.496907342],[224072.72845089156,6757774.300154421],[224070.58769930393,6757780.115615469],[224071.15203547914,6757780.351033898],[224070.92031410473,6757780.900501298],[224075.84664086692,6757782.701466582],[224076.05275935668,6757782.108590263],[224076.7948151414,6757782.349863098]]]]},"properties":{"pk":333,"id_way":69931239,"height":7.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223715.63122804687,6757748.829180519],[223712.7236371457,6757743.628523167],[223704.06590428934,6757748.445109943],[223707.1248092642,6757753.536675359],[223715.63122804687,6757748.829180519]]]]},"properties":{"pk":334,"id_way":69931301,"height":7.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223647.9800528307,6757328.294049131],[223652.37762598344,6757334.535948277],[223646.86253910026,6757338.670703272],[223651.02342236333,6757344.528908364],[223663.2568746721,6757335.774407235],[223654.63303686012,6757323.524114771],[223647.9800528307,6757328.294049131]]]]},"properties":{"pk":335,"id_way":69931306,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223728.42382655293,6757946.430749008],[223725.12742350373,6757940.514611575],[223702.63262367394,6757952.927120114],[223704.0079007071,6757955.364258602],[223715.05507034343,6757949.169848318],[223715.41976030017,6757948.782124576],[223715.30308444926,6757948.002773927],[223717.0806406322,6757946.971937531],[223717.83136067708,6757948.346857475],[223717.23422764902,6757948.661917885],[223718.41687998458,6757950.749414095],[223715.26837483517,6757952.487861477],[223715.7653127369,6757953.45461304],[223728.42382655293,6757946.430749008]]]]},"properties":{"pk":336,"id_way":69931361,"height":10.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223950.9100431653,6757630.251702166],[223959.00399909785,6757625.594265353],[223955.40878735445,6757618.48978714],[223947.3980897244,6757622.9988662405],[223950.9100431653,6757630.251702166]]]]},"properties":{"pk":337,"id_way":69931367,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223865.41379525056,6758196.6444511255],[223855.8376334377,6758198.750260893],[223859.28456560444,6758214.135644729],[223868.80690285726,6758212.0997918695],[223865.41379525056,6758196.6444511255]]]]},"properties":{"pk":338,"id_way":69931428,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224041.13197447232,6758516.577301856],[224045.0168489935,6758461.544525773],[224039.6519375394,6758458.900385423],[224035.55814740152,6758513.935801328],[224041.13197447232,6758516.577301856]]]]},"properties":{"pk":339,"id_way":69931430,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223883.7376140846,6757834.249423881],[223862.65505268343,6757843.715365274],[223868.24698676198,6757852.680312534],[223887.87461371865,6757843.481410127],[223883.7376140846,6757834.249423881]]]]},"properties":{"pk":340,"id_way":69931435,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223934.24873195784,6757554.512098016],[223940.18551909327,6757563.088290858],[223956.77120094482,6757551.462808845],[223950.83727868978,6757543.007468539],[223934.24873195784,6757554.512098016]]]]},"properties":{"pk":341,"id_way":69931444,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224058.97984353325,6757977.221449962],[224051.03844586873,6757998.78160212],[224059.31236446416,6758001.764647741],[224067.02681924755,6757980.12829929],[224058.97984353325,6757977.221449962]]]]},"properties":{"pk":342,"id_way":69931508,"height":9.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223957.44603182867,6757835.545835077],[223961.503125796,6757828.538274162],[223950.4252370859,6757822.116387491],[223946.5886821475,6757823.707365317],[223949.34141430102,6757830.981131123],[223957.44603182867,6757835.545835077]]]]},"properties":{"pk":343,"id_way":69931567,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223632.63585834028,6757269.254593437],[223639.22125094614,6757278.457227279],[223653.91849292323,6757267.975198617],[223647.91473681226,6757259.090484534],[223632.63585834028,6757269.254593437]]]]},"properties":{"pk":344,"id_way":69931569,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223960.01809180746,6758102.906345706],[223956.95341793308,6758112.109210475],[223966.3498339551,6758115.229548341],[223969.41016712322,6758106.059959855],[223960.01809180746,6758102.906345706]]]]},"properties":{"pk":345,"id_way":69931616,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223725.28807177022,6757855.506736221],[223715.5610395567,6757841.003427797],[223710.94436968287,6757844.052818848],[223710.51424468704,6757844.537110746],[223710.29699097402,6757844.982220397],[223710.2668793018,6757845.570638702],[223710.6944191537,6757846.721883187],[223719.75550301166,6757858.076646035],[223720.68819932922,6757858.266976506],[223721.55866899106,6757858.155314021],[223725.28807177022,6757855.506736221]]]]},"properties":{"pk":346,"id_way":69931711,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223567.0863653284,6757555.186760507],[223587.37923919703,6757551.297794871],[223595.0372020741,6757546.587973221],[223588.5671412673,6757536.207850951],[223580.35616992286,6757541.296622707],[223578.2141623,6757537.942916376],[223565.42407129172,6757540.650339446],[223565.9905101487,6757548.582728509],[223567.0863653284,6757555.186760507]]]]},"properties":{"pk":347,"id_way":69931807,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223871.4566746256,6757250.1156106265],[223864.17886298356,6757255.249527877],[223870.35678859573,6757263.942145587],[223877.7522037258,6757258.818361701],[223871.4566746256,6757250.1156106265]]]]},"properties":{"pk":348,"id_way":69931891,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223554.7338969855,6758136.495865852],[223544.73591112392,6758142.067203155],[223549.24488660906,6758150.070041334],[223559.20606825384,6758144.422677842],[223554.7338969855,6758136.495865852]]]]},"properties":{"pk":349,"id_way":69931930,"height":14.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223804.2500927033,6758137.337529236],[223808.95256987074,6758135.262500493],[223807.73996402105,6758132.473909345],[223803.03139474575,6758134.560074277],[223804.2500927033,6758137.337529236]]]]},"properties":{"pk":350,"id_way":69931931,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224042.45757915493,6757586.299383276],[224041.02329412635,6757583.777047656],[224035.97776496323,6757586.521573344],[224037.4110602792,6757589.033275465],[224042.45757915493,6757586.299383276]]]]},"properties":{"pk":351,"id_way":69931939,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224073.69669733522,6757963.947835134],[224093.80417177978,6757971.225865545],[224096.44846694023,6757963.8378925035],[224076.45690839036,6757956.439616697],[224073.69669733522,6757963.947835134]]]]},"properties":{"pk":352,"id_way":69931984,"height":10.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223915.95135573708,6757742.638436847],[223920.3002166077,6757753.999276602],[223932.7705492327,6757749.192866579],[223928.38849305603,6757737.878611224],[223915.95135573708,6757742.638436847]]]]},"properties":{"pk":353,"id_way":69932034,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223632.10581908046,6757291.51986412],[223628.79651905628,6757286.818678007],[223622.34556306154,6757291.274342896],[223625.8024893884,6757296.170155319],[223632.10581908046,6757291.51986412]]]]},"properties":{"pk":354,"id_way":69932039,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223587.9502297934,6758490.67945566],[223587.15399297792,6758499.285593988],[223597.94052451407,6758500.24192955],[223598.73329655136,6758491.592301088],[223587.9502297934,6758490.67945566]]]]},"properties":{"pk":355,"id_way":69932052,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223642.8572394802,6758342.696016832],[223635.53159303206,6758339.939920561],[223632.1750547207,6758349.233941382],[223639.5359218488,6758352.021872864],[223642.8572394802,6758342.696016832]]]]},"properties":{"pk":356,"id_way":69932133,"height":9.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223826.85946935133,6758562.508746833],[223826.79859759737,6758562.695508497],[223834.2831433896,6758564.68652983],[223832.99585201833,6758569.418102038],[223834.27350615157,6758569.783260013],[223832.33043682302,6758576.805082697],[223839.2436684188,6758578.664666446],[223844.31802207997,6758559.673145229],[223828.6792250868,6758555.507885404],[223826.85946935133,6758562.508746833]]]]},"properties":{"pk":357,"id_way":69932223,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223683.48185130203,6757820.504519284],[223677.84189439836,6757812.449938055],[223664.13220278226,6757822.0603594445],[223669.91980295832,6757830.126150903],[223683.48185130203,6757820.504519284]]]]},"properties":{"pk":358,"id_way":69932229,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223550.136094515,6757316.869269078],[223556.74151351774,6757311.521960921],[223550.4152080643,6757302.5801593475],[223541.25940002655,6757302.013048832],[223539.93950549408,6757310.30550545],[223545.65457656828,6757310.626656285],[223550.136094515,6757316.869269078]]]]},"properties":{"pk":359,"id_way":69932248,"height":16.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223694.48210772531,6758195.597179516],[223696.7420707156,6758196.168063433],[223702.74792754048,6758193.553099688],[223690.1563683182,6758164.908860002],[223682.5126308375,6758168.258639178],[223694.48210772531,6758195.597179516]]]]},"properties":{"pk":360,"id_way":69932259,"height":10.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223846.8980393801,6758098.211774929],[223850.8465445671,6758105.2345686285],[223859.47786699052,6758100.330856489],[223855.55944338295,6758093.316599113],[223846.8980393801,6758098.211774929]]]]},"properties":{"pk":361,"id_way":69932261,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224115.18311493754,6757427.510148893],[224102.30204951516,6757436.460551416],[224114.2705716975,6757453.261588444],[224117.74524627475,6757451.088794424],[224115.76805109106,6757448.20916695],[224115.29352665727,6757448.570512042],[224112.4009923475,6757444.367788684],[224121.83374760475,6757437.866750895],[224115.18311493754,6757427.510148893]]]]},"properties":{"pk":362,"id_way":69932268,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223795.12403825467,6757890.985356196],[223787.28603442106,6757877.004632826],[223772.07896456937,6757887.049444095],[223778.5509579622,6757896.816557326],[223782.76071058624,6757893.937477785],[223783.25776165404,6757892.022278387],[223784.56639236715,6757892.346411269],[223784.17035117,6757894.339823469],[223785.40036797308,6757896.436100307],[223795.12403825467,6757890.985356196]]]]},"properties":{"pk":363,"id_way":69932294,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224022.21548924057,6757700.164648006],[224020.60420452568,6757697.102702117],[224014.4656025896,6757700.274496096],[224015.9949812267,6757703.299101022],[224022.21548924057,6757700.164648006]]]]},"properties":{"pk":364,"id_way":69932317,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223601.83947443552,6757610.38291113],[223604.09556154342,6757608.795604905],[223604.30789239923,6757609.101767569],[223611.94634355028,6757603.716404587],[223611.74313938717,6757603.431859942],[223613.9338563152,6757601.883757396],[223605.0215176636,6757589.310885139],[223602.83096297068,6757590.858922785],[223588.08229206942,6757570.035344607],[223580.4428705776,6757575.42140157],[223598.38075468814,6757600.735806169],[223596.13322812016,6757602.321829081],[223601.83947443552,6757610.38291113]]]]},"properties":{"pk":365,"id_way":69932319,"height":30.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223919.00690727175,6758615.633260895],[223917.35069640362,6758627.442100691],[223952.33038064628,6758632.301747602],[223955.35009408378,6758620.8117393255],[223919.00690727175,6758615.633260895]]]]},"properties":{"pk":366,"id_way":69932354,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223908.94038012097,6757910.675281205],[223915.45487441125,6757922.285024313],[223921.2153470325,6757919.068476999],[223915.72972865865,6757906.805381176],[223908.94038012097,6757910.675281205]]]]},"properties":{"pk":367,"id_way":69932359,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224035.6634254063,6757598.096163801],[224037.06789187872,6757600.608545259],[224042.13791683098,6757597.860725742],[224040.75754897573,6757595.3899696255],[224035.6634254063,6757598.096163801]]]]},"properties":{"pk":368,"id_way":69932361,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223605.69323173788,6758370.214120896],[223603.29947770596,6758378.900912182],[223617.2806574385,6758382.906022356],[223618.42585886447,6758378.556556878],[223613.00622662265,6758377.087798807],[223613.62957375488,6758374.846595806],[223614.86903357774,6758375.125228699],[223615.41935313318,6758373.068278157],[223605.69323173788,6758370.214120896]]]]},"properties":{"pk":369,"id_way":69932389,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224027.216394696,6758126.742237059],[224024.44507796047,6758135.118474282],[224040.20133149106,6758140.2125792],[224042.91753538273,6758131.885004029],[224027.216394696,6758126.742237059]]]]},"properties":{"pk":370,"id_way":69932390,"height":18.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224216.34749308732,6757649.905834524],[224215.78724236693,6757644.48901011],[224213.01988493814,6757644.857766709],[224213.69539062932,6757650.265084579],[224216.34749308732,6757649.905834524]]]]},"properties":{"pk":371,"id_way":69932396,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223987.7605815853,6758492.684021002],[223984.04755736105,6758491.743978931],[223982.51774193242,6758497.643905341],[223986.14463142073,6758499.184877789],[223987.7605815853,6758492.684021002]]]]},"properties":{"pk":372,"id_way":69932418,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224045.05160113104,6757852.539749759],[224036.69046399556,6757849.518745155],[224034.35249290196,6757855.835320977],[224042.71311902622,6757858.943491798],[224045.05160113104,6757852.539749759]]]]},"properties":{"pk":373,"id_way":69932448,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223706.62082984947,6758392.4911873415],[223703.1293296601,6758404.890643218],[223711.42523303023,6758407.260484702],[223715.04153915145,6758394.938489375],[223706.62082984947,6758392.4911873415]]]]},"properties":{"pk":374,"id_way":69932472,"height":7.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223928.67662689465,6758021.727061918],[223934.54835804386,6758018.406087622],[223931.54559573796,6758013.123380601],[223925.70280169547,6758016.442056696],[223928.67662689465,6758021.727061918]]]]},"properties":{"pk":375,"id_way":69932473,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224121.71783215503,6757438.196607977],[224125.36064048528,6757444.489414057],[224126.70225370151,6757447.289361397],[224130.70368356214,6757445.334219249],[224129.70877342136,6757443.232320857],[224126.9325385487,6757445.152514441],[224121.94582734717,6757438.0324992305],[224121.71783215503,6757438.196607977]]]]},"properties":{"pk":376,"id_way":69932477,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223747.98223368308,6758347.14970508],[223749.563602277,6758347.5780243315],[223750.34304564353,6758344.771213209],[223748.7895096265,6758344.341079069],[223747.98223368308,6758347.14970508]]]]},"properties":{"pk":377,"id_way":69932517,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224010.2713055459,6758592.912238299],[224015.3992698931,6758590.2195590325],[224012.5937070765,6758583.278113926],[224015.114198976,6758573.459633986],[224002.37486943477,6758567.829468622],[223996.67368882947,6758589.329861792],[224010.2713055459,6758592.912238299]]]]},"properties":{"pk":378,"id_way":69932518,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223779.90791528777,6757908.748971167],[223773.9783146586,6757912.108409988],[223775.71030717844,6757915.219697887],[223781.67125173192,6757911.890354512],[223779.90791528777,6757908.748971167]]]]},"properties":{"pk":379,"id_way":69932520,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223982.3660265475,6757950.747372228],[223985.59822407548,6757942.00695878],[223971.73741330687,6757936.8016413115],[223968.4444325253,6757945.613065686],[223982.3660265475,6757950.747372228]]]]},"properties":{"pk":380,"id_way":69932585,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223617.4327560833,6758111.005522165],[223627.36570632152,6758128.496950227],[223632.85167532924,6758125.211133927],[223622.97548567003,6758107.907365919],[223617.4327560833,6758111.005522165]]]]},"properties":{"pk":381,"id_way":69932607,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223911.27977884418,6758142.048881798],[223896.37401919498,6758136.636494889],[223893.52789268128,6758144.386904702],[223908.40211918732,6758149.867904188],[223911.27977884418,6758142.048881798]]]]},"properties":{"pk":382,"id_way":69932608,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223539.01521410394,6757458.527991504],[223533.89879146666,6757450.398125766],[223526.41382045977,6757455.8696966795],[223531.06312225023,6757463.502396822],[223539.01521410394,6757458.527991504]]]]},"properties":{"pk":383,"id_way":69932610,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223916.64818207952,6757368.465025014],[223911.663823818,6757361.67007024],[223901.2665896391,6757369.149646607],[223906.2253652407,6757375.990362937],[223916.64818207952,6757368.465025014]]]]},"properties":{"pk":384,"id_way":69932612,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223966.03680959906,6758432.882471134],[223968.4261358099,6758442.490815392],[223977.08954843413,6758440.341549627],[223974.6381937044,6758430.694622007],[223966.03680959906,6758432.882471134]]]]},"properties":{"pk":385,"id_way":69932629,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224079.44780423152,6757845.662071244],[224073.89370026093,6757843.619214812],[224070.68762281645,6757852.511725048],[224076.3293411033,6757854.547909848],[224079.44780423152,6757845.662071244]]]]},"properties":{"pk":386,"id_way":69932632,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223897.38327307382,6757693.986394622],[223911.86389001113,6757688.627684738],[223912.01919948694,6757684.533680979],[223911.50467020366,6757683.294786668],[223904.74239369459,6757685.814767658],[223903.00730864776,6757681.075187838],[223893.85991523165,6757684.762957833],[223897.38327307382,6757693.986394622]]]]},"properties":{"pk":387,"id_way":69932669,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223884.38419724436,6758396.963308923],[223892.60269384037,6758399.994118404],[223896.69971502468,6758388.8440887965],[223888.48480374666,6758385.85661897],[223884.38419724436,6758396.963308923]]]]},"properties":{"pk":388,"id_way":69932690,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223725.4645699658,6758462.767866609],[223732.75696021356,6758462.829891622],[223732.91672482455,6758453.976265188],[223725.57134404572,6758453.886017919],[223725.4645699658,6758462.767866609]]]]},"properties":{"pk":389,"id_way":69932692,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223738.5923805717,6757937.902207998],[223753.18406029817,6757929.729231239],[223749.15182080807,6757922.513297897],[223734.59135943287,6757930.793750081],[223738.5923805717,6757937.902207998]]]]},"properties":{"pk":390,"id_way":69932693,"height":9.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223939.65533804946,6757660.655900013],[223935.81940827798,6757652.659912914],[223924.24562959743,6757658.435529036],[223916.93657350575,6757663.582400122],[223920.06726818957,6757670.211580875],[223939.65533804946,6757660.655900013]]]]},"properties":{"pk":391,"id_way":69932695,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223755.40673312766,6758372.622758121],[223756.96677616864,6758366.635344812],[223753.6973575338,6758365.878424629],[223752.24789405556,6758371.457681037],[223755.40673312766,6758372.622758121]]]]},"properties":{"pk":392,"id_way":69932720,"height":3.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224128.4413524061,6758547.416236404],[224110.92752424622,6758584.370176829],[224119.41553088112,6758588.565043546],[224137.1969304146,6758551.690552988],[224128.4413524061,6758547.416236404]]]]},"properties":{"pk":393,"id_way":69932721,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223892.95220023635,6757879.818460023],[223887.9730182918,6757882.628615236],[223890.97684541962,6757887.913017315],[223895.4627682688,6757885.487711831],[223892.95220023635,6757879.818460023]]]]},"properties":{"pk":394,"id_way":69932723,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223949.72772517006,6757580.391269987],[223948.99050911158,6757580.802039882],[223948.73833224227,6757581.8254613625],[223951.00534193157,6757586.018279981],[223970.32120963442,6757575.521764958],[223962.0054232795,6757559.0227765795],[223945.11811131772,6757568.030537707],[223945.9335249099,6757573.905914329],[223959.91461311307,6757566.641423122],[223962.95815524063,6757572.240099916],[223949.06286133899,6757579.777185598],[223949.72772517006,6757580.391269987]]]]},"properties":{"pk":395,"id_way":69932725,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224081.48259160956,6757977.614094547],[224079.6423148314,6757982.875238049],[224081.9684243564,6757983.760627481],[224083.83439461217,6757978.466686449],[224081.48259160956,6757977.614094547]]]]},"properties":{"pk":396,"id_way":69932754,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223969.43708137417,6757891.493875331],[223972.0914909869,6757892.4660439305],[223974.0983115519,6757887.078234653],[223971.5065709261,6757886.080927268],[223969.43708137417,6757891.493875331]]]]},"properties":{"pk":397,"id_way":69932786,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223595.30545716075,6758107.4682077635],[223603.93668199272,6758102.522242369],[223603.37686374615,6758101.622668288],[223604.7426600236,6758100.785182914],[223602.38308382558,6758096.436421854],[223608.3965052163,6758092.990058702],[223610.87104171378,6758097.382215301],[223612.23230231673,6758096.593917955],[223612.79511219045,6758097.508010078],[223617.84314622235,6758094.652936778],[223609.79769848747,6758080.548145878],[223587.35330100427,6758093.323014858],[223595.30545716075,6758107.4682077635]]]]},"properties":{"pk":398,"id_way":69932809,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223763.96190647318,6758010.222514948],[223755.36126412032,6758014.971330073],[223755.50326908947,6758015.247419733],[223753.5533148729,6758016.384391785],[223756.26670246216,6758021.21548376],[223753.65797810364,6758022.7082013795],[223758.460053322,6758031.345770639],[223771.61944506268,6758023.96866208],[223763.96190647318,6758010.222514948]]]]},"properties":{"pk":399,"id_way":69932811,"height":13.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223545.5702561221,6757518.021475218],[223548.9890235529,6757517.313204509],[223547.29602293516,6757509.610225026],[223543.96627094867,6757510.237195759],[223545.5702561221,6757518.021475218]]]]},"properties":{"pk":400,"id_way":69932813,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223973.03051372067,6757378.06307755],[223975.94536661124,6757382.322671035],[223993.04928138407,6757370.1524715815],[223992.51326252805,6757369.2828044575],[223994.18371133326,6757368.064575938],[223994.80673137543,6757368.974069584],[223997.25731903594,6757367.237816952],[223996.69624522797,6757366.326613674],[223998.37365800125,6757365.069770997],[223998.98933337475,6757366.060261194],[224004.94891172243,6757361.930432491],[224006.12108366567,6757354.996516266],[223999.50676424638,6757353.89662571],[223999.9260911641,6757354.488269611],[223998.22106863488,6757355.7102828855],[223997.72039082914,6757355.003444803],[223970.44909135267,6757374.379677205],[223970.7416648223,6757374.808644679],[223970.2163432051,6757377.514717887],[223973.03051372067,6757378.06307755]]]]},"properties":{"pk":401,"id_way":69932815,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223641.74289299353,6757891.142209578],[223635.97304080983,6757895.196307861],[223645.8959139847,6757909.8251371365],[223651.606426156,6757905.765374857],[223641.74289299353,6757891.142209578]]]]},"properties":{"pk":402,"id_way":69932837,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223944.94683038074,6757720.778371106],[223945.583865566,6757720.399961146],[223945.0561178015,6757719.356147935],[223944.34454582102,6757719.760634825],[223944.94683038074,6757720.778371106]]]]},"properties":{"pk":403,"id_way":69932861,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223866.33655282596,6758583.543690977],[223864.77129796546,6758587.707290901],[223877.53304629808,6758592.395501461],[223878.85504856502,6758587.269095364],[223866.33655282596,6758583.543690977]]]]},"properties":{"pk":404,"id_way":69932883,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223793.18317435216,6757946.5527927065],[223790.56877135174,6757941.907050275],[223786.41163899016,6757944.211029862],[223789.0294083298,6757948.899321605],[223793.18317435216,6757946.5527927065]]]]},"properties":{"pk":405,"id_way":69932886,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224044.7423052037,6757621.211842915],[224045.66242463575,6757618.633752009],[224040.2001873906,6757616.672264463],[224039.31093616792,6757619.290319841],[224044.7423052037,6757621.211842915]]]]},"properties":{"pk":406,"id_way":69932888,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223646.1300407468,6758161.636626788],[223651.44525871068,6758158.464332033],[223650.15419670145,6758156.153628996],[223644.80992062498,6758159.31708781],[223646.1300407468,6758161.636626788]]]]},"properties":{"pk":407,"id_way":69932909,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224047.189486762,6758075.633447206],[224049.27959880693,6758076.3237246815],[224054.00089178982,6758063.482321484],[224046.28875793537,6758060.732567921],[224043.49593434663,6758068.914163045],[224048.8824344474,6758070.816673304],[224047.189486762,6758075.633447206]]]]},"properties":{"pk":408,"id_way":69932910,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224139.31346442588,6757453.247096546],[224141.4431839272,6757458.195783143],[224144.3461524969,6757457.719884239],[224143.47558041508,6757452.583454336],[224139.31346442588,6757453.247096546]]]]},"properties":{"pk":409,"id_way":69932914,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223931.91964392035,6758531.795386835],[223935.31364868314,6758533.501582316],[223936.12460384567,6758531.901602944],[223933.99372320774,6758530.825464799],[223938.2119175556,6758522.370520811],[223932.86073084877,6758519.69608343],[223931.08037393697,6758523.268585112],[223935.19404304857,6758525.333436747],[223931.91964392035,6758531.795386835]]]]},"properties":{"pk":410,"id_way":69932931,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224079.8784947953,6757885.281704825],[224082.22609541978,6757878.799678359],[224069.68812910962,6757874.221838109],[224067.4341453531,6757880.58612202],[224079.8784947953,6757885.281704825]]]]},"properties":{"pk":411,"id_way":69932934,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223855.55165503293,6757804.133509223],[223852.18570650415,6757798.978845116],[223849.3775755141,6757800.740748917],[223852.8944412904,6757805.954472536],[223855.55165503293,6757804.133509223]]]]},"properties":{"pk":412,"id_way":69932957,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223597.36034013878,6758534.31311289],[223595.957579693,6758543.159231025],[223623.1371755682,6758547.681043638],[223624.5785187686,6758538.953523324],[223597.36034013878,6758534.31311289]]]]},"properties":{"pk":413,"id_way":69933006,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223575.68912321902,6757877.504023583],[223585.99254326342,6757877.990312659],[223595.45268684716,6757867.604589547],[223585.98753025229,6757858.363405009],[223570.8736954936,6757873.982045075],[223571.78242807154,6757877.336481443],[223574.15379652657,6757877.445473985],[223574.10215117372,6757874.159260624],[223578.21740327985,6757869.9382325355],[223578.16654165668,6757869.028356054],[223579.9545983375,6757867.194497292],[223585.7029108931,6757872.8811923675],[223585.66467815047,6757874.363987571],[223582.7201317392,6757874.309659505],[223581.21295558434,6757872.97053698],[223577.6481156765,6757872.843850748],[223575.89430893882,6757874.44063496],[223575.68912321902,6757877.504023583]]]]},"properties":{"pk":414,"id_way":69933009,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223766.33039233732,6758387.800645498],[223760.54542360516,6758385.687121148],[223756.1150118665,6758397.7340776175],[223762.02203718876,6758399.892612925],[223766.33039233732,6758387.800645498]]]]},"properties":{"pk":415,"id_way":69933052,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223759.00850063722,6757826.175348115],[223754.60538983293,6757818.319738138],[223754.17168840428,6757817.660460039],[223753.41462050696,6757817.007545128],[223753.03709676513,6757816.942855654],[223751.80736290896,6757817.321143793],[223742.93608650923,6757823.132264175],[223742.28966174502,6757824.222728991],[223742.36709528783,6757824.92175897],[223746.68123508178,6757833.313822813],[223759.00850063722,6757826.175348115]]]]},"properties":{"pk":416,"id_way":69933055,"height":15.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223807.9221666804,6757483.789787737],[223811.31755142668,6757481.420492081],[223808.3297854415,6757477.075426023],[223804.8769812013,6757479.449603457],[223807.9221666804,6757483.789787737]]]]},"properties":{"pk":417,"id_way":69933057,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223766.4052933859,6758133.069793615],[223757.36679389837,6758137.121270433],[223761.68266509427,6758146.972005274],[223770.7440149489,6758142.929606025],[223766.4052933859,6758133.069793615]]]]},"properties":{"pk":418,"id_way":69933077,"height":7.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223893.89279712443,6758031.197325449],[223899.29074404357,6758028.1737198895],[223893.96017181096,6758018.654329156],[223886.311285941,6758022.966438945],[223891.847126245,6758032.872587599],[223894.16001491164,6758031.631058282],[223893.89279712443,6758031.197325449]]]]},"properties":{"pk":419,"id_way":69933078,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224384.4789550814,6757455.311910537],[224385.4978248238,6757456.393940248],[224387.066299815,6757455.109212115],[224385.9864589704,6757453.880654724],[224384.4789550814,6757455.311910537]]]]},"properties":{"pk":420,"id_way":69933082,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223853.17408215342,6758423.178580009],[223858.25655297854,6758409.314438556],[223848.38660111802,6758405.570527365],[223843.30494545124,6758419.519666262],[223853.17408215342,6758423.178580009]]]]},"properties":{"pk":421,"id_way":69933099,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224112.11650195718,6757750.790413865],[224103.73110249016,6757771.911488102],[224101.29135065246,6757771.010825412],[224102.75488969797,6757766.981588246],[224099.77923860453,6757765.932599381],[224098.79207985438,6757768.6985571515],[224093.6154810366,6757766.875871786],[224081.0948036826,6757800.833030202],[224107.09064496428,6757810.443966507],[224127.13984585778,6757756.052092722],[224112.11650195718,6757750.790413865]]]]},"properties":{"pk":422,"id_way":69933102,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223885.99890327806,6757783.811718791],[223890.6570121517,6757780.697900052],[223888.80393020742,6757777.658531339],[223884.20050031293,6757779.81447825],[223885.99890327806,6757783.811718791]]]]},"properties":{"pk":423,"id_way":69933126,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223637.17933766203,6757338.1791966995],[223643.21405491637,6757333.849203852],[223642.18045490148,6757332.421122407],[223636.14696419428,6757336.761644358],[223637.17933766203,6757338.1791966995]]]]},"properties":{"pk":424,"id_way":69933130,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223698.1105443814,6757960.911784501],[223689.32390077034,6757945.626066207],[223689.5652754354,6757945.349399541],[223689.25651109283,6757944.796682902],[223688.51033151345,6757944.142704238],[223687.44916917945,6757943.603317836],[223686.54403916132,6757943.676418791],[223685.28915825568,6757944.184015399],[223685.13951876285,6757944.263837876],[223685.33469339335,6757944.404571868],[223678.06241512846,6757949.238557958],[223689.30296149844,6757966.463736903],[223698.1105443814,6757960.911784501]]]]},"properties":{"pk":425,"id_way":69933172,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223895.54180442553,6757620.552209051],[223897.92415171242,6757618.84657323],[223894.4991662295,6757613.91271125],[223892.08240891603,6757615.64270741],[223895.54180442553,6757620.552209051]]]]},"properties":{"pk":426,"id_way":69933176,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223838.2361684248,6758174.868467539],[223841.30269600597,6758188.344398862],[223847.38622380362,6758187.010785555],[223844.35522566573,6758173.50514132],[223838.2361684248,6758174.868467539]]]]},"properties":{"pk":427,"id_way":69933205,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224021.62868273308,6758575.6935131615],[224029.0514004745,6758558.235149074],[224021.21585918052,6758554.388742346],[224017.69919950486,6758562.528936418],[224019.91352602848,6758563.520340601],[224017.01253836573,6758570.3379380535],[224014.70514597525,6758569.420149577],[224013.4710567288,6758572.2427060865],[224021.62868273308,6758575.6935131615]]]]},"properties":{"pk":428,"id_way":69933206,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223903.82915294464,6757846.940132568],[223917.33740610827,6757840.889625539],[223912.49468287238,6757830.077873523],[223899.01669362874,6757836.136971658],[223903.82915294464,6757846.940132568]]]]},"properties":{"pk":429,"id_way":69933208,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224108.65919242805,6757502.391677662],[224114.97848571517,6757511.440731876],[224120.65626604125,6757507.461836201],[224114.27666096637,6757498.407672762],[224108.65919242805,6757502.391677662]]]]},"properties":{"pk":430,"id_way":69933211,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224191.96958474375,6757956.005610535],[224193.1872769255,6757953.006781865],[224195.281248868,6757953.83964668],[224205.5731524585,6757925.930255565],[224195.40835261694,6757922.340095141],[224185.23390829275,6757950.067937994],[224187.16025634238,6757950.816186622],[224185.99744292133,6757953.817514948],[224191.96958474375,6757956.005610535]]]]},"properties":{"pk":431,"id_way":69933256,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223797.58192039616,6757789.271333476],[223808.5141336497,6757808.671845202],[223818.27277399588,6757803.109030813],[223807.31401125598,6757783.706857923],[223797.58192039616,6757789.271333476]]]]},"properties":{"pk":432,"id_way":69933284,"height":13.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223972.55265770515,6758097.1309346855],[223980.64923385432,6758100.050482761],[223981.3006126006,6758098.1092351265],[223973.20393937547,6758095.189969113],[223972.55265770515,6758097.1309346855]]]]},"properties":{"pk":433,"id_way":69933310,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223532.57199067186,6757568.586777171],[223531.645976433,6757563.574924004],[223528.0175551759,6757564.195705861],[223529.00855922612,6757569.297354461],[223532.57199067186,6757568.586777171]]]]},"properties":{"pk":434,"id_way":69933313,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223691.90607312333,6757888.901334168],[223687.41949580167,6757882.536672608],[223679.3635058575,6757888.256686164],[223683.8564818415,6757894.609932124],[223691.90607312333,6757888.901334168]]]]},"properties":{"pk":435,"id_way":69933340,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223588.46113694904,6757536.038249711],[223580.81882143018,6757523.843928329],[223575.31110497983,6757525.02242617],[223577.91327299934,6757531.775796718],[223578.60892239973,6757531.457642046],[223581.8647541352,6757536.959130253],[223581.1766651482,6757537.394330526],[223582.49759905084,6757539.715062144],[223588.46113694904,6757536.038249711]]]]},"properties":{"pk":436,"id_way":69933368,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223579.2438375244,6758132.163643988],[223581.88138369296,6758130.685497677],[223578.7051242045,6758125.038192444],[223576.0675758466,6758126.5163402315],[223579.2438375244,6758132.163643988]]]]},"properties":{"pk":437,"id_way":69933453,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223928.72671826454,6758195.357279987],[223934.75221643702,6758203.071938415],[223942.07024361234,6758196.510026784],[223935.5843773834,6758189.180479928],[223928.72671826454,6758195.357279987]]]]},"properties":{"pk":438,"id_way":69933454,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224089.10318174234,6757568.083790382],[224089.1686455442,6757567.835632997],[224091.59961338082,6757568.867987149],[224091.56704460896,6757569.030685405],[224100.31368686,6757573.242752563],[224105.41516311388,6757564.146398974],[224101.83749962755,6757562.365373228],[224101.9230372935,6757561.9363220185],[224099.09496871333,6757560.588733569],[224093.22077452537,6757558.168400988],[224092.47557104638,6757560.173544843],[224088.33169600272,6757558.760862856],[224088.7232499913,6757557.104973807],[224084.63741914445,6757555.873407452],[224084.7282005494,6757555.52394947],[224078.88686983893,6757554.208076805],[224076.8049432073,6757564.71612062],[224082.75056942974,6757566.094434425],[224089.10318174234,6757568.083790382]]]]},"properties":{"pk":439,"id_way":69933460,"height":19.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223933.95129073033,6758479.04703063],[223932.43333035143,6758482.031194028],[223934.00142198763,6758482.885917874],[223935.56988561916,6758479.645892672],[223933.95129073033,6758479.04703063]]]]},"properties":{"pk":440,"id_way":69933482,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224043.08716843408,6757960.800897244],[224051.53719183436,6757963.913210818],[224057.0114235496,6757948.750734064],[224048.73537889562,6757945.679606317],[224043.08716843408,6757960.800897244]]]]},"properties":{"pk":441,"id_way":69933485,"height":9.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223776.148976194,6758628.798231092],[223775.20199255124,6758631.376883503],[223779.66101436643,6758632.930768357],[223780.57626017404,6758630.3969928725],[223776.148976194,6758628.798231092]]]]},"properties":{"pk":442,"id_way":69933505,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223702.44897404924,6757271.640157081],[223706.0583782995,6757276.660263786],[223710.816039502,6757273.268525049],[223707.29427497654,6757268.252065838],[223702.44897404924,6757271.640157081]]]]},"properties":{"pk":443,"id_way":69933512,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223567.97341225873,6757634.154422852],[223562.41699714478,6757626.369191688],[223560.05844662234,6757627.975200987],[223556.69591719875,6757623.287886245],[223550.4209414766,6757627.706176572],[223559.28421315894,6757640.315686463],[223567.97341225873,6757634.154422852]]]]},"properties":{"pk":444,"id_way":69933555,"height":10.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223597.7389361714,6758330.19015564],[223581.56656850586,6758327.37791737],[223579.47524776668,6758339.837281628],[223573.7903663728,6758340.653252078],[223573.24862226332,6758343.839392999],[223594.8400544823,6758347.48544781],[223597.7389361714,6758330.19015564]]]]},"properties":{"pk":445,"id_way":69933577,"height":7.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223553.40247616972,6757893.692172857],[223554.46596209324,6757890.203474451],[223554.81968364507,6757890.241785094],[223555.42775827102,6757888.009958396],[223555.18727424543,6757887.928705674],[223555.86555370234,6757885.529438141],[223559.45645924727,6757886.486411365],[223559.60750572395,6757887.325697551],[223563.03178624864,6757888.480133073],[223565.1864106355,6757885.725527808],[223546.2146827248,6757880.1899184035],[223542.6339955955,6757892.397856031],[223556.7989871766,6757896.5988443],[223559.2477000762,6757893.4278442385],[223557.98688466338,6757892.469012985],[223556.25334174588,6757894.583435092],[223553.40247616972,6757893.692172857]]]]},"properties":{"pk":446,"id_way":69933580,"height":16.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224166.96642900674,6757706.739206443],[224167.12060594867,6757706.1230206285],[224203.7762043379,6757719.662645392],[224199.89707253486,6757730.331664758],[224195.20097013816,6757743.939593611],[224203.97442497683,6757747.127958768],[224215.64252416432,6757714.0324357],[224162.2396547106,6757694.325841483],[224158.76761794006,6757703.731394341],[224166.96642900674,6757706.739206443]]]]},"properties":{"pk":447,"id_way":69933583,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224112.12324462514,6757988.746307536],[224109.73642211538,6757987.906297995],[224107.84259139627,6757993.127623283],[224110.16490144262,6757993.971842716],[224112.12324462514,6757988.746307536]]]]},"properties":{"pk":448,"id_way":69933612,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223879.21069590707,6758549.678699468],[223877.1650721088,6758557.701210265],[223892.72892872986,6758561.841758006],[223893.45025441158,6758561.632879006],[223897.72581511724,6758547.132071378],[223893.33176495647,6758545.874137197],[223891.21456737723,6758552.9773614695],[223879.21069590707,6758549.678699468]]]]},"properties":{"pk":449,"id_way":69933649,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223594.2272253483,6758411.337581241],[223592.8235586011,6758419.393631808],[223601.50221349436,6758420.83941201],[223602.82267794828,6758412.812860658],[223594.2272253483,6758411.337581241]]]]},"properties":{"pk":450,"id_way":69933652,"height":9.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224006.54107654502,6757885.616158201],[224008.93980407136,6757879.1289112335],[223995.04101316244,6757874.003664655],[223992.67213854496,6757880.400545068],[224006.54107654502,6757885.616158201]]]]},"properties":{"pk":451,"id_way":69933656,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223794.51616599035,6758128.5381846065],[223795.6117814241,6758131.079827037],[223800.41036166943,6758128.99609932],[223799.30775323798,6758126.454950548],[223794.51616599035,6758128.5381846065]]]]},"properties":{"pk":452,"id_way":69933700,"height":3.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224024.31827453847,6758190.508346064],[224024.92463844267,6758188.255133707],[224023.67046610924,6758187.951174383],[224023.08757186646,6758190.1641589785],[224024.31827453847,6758190.508346064]]]]},"properties":{"pk":453,"id_way":69933701,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223553.16375897048,6757549.590390865],[223552.11648585595,6757543.823731092],[223549.26306435544,6757544.45039191],[223550.421011254,6757550.1450839965],[223553.16375897048,6757549.590390865]]]]},"properties":{"pk":454,"id_way":69933705,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224066.7462463029,6757321.64392697],[224052.0789034109,6757331.922764346],[224052.73085483044,6757332.866156725],[224067.33319647395,6757322.461962466],[224066.7462463029,6757321.64392697]]]]},"properties":{"pk":455,"id_way":69933708,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223806.595368218,6757884.156271976],[223818.66205692734,6757877.250684218],[223814.21779879837,6757870.139878425],[223802.473786694,6757876.768776546],[223806.595368218,6757884.156271976]]]]},"properties":{"pk":456,"id_way":69933742,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224008.61959849592,6757751.046548243],[224017.3913767792,6757746.9200185845],[224014.4669482027,6757740.733495845],[224005.643389395,6757744.85315703],[224008.61959849592,6757751.046548243]]]]},"properties":{"pk":457,"id_way":69933778,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223575.65052620234,6757553.7473393185],[223576.87558453067,6757560.068746098],[223579.6113918634,6757559.514620874],[223578.56166132897,6757553.199203101],[223575.65052620234,6757553.7473393185]]]]},"properties":{"pk":458,"id_way":69933782,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223995.1998189193,6757916.20437612],[223997.89621247404,6757908.9346322175],[223981.51383387207,6757902.851640997],[223978.81441071467,6757910.077030544],[223995.1998189193,6757916.20437612]]]]},"properties":{"pk":459,"id_way":69933813,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224035.15437604333,6757721.834915774],[224032.52550642358,6757728.492269515],[224041.18711930615,6757732.192141218],[224043.6431020735,6757726.048897322],[224044.20939254278,6757724.087048723],[224044.45088034007,6757722.087694044],[224044.41776003997,6757721.032773318],[224044.1594513035,6757719.036219282],[224043.59003916936,6757717.225484867],[224035.15437604333,6757721.834915774]]]]},"properties":{"pk":460,"id_way":69933818,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224016.90169736484,6758108.369896582],[224011.7921683039,6758106.761659687],[224003.91258088814,6758128.438979037],[224014.67079570275,6758131.906639899],[224017.37644702857,6758123.53548266],[224011.66022512468,6758121.666131799],[224012.8295979406,6758118.352294084],[224013.3640784482,6758118.55432152],[224016.90169736484,6758108.369896582]]]]},"properties":{"pk":461,"id_way":69933851,"height":9.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224212.1868449926,6757639.629776331],[224209.5065293745,6757639.991324918],[224210.09538732457,6757645.049108168],[224212.79725719223,6757644.685783833],[224212.1868449926,6757639.629776331]]]]},"properties":{"pk":462,"id_way":69933859,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223977.6081353419,6758543.69250798],[223977.1960574749,6758544.494642206],[223984.6797551324,6758548.441085683],[223985.71496568937,6758546.311931457],[223986.8707808602,6758546.832419596],[223987.8581311347,6758544.881150079],[223986.73128158995,6758544.325841267],[223988.4540552779,6758540.885626155],[223980.97507094892,6758537.0141690215],[223977.6081353419,6758543.69250798]]]]},"properties":{"pk":463,"id_way":69933885,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224023.39239049805,6757911.476916695],[224029.3939953378,6757895.135386662],[224021.03525302076,6757892.136281812],[224015.05763243596,6757908.4104757365],[224023.39239049805,6757911.476916695]]]]},"properties":{"pk":464,"id_way":69933911,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223918.56368392348,6758046.214135068],[223915.6489661115,6758041.013620109],[223908.8909397835,6758044.80809047],[223911.82827696714,6758050.017690445],[223918.56368392348,6758046.214135068]]]]},"properties":{"pk":465,"id_way":69933935,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223701.19993220357,6758442.594580692],[223705.23303612322,6758428.736107962],[223696.36956336882,6758426.12566015],[223692.46113985995,6758439.875050047],[223701.19993220357,6758442.594580692]]]]},"properties":{"pk":466,"id_way":69933936,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224113.27656159332,6757471.400926757],[224116.3261992027,6757475.862757655],[224118.73804179017,6757474.164927391],[224115.695548905,6757469.702426889],[224113.27656159332,6757471.400926757]]]]},"properties":{"pk":467,"id_way":69933940,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223680.60647207632,6758338.067879726],[223679.85934980572,6758340.023015485],[223676.86008251132,6758339.005618156],[223677.39394218466,6758337.426672543],[223678.08824739335,6758334.2048011],[223672.72056223376,6758332.970586401],[223670.61406449997,6758341.912096727],[223681.97323648565,6758346.09820999],[223684.81750881262,6758338.259243051],[223680.60647207632,6758338.067879726]]]]},"properties":{"pk":468,"id_way":69933960,"height":6.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223744.53456951727,6757905.29075781],[223751.15234437186,6757915.0185168255],[223753.14239262187,6757919.078256453],[223757.948486647,6757916.304369854],[223755.58711622818,6757912.164775846],[223762.8774047744,6757907.288242412],[223756.25574061353,6757897.519284294],[223744.53456951727,6757905.29075781]]]]},"properties":{"pk":469,"id_way":69933963,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223957.93645492097,6757892.75036535],[223959.75020561073,6757887.933907878],[223962.94858184052,6757889.091449436],[223965.01586116818,6757883.632391128],[223964.10137542078,6757883.295651404],[223963.47492101046,6757884.522579398],[223949.8707235966,6757878.302169541],[223945.90133989204,6757888.333797828],[223957.93645492097,6757892.75036535]]]]},"properties":{"pk":470,"id_way":69934015,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223879.91174583402,6757631.734948712],[223882.94747235943,6757629.564431023],[223878.84407724024,6757623.836913454],[223875.8087290546,6757626.007161341],[223879.91174583402,6757631.734948712]]]]},"properties":{"pk":471,"id_way":69934017,"height":3.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223821.81599316213,6758166.518312652],[223822.38442238854,6758169.229559802],[223827.3904968051,6758166.578489078],[223826.81359344244,6758163.9320992585],[223821.81599316213,6758166.518312652]]]]},"properties":{"pk":472,"id_way":69934040,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223978.1227236369,6758050.760135245],[223986.75984332652,6758053.227251472],[223986.13295755335,6758055.796763065],[223988.48504188904,6758056.461505304],[223989.80294138263,6758050.636108735],[223991.83487356687,6758042.947541656],[223976.9791053582,6758038.3306535],[223978.1227236369,6758050.760135245]]]]},"properties":{"pk":473,"id_way":69934041,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223628.6814250257,6757286.655104204],[223624.81417324996,6757281.156533603],[223618.50542010824,6757285.7307407595],[223622.233607362,6757291.108601453],[223628.6814250257,6757286.655104204]]]]},"properties":{"pk":474,"id_way":69934043,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223964.07223953636,6758425.062593602],[223975.17117936592,6758422.248543254],[223973.6310333277,6758415.994213977],[223969.8763487366,6758416.898235096],[223969.81569063012,6758416.704180767],[223962.4497008614,6758418.613901827],[223964.07223953636,6758425.062593602]]]]},"properties":{"pk":475,"id_way":69934062,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224223.3542740172,6757877.665383264],[224232.75208560884,6757852.223764681],[224233.70476202207,6757847.91409388],[224224.03580037184,6757790.459718023],[224218.57601263004,6757791.319751026],[224219.51053883837,6757797.128006427],[224216.368854003,6757797.682258999],[224217.42640033585,6757803.804059311],[224215.23465768257,6757804.226184205],[224222.59501543394,6757848.293028393],[224213.03940957927,6757874.075293398],[224223.3542740172,6757877.665383264]]]]},"properties":{"pk":476,"id_way":69934065,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223696.4070521087,6757772.470802843],[223702.02467453916,6757780.538358543],[223708.46918605996,6757776.007044082],[223702.77371319046,6757767.978600173],[223696.4070521087,6757772.470802843]]]]},"properties":{"pk":477,"id_way":69934090,"height":13.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223875.8132913827,6758421.509257652],[223883.6455088291,6758424.425949654],[223886.34246519348,6758417.067257976],[223878.50962914474,6758414.161651452],[223875.8132913827,6758421.509257652]]]]},"properties":{"pk":478,"id_way":69934113,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223743.7428990383,6757925.364727772],[223739.56574091193,6757917.908599995],[223730.6085647023,6757923.6757304715],[223734.4934827887,6757930.61933314],[223743.7428990383,6757925.364727772]]]]},"properties":{"pk":479,"id_way":69934115,"height":10.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223992.2311151035,6757665.375796462],[224001.57221662733,6757660.036745505],[223995.23749385655,6757648.869966484],[223985.8928438673,6757654.165385123],[223992.2311151035,6757665.375796462]]]]},"properties":{"pk":480,"id_way":69934118,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223896.26111246107,6758183.489640191],[223896.17476045826,6758183.79271651],[223889.41625707943,6758181.53632922],[223889.08242580065,6758184.264126481],[223890.39936088576,6758184.270683937],[223888.81062176797,6758190.443041486],[223893.19593550978,6758190.984046222],[223895.06350322976,6758189.83930694],[223897.27769557352,6758183.88490404],[223896.26111246107,6758183.489640191]]]]},"properties":{"pk":481,"id_way":69934139,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224078.64502069575,6758558.720993458],[224069.94494743645,6758554.332835826],[224065.87228450977,6758562.471122156],[224074.6278644347,6758566.9093547035],[224078.64502069575,6758558.720993458]]]]},"properties":{"pk":482,"id_way":69934140,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223925.7654699736,6757878.154261461],[223918.30002382305,6757861.845389621],[223911.7792644369,6757864.790241681],[223919.1005637534,6757881.252830048],[223925.7654699736,6757878.154261461]]]]},"properties":{"pk":483,"id_way":69934142,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223924.20281606656,6757561.240527795],[223924.09781420932,6757561.11353761],[223917.21679191734,6757565.980615144],[223920.45987716812,6757572.495352255],[223923.37690761176,6757573.194412321],[223919.30405926402,6757564.655834882],[223924.20281606656,6757561.240527795]]]]},"properties":{"pk":484,"id_way":69934144,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224075.82829171547,6757975.551132987],[224073.3340499452,6757982.669949763],[224075.9294435596,6757983.625435034],[224078.51213849924,6757976.521677518],[224075.82829171547,6757975.551132987]]]]},"properties":{"pk":485,"id_way":69934165,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223983.34510858567,6757848.132322711],[223970.09249630664,6757840.421569409],[223965.67673411462,6757848.102886013],[223978.93495117943,6757855.766594797],[223983.34510858567,6757848.132322711]]]]},"properties":{"pk":486,"id_way":69934193,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223695.07344659255,6758060.669208498],[223705.59827906132,6758079.399715297],[223712.59716971993,6758075.517513893],[223702.13218458695,6758056.792728467],[223695.07344659255,6758060.669208498]]]]},"properties":{"pk":487,"id_way":69934216,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223747.12251308534,6758049.196639188],[223752.83966101232,6758059.310860944],[223756.3999476241,6758057.355585579],[223750.62225328447,6758047.214900957],[223747.12251308534,6758049.196639188]]]]},"properties":{"pk":488,"id_way":69934217,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223540.28556401806,6757486.467327492],[223541.30601897812,6757485.829586996],[223539.28169614525,6757482.394822289],[223538.17938166377,6757483.081781315],[223540.28556401806,6757486.467327492]]]]},"properties":{"pk":489,"id_way":69934219,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223602.27365534392,6757922.857047411],[223601.91732166175,6757922.752294232],[223599.0321924158,6757926.584017466],[223602.83883016813,6757933.057761886],[223617.29815174307,6757937.234986099],[223620.0416218982,6757927.537332329],[223602.27365534392,6757922.857047411]]]]},"properties":{"pk":490,"id_way":69934254,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223920.38485094393,6757720.163333626],[223925.20778874902,6757729.3576716175],[223927.41086336927,6757734.255834886],[223938.46205630756,6757728.604921829],[223931.28955360266,6757714.699228996],[223920.38485094393,6757720.163333626]]]]},"properties":{"pk":491,"id_way":69934277,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223586.41444781492,6757379.594169813],[223580.43414949096,6757383.845218508],[223577.83262352995,6757380.210134676],[223575.68595896405,6757381.751117159],[223583.3914493478,6757392.427379561],[223591.53148347046,6757386.6229826035],[223586.41444781492,6757379.594169813]]]]},"properties":{"pk":492,"id_way":69934279,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223792.01700046397,6758595.872100541],[223795.5297403761,6758585.828506426],[223783.4363027811,6758581.448514006],[223779.8381734566,6758591.532030388],[223792.01700046397,6758595.872100541]]]]},"properties":{"pk":493,"id_way":69934301,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223761.80591944561,6757284.11386576],[223758.7989342828,6757286.16406188],[223761.63789989278,6757290.273221305],[223764.64335504294,6757288.106426335],[223761.80591944561,6757284.11386576]]]]},"properties":{"pk":494,"id_way":69934306,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223852.38017317923,6758141.018242528],[223846.74224906976,6758126.316013597],[223826.85949783598,6758134.968162651],[223828.26719241298,6758138.733317715],[223831.96732784327,6758137.275628099],[223835.47746385273,6758146.372496345],[223852.38017317923,6758141.018242528]]]]},"properties":{"pk":495,"id_way":69934326,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223644.80540266103,6758146.727612707],[223643.5730262358,6758144.567137812],[223638.20102579068,6758147.657231544],[223639.46446787758,6758149.847827228],[223644.80540266103,6758146.727612707]]]]},"properties":{"pk":496,"id_way":69934327,"height":3.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224128.34464398035,6757460.8768963395],[224131.41295093074,6757465.22746688],[224133.83195891714,6757463.528965135],[224130.7565138097,6757459.179058758],[224128.34464398035,6757460.8768963395]]]]},"properties":{"pk":497,"id_way":69934331,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224084.70623498835,6757871.985735104],[224087.87728218004,6757863.218213634],[224079.60391096908,6757860.256413137],[224076.40099337557,6757868.993793946],[224084.70623498835,6757871.985735104]]]]},"properties":{"pk":498,"id_way":69934354,"height":12.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223848.0510956202,6757801.680672327],[223842.85572808227,6757805.069402062],[223851.92297738272,6757818.67451839],[223857.0097895367,6757815.317170057],[223848.0510956202,6757801.680672327]]]]},"properties":{"pk":499,"id_way":69934383,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223670.4329541297,6758382.661597858],[223673.63604501254,6758368.847390993],[223664.59585760423,6758366.688857659],[223661.2704086519,6758380.40133608],[223670.4329541297,6758382.661597858]]]]},"properties":{"pk":500,"id_way":69934434,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223564.5883467125,6757858.189525599],[223563.59835665516,6757862.142646088],[223564.33892822286,6757862.340169687],[223563.7722111186,6757864.272512596],[223568.4504981884,6757865.666087489],[223566.62684090837,6757858.853846774],[223564.5883467125,6757858.189525599]]]]},"properties":{"pk":501,"id_way":69934437,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223996.14570988703,6758500.275739233],[224001.42666264242,6758500.633666292],[224001.62512142907,6758497.785006992],[223996.31950938393,6758497.472135414],[223996.14570988703,6758500.275739233]]]]},"properties":{"pk":502,"id_way":69934463,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223761.24267037737,6758463.159754771],[223761.37324814277,6758454.309457133],[223752.15825953984,6758454.257266037],[223752.08262056098,6758463.059486798],[223761.24267037737,6758463.159754771]]]]},"properties":{"pk":503,"id_way":69934488,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223609.74211098682,6757832.619346413],[223615.32954877813,6757840.8443584135],[223621.8086399404,6757836.386553112],[223616.10678004465,6757828.203702907],[223609.74211098682,6757832.619346413]]]]},"properties":{"pk":504,"id_way":69934491,"height":16.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223754.5773466394,6757516.7418835],[223748.3693326657,6757507.845101321],[223739.639398562,6757514.076039795],[223747.64445420247,6757525.54120555],[223756.43639235996,6757519.436489227],[223754.5773466394,6757516.7418835]]]]},"properties":{"pk":505,"id_way":69934493,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223714.97633093488,6758156.813167603],[223713.95381670914,6758154.53715635],[223705.00788787226,6758158.427464596],[223708.93823046985,6758167.328207552],[223717.90942056215,6758163.403583493],[223714.97633093488,6758156.813167603]]]]},"properties":{"pk":506,"id_way":69934514,"height":10.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223882.05037297908,6758048.158440269],[223879.2570793188,6758043.160252838],[223876.70614528516,6758044.597405266],[223879.4994408238,6758049.595591435],[223882.05037297908,6758048.158440269]]]]},"properties":{"pk":507,"id_way":69934515,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224145.46689021788,6757439.913146917],[224163.21817076716,6757437.135821343],[224161.96297654844,6757429.479732902],[224155.08328319772,6757430.652571349],[224155.40467477814,6757432.866509981],[224148.39775654505,6757434.108292868],[224148.01376329057,6757431.774091161],[224143.92391306156,6757432.412114729],[224145.46689021788,6757439.913146917]]]]},"properties":{"pk":508,"id_way":69934519,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224051.0441471622,6757915.408823001],[224053.0524489823,6757909.944838651],[224044.86789013838,6757906.878602511],[224042.88129197207,6757912.340744029],[224051.0441471622,6757915.408823001]]]]},"properties":{"pk":509,"id_way":69934542,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223874.38331068403,6757745.773679395],[223880.05391029338,6757755.8013633825],[223883.85718251023,6757759.496130122],[223898.38964551385,6757751.391190478],[223896.15811858902,6757746.099986209],[223890.69341475298,6757736.427591212],[223874.38331068403,6757745.773679395]]]]},"properties":{"pk":510,"id_way":69934591,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223637.41324276477,6757449.381504124],[223637.13916793,6757451.20835997],[223639.33007901206,6757451.600290089],[223638.6195717736,6757455.884751074],[223624.69040211485,6757465.9007421555],[223623.81485105105,6757464.652027407],[223622.76306981893,6757464.945410471],[223621.50066172908,6757465.444699284],[223620.20626383618,6757466.223723431],[223614.72231576947,6757470.1494974615],[223613.2112746754,6757470.059757605],[223612.0604634184,6757470.880853886],[223611.89132751638,6757472.306478576],[223613.19781015776,6757474.126360685],[223607.6802474844,6757478.073348571],[223612.70420224234,6757485.46327486],[223657.16623175298,6757453.908441775],[223611.2131528072,6757389.050223053],[223603.8215246413,6757394.249246812],[223640.52193492072,6757445.9342257045],[223639.65439483683,6757449.667141357],[223637.41324276477,6757449.381504124]]]]},"properties":{"pk":511,"id_way":69934599,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223674.97477771566,6757984.991527067],[223693.13601597113,6757973.774188483],[223689.07172667552,6757966.441226306],[223680.7535844752,6757971.554526397],[223678.9519372631,6757968.701425493],[223668.8348616929,6757974.901603363],[223674.97477771566,6757984.991527067]]]]},"properties":{"pk":512,"id_way":69934623,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224047.69531588262,6757612.802703804],[224048.61037166844,6757610.257820843],[224043.11179915207,6757608.223219562],[224042.22974319488,6757610.840018191],[224047.69531588262,6757612.802703804]]]]},"properties":{"pk":513,"id_way":69934625,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223833.96106144515,6758156.1307176035],[223841.9719046536,6758154.178019645],[223840.8468005499,6758150.108447521],[223838.8360954661,6758150.616177551],[223837.5114294245,6758145.9254118595],[223831.66174438476,6758147.779309741],[223833.96106144515,6758156.1307176035]]]]},"properties":{"pk":514,"id_way":69934645,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224042.04037055487,6757990.162366256],[224045.4575669444,6757980.716491745],[224035.33488775365,6757977.084308754],[224031.93055929523,6757986.611893739],[224042.04037055487,6757990.162366256]]]]},"properties":{"pk":515,"id_way":69934646,"height":10.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224458.22631296323,6757499.627235158],[224462.71354753786,6757501.233677391],[224464.5147611503,6757496.254231783],[224460.0608713081,6757494.613043618],[224458.22631296323,6757499.627235158]]]]},"properties":{"pk":516,"id_way":69934650,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223805.2555548471,6758379.146087169],[223796.30194787335,6758375.353119466],[223795.7135173465,6758375.642558958],[223795.32716055436,6758376.151767715],[223795.1827329127,6758377.191138014],[223795.48705913403,6758377.797681122],[223794.60120285527,6758380.149820844],[223791.7371989936,6758379.110901629],[223789.56937309363,6758385.122770046],[223801.86801970672,6758389.619315028],[223803.37868274536,6758385.472188315],[223802.9934958953,6758385.35874367],[223805.2555548471,6758379.146087169]]]]},"properties":{"pk":517,"id_way":69934690,"height":9.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223795.29514812963,6757837.356684468],[223782.4639167035,6757843.877217325],[223785.98198590087,6757849.8162486935],[223786.7320883611,6757849.245277828],[223793.81060015343,6757845.107942958],[223794.49528225398,6757846.095213994],[223798.54941361095,6757844.125639762],[223798.14872529806,6757842.610911394],[223795.29514812963,6757837.356684468]]]]},"properties":{"pk":518,"id_way":69934693,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223993.41860747425,6758084.350980297],[223994.98746013382,6758079.891756332],[223978.89913938162,6758075.561114092],[223977.83532407714,6758078.658683687],[223993.41860747425,6758084.350980297]]]]},"properties":{"pk":519,"id_way":69934717,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223953.00917980704,6758029.006872045],[223947.81139513775,6758027.091618728],[223946.868486325,6758029.507057858],[223952.06906350152,6758031.464822338],[223953.00917980704,6758029.006872045]]]]},"properties":{"pk":520,"id_way":69934718,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223531.74109637985,6757659.8092871355],[223522.77886887323,6757647.2626589155],[223510.45391403773,6757655.981177331],[223519.37103910133,6757668.52043502],[223531.74109637985,6757659.8092871355]]]]},"properties":{"pk":521,"id_way":69934720,"height":9.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223683.7241322455,6758366.550831627],[223691.52409660426,6758369.415134359],[223694.39826236235,6758361.551571525],[223686.53906437554,6758358.681161078],[223683.7241322455,6758366.550831627]]]]},"properties":{"pk":522,"id_way":69934743,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224043.07457573962,6758604.571920164],[224044.7437316311,6758600.653276219],[224025.49807296705,6758592.672890719],[224023.90230637,6758596.546725221],[224043.07457573962,6758604.571920164]]]]},"properties":{"pk":523,"id_way":69934744,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223681.94609575407,6757847.324843151],[223676.01506230675,6757839.059572831],[223673.4825251558,6757840.845374916],[223679.07915274205,6757848.698431364],[223679.3045782684,6757848.870321156],[223679.66626273104,6757848.869842539],[223681.94609575407,6757847.324843151]]]]},"properties":{"pk":524,"id_way":69934746,"height":3.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223616.66237389197,6757503.252552742],[223622.2214965165,6757511.159182678],[223626.15996814665,6757508.444465783],[223632.27437089867,6757517.0633534575],[223630.76280640336,6757518.088706291],[223637.46266829676,6757527.66055634],[223642.4585883024,6757524.072714241],[223623.9743536612,6757498.082322263],[223616.66237389197,6757503.252552742]]]]},"properties":{"pk":525,"id_way":69934771,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223492.23113045006,6757277.830300073],[223491.65801772813,6757286.160100168],[223503.77965335594,6757286.924917382],[223504.5792382757,6757279.216345796],[223504.39695349877,6757278.59472673],[223492.23113045006,6757277.830300073]]]]},"properties":{"pk":526,"id_way":69934783,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223963.51897113974,6758000.859598373],[223957.19327762673,6757998.423914542],[223956.2533870503,6758000.774404096],[223959.75256766888,6758002.215173952],[223960.36796583948,6758003.602675785],[223962.24575171858,6758004.346081132],[223963.51897113974,6758000.859598373]]]]},"properties":{"pk":527,"id_way":69934793,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223942.54571962514,6758155.300790828],[223938.76331563678,6758154.068109029],[223940.33968837286,6758149.646407541],[223924.63677668304,6758143.963185999],[223921.75647726285,6758151.749773457],[223941.24958768516,6758158.864670178],[223942.54571962514,6758155.300790828]]]]},"properties":{"pk":528,"id_way":69934815,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223598.0667272136,6758150.48426905],[223629.57977526382,6758132.829448578],[223623.15911215974,6758121.535872428],[223615.00267554604,6758126.080141363],[223615.89024506902,6758127.6691715075],[223592.58630536371,6758140.698376888],[223598.0667272136,6758150.48426905]]]]},"properties":{"pk":529,"id_way":69934816,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224064.35806337462,6757527.224829578],[224060.2649302958,6757530.0714891255],[224060.35889346272,6757530.281736913],[224050.558619833,6757535.985104895],[224055.8781403863,6757545.252934308],[224070.05653793135,6757535.28718397],[224064.35806337462,6757527.224829578]]]]},"properties":{"pk":530,"id_way":69934820,"height":10.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223970.33001272823,6758480.344035339],[223975.6803467209,6758481.572011809],[223975.14814747783,6758483.468864819],[223977.36242660254,6758484.062355517],[223980.5701857342,6758474.379765988],[223972.91740627488,6758472.475615317],[223970.33001272823,6758480.344035339]]]]},"properties":{"pk":531,"id_way":69934837,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224075.46478408892,6757932.219958388],[224064.99789887533,6757960.7709952295],[224073.50873475624,6757963.879493526],[224083.97945055744,6757935.371925013],[224075.46478408892,6757932.219958388]]]]},"properties":{"pk":532,"id_way":69934840,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223818.44665114244,6757803.010202537],[223824.05239037008,6757799.833255363],[223821.52912764993,6757795.380282193],[223819.44963111557,6757796.528845297],[223815.63232555875,6757789.8691114085],[223828.26476177454,6757782.54000332],[223823.6408254126,6757774.411091814],[223807.4837907962,6757783.600774954],[223818.44665114244,6757803.010202537]]]]},"properties":{"pk":533,"id_way":69934867,"height":13.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223702.95458707248,6757262.082327954],[223687.00338272293,6757273.426674506],[223682.83925293028,6757267.01882778],[223674.16840746897,6757273.199157757],[223682.67862188185,6757285.33655442],[223707.17928336764,6757268.088428599],[223702.95458707248,6757262.082327954]]]]},"properties":{"pk":534,"id_way":69934869,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223638.92611364325,6758429.996644089],[223641.44355497306,6758419.493726964],[223634.65085629694,6758417.907380426],[223633.0117427897,6758424.69395596],[223631.58743476518,6758424.374162426],[223630.65710490136,6758428.171042884],[223638.92611364325,6758429.996644089]]]]},"properties":{"pk":535,"id_way":69934900,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224033.62704905318,6757617.220357855],[224039.12267939173,6757619.2227072995],[224040.01169701936,6757616.605339651],[224034.54277190933,6757614.686226649],[224033.62704905318,6757617.220357855]]]]},"properties":{"pk":536,"id_way":69934902,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223644.03345867863,6758301.294795221],[223647.21250780436,6758303.516806255],[223648.31954419368,6758301.792555702],[223645.1979603614,6758299.606822685],[223644.03345867863,6758301.294795221]]]]},"properties":{"pk":537,"id_way":69934932,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224248.56457511452,6758535.385098871],[224264.77459694218,6758544.487591093],[224273.2629950801,6758529.311696598],[224257.1081882282,6758520.248767321],[224248.56457511452,6758535.385098871]]]]},"properties":{"pk":538,"id_way":69934933,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223590.85863032966,6757811.209924183],[223593.60133133738,6757809.33218955],[223604.31678555792,6757801.911405342],[223600.42174285417,6757801.206478274],[223591.4800280011,6757807.3376002675],[223590.85863032966,6757811.209924183]]]]},"properties":{"pk":539,"id_way":69934935,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223934.95043984143,6757597.525499351],[223934.40200423036,6757599.012142385],[223933.7802611983,6757599.637932512],[223933.53286852074,6757600.601062872],[223937.77520562522,6757609.563481255],[223938.54948577497,6757610.114818426],[223939.60127171932,6757609.931287594],[223941.063387839,6757610.421515648],[223934.95043984143,6757597.525499351]]]]},"properties":{"pk":540,"id_way":69934937,"height":3.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224102.04307929781,6757985.082983691],[224100.12022304718,6757990.30715078],[224102.50462152177,6757991.189189353],[224104.40198423513,6757985.925136327],[224102.04307929781,6757985.082983691]]]]},"properties":{"pk":541,"id_way":69934958,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223824.8003627393,6758543.994784196],[223826.92738080322,6758535.975031868],[223817.67981680276,6758533.522480298],[223817.35016598445,6758534.740667073],[223813.9604614761,6758533.886849071],[223811.9760195185,6758532.9254039135],[223815.06735569763,6758524.802780013],[223805.78901290506,6758521.302129442],[223800.44710349786,6758535.847268447],[223801.50415248095,6758537.909199057],[223824.8003627393,6758543.994784196]]]]},"properties":{"pk":542,"id_way":69934979,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223589.6391290761,6758441.346082501],[223599.44199377813,6758442.334547582],[223599.9104868133,6758437.3996650325],[223590.22002345885,6758436.368966203],[223589.6391290761,6758441.346082501]]]]},"properties":{"pk":543,"id_way":69934981,"height":9.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224004.02340959784,6757892.354988443],[223990.16298933112,6757887.149808748],[223987.82166027252,6757893.509051735],[224001.74094050814,6757898.522583476],[224004.02340959784,6757892.354988443]]]]},"properties":{"pk":544,"id_way":69934982,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224055.04429070486,6758270.7158375755],[224056.7925498026,6758262.741645435],[224029.77047652504,6758256.128481518],[224029.89275095394,6758255.492380048],[224029.22187046558,6758255.31191515],[224029.0774973238,6758255.934344768],[224026.28796546016,6758255.25464003],[224026.11037840924,6758255.84934414],[224023.2206948343,6758255.125727641],[224023.4253074817,6758254.496063771],[224010.7937283932,6758251.347834461],[224010.88183827524,6758251.040158841],[224005.2174168501,6758249.654517092],[224005.12954804258,6758249.963166359],[223986.42946031236,6758245.296925652],[223988.85722178515,6758238.946311351],[223989.1819457985,6758239.064594314],[223991.27687523165,6758233.481646293],[223991.07484958833,6758233.408695262],[223993.840571176,6758226.194669469],[223993.7360366326,6758225.483834834],[223988.21157969374,6758223.223592548],[223987.0957103471,6758223.81562096],[223976.11533696638,6758250.939296657],[224055.04429070486,6758270.7158375755]]]]},"properties":{"pk":545,"id_way":69935004,"height":6.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223792.03873592668,6758122.886038103],[223793.2250731765,6758125.554637564],[223798.02470760216,6758123.470451954],[223796.86643624547,6758120.799837031],[223792.03873592668,6758122.886038103]]]]},"properties":{"pk":546,"id_way":69935005,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223552.702545857,6757529.764106791],[223542.1457216283,6757531.995458869],[223543.39806198093,6757537.853521894],[223544.55216805416,6757537.6088570645],[223545.14391547747,6757540.6506151585],[223548.23069383737,6757540.024105287],[223548.02376965623,6757539.040094713],[223550.23271482968,6757538.531726421],[223550.9533746872,6757541.807040026],[223544.49577080834,6757543.13137663],[223544.9226479053,6757545.190771491],[223555.1321635075,6757542.967592512],[223552.702545857,6757529.764106791]]]]},"properties":{"pk":547,"id_way":69935007,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224041.30947120488,6757479.346852375],[224047.48827019983,6757487.89435771],[224055.80171099046,6757481.974937343],[224049.83929796115,6757473.366185648],[224041.30947120488,6757479.346852375]]]]},"properties":{"pk":548,"id_way":69935009,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223738.59409519273,6757871.29762907],[223750.62768621295,6757863.4198770225],[223744.50242996798,6757857.006065818],[223731.97065500534,6757865.253008464],[223735.78575154213,6757871.055309644],[223737.61878225143,6757869.837526529],[223738.59409519273,6757871.29762907]]]]},"properties":{"pk":549,"id_way":69935031,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223984.70484707557,6757700.974254725],[223988.06725622033,6757708.028785532],[223995.14746757838,6757704.653139471],[223991.75052669918,6757697.5897154035],[223984.70484707557,6757700.974254725]]]]},"properties":{"pk":550,"id_way":69935057,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223587.21745018032,6757558.054899247],[223590.31501681756,6757556.109830476],[223587.3684838758,6757551.503596197],[223584.86663996696,6757551.988234094],[223585.96764085224,6757558.308559707],[223587.21745018032,6757558.054899247]]]]},"properties":{"pk":551,"id_way":69935059,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223920.80495575056,6758602.802947402],[223919.03467496697,6758615.435197377],[223955.40138909212,6758620.617028174],[223958.69393545468,6758608.135561782],[223920.80495575056,6758602.802947402]]]]},"properties":{"pk":552,"id_way":69935081,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223758.33348896416,6757973.09178141],[223771.29330178435,6757965.742570341],[223765.66278471035,6757955.599978879],[223752.5599116778,6757962.8286591815],[223758.33348896416,6757973.09178141]]]]},"properties":{"pk":553,"id_way":69935085,"height":13.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224095.56563745602,6757720.706627222],[224098.88989968144,6757711.914824181],[224089.6379129114,6757708.487668631],[224086.27743610254,6757717.195023484],[224095.56563745602,6757720.706627222]]]]},"properties":{"pk":554,"id_way":69935087,"height":10.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223995.15569451856,6758079.72826346],[224007.71811412406,6758083.004966303],[224011.13449477506,6758073.634294826],[223996.82477263446,6758069.477362522],[223993.35321535036,6758079.269566438],[223995.15569451856,6758079.72826346]]]]},"properties":{"pk":555,"id_way":69935113,"height":13.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223618.69523054332,6757351.255330574],[223617.74822578896,6757349.954747113],[223615.09067290975,6757351.853176023],[223615.9250846981,6757353.180457762],[223618.69523054332,6757351.255330574]]]]},"properties":{"pk":556,"id_way":69935117,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224201.06137871524,6757646.213294693],[224203.91440062464,6757645.847625386],[224203.2969113816,6757640.79316113],[224200.4176149501,6757641.19227068],[224201.06137871524,6757646.213294693]]]]},"properties":{"pk":557,"id_way":69935120,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223950.80499222537,6758504.187221987],[223956.89719949607,6758507.269765573],[223960.99835148713,6758499.242093483],[223954.73191170426,6758496.270746827],[223950.80499222537,6758504.187221987]]]]},"properties":{"pk":558,"id_way":69935144,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224026.43730719524,6757832.049125519],[224017.42577353574,6757828.780461498],[224016.1771022797,6757832.21325713],[224011.20867572125,6757830.462601532],[224008.74361649356,6757837.069766149],[224022.61044222876,6757842.35153061],[224026.43730719524,6757832.049125519]]]]},"properties":{"pk":559,"id_way":69935175,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223682.35184959226,6758442.994235282],[223682.1412120248,6758445.039604434],[223679.10730289048,6758444.725629886],[223677.89785827254,6758450.649072395],[223688.37106238076,6758451.748476849],[223689.22699389822,6758443.728037753],[223682.35184959226,6758442.994235282]]]]},"properties":{"pk":560,"id_way":69935203,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223908.2915381662,6758048.384784035],[223900.1987206616,6758052.977565469],[223910.66192422263,6758071.424495022],[223918.78485512515,6758066.840202578],[223912.95864608232,6758056.569300168],[223907.85773175053,6758059.488692458],[223906.01897643885,6758056.302229114],[223911.11564150895,6758053.315756358],[223908.2915381662,6758048.384784035]]]]},"properties":{"pk":561,"id_way":69935205,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223703.77469208717,6758327.593835432],[223701.5551149077,6758333.599782916],[223712.39875120684,6758337.66579937],[223714.5968654147,6758331.574040733],[223703.77469208717,6758327.593835432]]]]},"properties":{"pk":562,"id_way":69935238,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223592.88754684536,6757936.101483338],[223595.85865721977,6757936.960651056],[223596.22483891217,6757935.696692569],[223593.21589384013,6757934.986979894],[223592.88754684536,6757936.101483338]]]]},"properties":{"pk":563,"id_way":69935242,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223776.35193265675,6757812.347353895],[223776.24934070857,6757812.157696052],[223768.6308091075,6757816.466828081],[223771.89828872174,6757822.385499022],[223779.5723367699,6757818.115039071],[223776.35193265675,6757812.347353895]]]]},"properties":{"pk":564,"id_way":69935291,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223877.49840138378,6757684.506108004],[223872.52923943187,6757675.584441791],[223871.95432192265,6757675.055059217],[223871.28043106248,6757674.800747825],[223870.37110530815,6757674.734761111],[223869.58568013433,6757675.02298477],[223861.13206476686,6757680.919768831],[223868.35755187966,6757691.064736984],[223877.49840138378,6757684.506108004]]]]},"properties":{"pk":565,"id_way":69935293,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223962.56251402196,6758041.413663388],[223959.92365801585,6758048.516010593],[223967.25912055816,6758050.297218739],[223967.62261116435,6758048.562890431],[223977.94367792347,6758051.018424572],[223977.4974480788,6758046.132815871],[223962.56251402196,6758041.413663388]]]]},"properties":{"pk":566,"id_way":69935313,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223804.15386484723,6758150.321161329],[223805.28174539967,6758152.904329456],[223810.19456753685,6758150.74541507],[223809.07054716322,6758148.204772182],[223804.15386484723,6758150.321161329]]]]},"properties":{"pk":567,"id_way":69935314,"height":3.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223620.14945170205,6757300.501644022],[223616.1063966796,6757294.65542584],[223611.8533395453,6757297.64949642],[223616.79101317003,6757304.570255838],[223621.00724990174,6757301.687847621],[223620.14945170205,6757300.501644022]]]]},"properties":{"pk":568,"id_way":69935316,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223951.2622486025,6758373.6470163325],[223952.33281461342,6758373.326647756],[223953.39130324495,6758377.484213833],[223954.10193850065,6758377.326325708],[223954.8106177841,6758380.333574483],[223960.23927736678,6758379.077481062],[223959.35928553503,6758375.249441174],[223962.4149532132,6758374.467858472],[223961.16415100088,6758369.235022166],[223950.43787420072,6758370.264998762],[223951.2622486025,6758373.6470163325]]]]},"properties":{"pk":569,"id_way":69935335,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224188.37192990188,6757791.256266907],[224191.0169364838,6757783.78087617],[224186.7995203592,6757782.264366487],[224184.15078939934,6757789.697237666],[224188.37192990188,6757791.256266907]]]]},"properties":{"pk":570,"id_way":69935338,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223685.83955153293,6757760.901559286],[223678.53703518625,6757766.044346759],[223684.98326260858,6757775.249741813],[223692.97219127847,6757769.733340953],[223686.47407383297,6757760.404763161],[223685.83955153293,6757760.901559286]]]]},"properties":{"pk":571,"id_way":69935361,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223689.46856296065,6757307.27458668],[223694.1080578192,6757313.762878084],[223699.61300240137,6757309.853531959],[223694.96975494738,6757303.224597987],[223689.46856296065,6757307.27458668]]]]},"properties":{"pk":572,"id_way":69935363,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223783.6555217123,6757915.424409201],[223777.7248923126,6757918.750684599],[223779.45623751899,6757921.860816971],[223785.36229862773,6757918.492891584],[223783.6555217123,6757915.424409201]]]]},"properties":{"pk":573,"id_way":69935384,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223999.67692885437,6757631.845403257],[223990.634449224,6757636.554250112],[223994.26092130147,6757643.503574841],[223995.83225773496,6757642.752330539],[223998.10566242115,6757647.180828928],[224005.5715684575,6757643.333833833],[223999.67692885437,6757631.845403257]]]]},"properties":{"pk":574,"id_way":69935386,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223899.03974360874,6758175.362057534],[223882.74468691993,6758169.364356752],[223873.41846235958,6758171.536087176],[223876.01342234295,6758183.076829735],[223886.36777093384,6758180.625294739],[223889.35888436087,6758181.306307525],[223896.03968649873,6758183.536766251],[223899.03974360874,6758175.362057534]]]]},"properties":{"pk":575,"id_way":69935408,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224059.67313080883,6758391.64773349],[224054.5743523909,6758403.697012796],[224078.02647119339,6758413.616402382],[224084.25589801354,6758399.00081727],[224074.17730913,6758394.680058581],[224073.07266199248,6758397.287800502],[224059.67313080883,6758391.64773349]]]]},"properties":{"pk":576,"id_way":69935410,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223868.34110246992,6757852.857078987],[223871.4893686529,6757859.719273612],[223891.19927262343,6757850.869335805],[223887.95655943902,6757843.663880302],[223868.34110246992,6757852.857078987]]]]},"properties":{"pk":577,"id_way":69935412,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223926.96950616097,6757580.247743669],[223936.24310133644,6757575.814389744],[223932.68087997395,6757568.3133082185],[223940.0215609503,6757563.202826682],[223934.08440461586,6757554.626100501],[223919.55760914175,6757564.722873054],[223926.96950616097,6757580.247743669]]]]},"properties":{"pk":578,"id_way":69935414,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224064.34896566105,6757971.3823458385],[224061.85777350885,6757978.023372076],[224064.596748395,6757979.022384927],[224067.0261493935,6757972.343513427],[224064.34896566105,6757971.3823458385]]]]},"properties":{"pk":579,"id_way":69935435,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223963.24054672653,6757904.259352382],[223968.08348259627,6757891.17735892],[223959.867770479,6757888.189156866],[223954.96957144164,6757901.144964976],[223963.24054672653,6757904.259352382]]]]},"properties":{"pk":580,"id_way":69935459,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223886.07536564258,6757612.472618697],[223889.44533498265,6757617.29850368],[223891.80467195157,6757615.596023435],[223888.43100372175,6757610.823128552],[223886.07536564258,6757612.472618697]]]]},"properties":{"pk":581,"id_way":69935461,"height":3.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223966.88862823034,6758125.805420063],[223954.5598675559,6758121.6595917875],[223948.9100194399,6758136.525849144],[223946.9331331736,6758143.850166759],[223952.0477967094,6758145.687444631],[223955.8320372786,6758135.192317835],[223958.7418940255,6758136.292204182],[223954.840441018,6758146.7159217885],[223960.5650181624,6758148.785291775],[223962.0305263594,6758142.97353952],[223966.88862823034,6758125.805420063]]]]},"properties":{"pk":582,"id_way":69935481,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223734.485146648,6758026.979077457],[223727.1206280618,6758013.868018548],[223720.7432098388,6758017.551914066],[223728.05302022098,6758030.624138198],[223734.485146648,6758026.979077457]]]]},"properties":{"pk":583,"id_way":69935482,"height":13.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223526.53752960393,6757466.562467884],[223523.5945302407,6757468.390858372],[223526.32738676513,6757471.593704531],[223529.2656084251,6757469.702330258],[223526.53752960393,6757466.562467884]]]]},"properties":{"pk":584,"id_way":69935485,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223538.96718289395,6757904.989765668],[223547.96828079564,6757907.751805802],[223548.6095853562,6757908.85904014],[223549.6263509038,6757905.732674885],[223548.53870953564,6757904.261510259],[223549.99400685882,6757899.295696477],[223551.84005353006,6757897.896709194],[223554.98921870423,6757898.928397006],[223556.66766229275,6757896.768506921],[223542.57789312024,6757892.5898277685],[223538.96718289395,6757904.989765668]]]]},"properties":{"pk":585,"id_way":69935510,"height":12.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223556.12769520795,6757329.132623754],[223564.80413911128,6757322.948553686],[223556.85716310394,6757311.68565909],[223548.4190922794,6757318.528363663],[223551.25575075072,6757322.448003112],[223549.56287742802,6757323.75619084],[223553.76026405548,6757329.806543858],[223555.7187190395,6757328.591237408],[223556.12769520795,6757329.132623754]]]]},"properties":{"pk":586,"id_way":69935540,"height":16.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223805.96159199663,6758575.216745756],[223808.63871130993,6758575.998226786],[223810.36035198957,6758571.173835116],[223807.71157134624,6758570.473473294],[223805.96159199663,6758575.216745756]]]]},"properties":{"pk":587,"id_way":69935584,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223619.73122560902,6758144.564531848],[223625.0017891302,6758141.669751966],[223624.57097537766,6758140.894690835],[223619.3136135324,6758143.7475909125],[223619.73122560902,6758144.564531848]]]]},"properties":{"pk":588,"id_way":69935640,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223835.0115848074,6758103.722724164],[223829.7355055282,6758094.409167402],[223821.25275193588,6758099.189934399],[223826.5870965044,6758108.586150168],[223835.0115848074,6758103.722724164]]]]},"properties":{"pk":589,"id_way":69935641,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224039.15787055064,6757592.530421416],[224037.78206379316,6757590.092763982],[224032.73603873048,6757592.94597682],[224034.111572052,6757595.383788651],[224039.15787055064,6757592.530421416]]]]},"properties":{"pk":590,"id_way":69935649,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224116.6278366942,6757971.337383966],[224105.14519990765,6757967.013738396],[224106.07023322608,6757964.598683661],[224101.22809431457,6757962.800253425],[224100.30331448888,6757965.214543463],[224096.636442951,6757963.906200303],[224093.99218038644,6757971.294082274],[224113.89616995814,6757978.533728737],[224116.6278366942,6757971.337383966]]]]},"properties":{"pk":591,"id_way":69935692,"height":10.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223931.63746414642,6757743.577816844],[223930.9359562754,6757743.886187931],[223934.7214707881,6757753.712495116],[223939.20656607155,6757760.496886843],[223954.4911010188,6757750.023239886],[223945.38159282107,6757736.963775518],[223934.6259645209,6757742.106919506],[223939.51563698944,6757749.277291589],[223937.7440206863,6757749.78905146],[223937.24121480912,6757750.228699001],[223936.63969853803,6757751.382805086],[223932.67051627155,6757745.6676419815],[223931.63746414642,6757743.577816844]]]]},"properties":{"pk":592,"id_way":69935737,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223663.93732295782,6757313.192376966],[223673.5276111359,6757306.840552762],[223672.112325486,6757304.792890972],[223670.21354188802,6757306.216194849],[223664.15608183196,6757297.706575544],[223656.6149817221,6757302.9080671845],[223663.93732295782,6757313.192376966]]]]},"properties":{"pk":593,"id_way":69935742,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223603.90252608096,6758354.955721938],[223601.50411517432,6758368.787933967],[223608.71070408652,6758370.919013826],[223611.10579963546,6758356.164281359],[223603.90252608096,6758354.955721938]]]]},"properties":{"pk":594,"id_way":69935794,"height":6.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224237.77628421583,6758614.396259512],[224266.73262972198,6758628.311091623],[224272.08309201832,6758617.440913033],[224243.03624774012,6758603.521987896],[224237.77628421583,6758614.396259512]]]]},"properties":{"pk":595,"id_way":69935795,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223562.82157406796,6757889.127481622],[223561.20208584517,6757891.207425853],[223569.67305824193,6757905.854259041],[223577.5361832901,6757901.303780367],[223572.70942750957,6757893.057102667],[223568.3139067772,6757895.582667104],[223566.42519754817,6757895.13014003],[223562.82157406796,6757889.127481622]]]]},"properties":{"pk":596,"id_way":69935798,"height":10.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223733.55261810118,6758440.379953346],[223731.02821418145,6758448.162272382],[223733.13226138218,6758448.764892185],[223749.8622361806,6758449.032379882],[223750.83008047493,6758445.253394154],[223740.27375232842,6758442.249574685],[223740.1191111809,6758442.691096739],[223733.55261810118,6758440.379953346]]]]},"properties":{"pk":597,"id_way":69935859,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223676.0624690934,6757838.781691189],[223689.74245799912,6757829.173749399],[223683.59664453976,6757820.668298985],[223670.03597270176,6757830.288954054],[223676.0624690934,6757838.781691189]]]]},"properties":{"pk":598,"id_way":69935863,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223697.56940767303,6758208.896998115],[223692.84692277518,6758207.177259757],[223690.83403947946,6758212.675220695],[223695.55652086547,6758214.394957423],[223697.56940767303,6758208.896998115]]]]},"properties":{"pk":599,"id_way":69935897,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223870.67143220225,6758069.662732343],[223873.43958448333,6758074.551421977],[223879.3085519265,6758071.186917944],[223876.54394078342,6758066.341215341],[223870.67143220225,6758069.662732343]]]]},"properties":{"pk":600,"id_way":69935898,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224110.70136776823,6757473.202274273],[224113.79890976872,6757477.628096156],[224116.16243125687,6757475.97758697],[224113.1127630518,6757471.515711308],[224110.70136776823,6757473.202274273]]]]},"properties":{"pk":601,"id_way":69935903,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223771.91216361354,6757887.159795637],[223763.15177491092,6757892.964598348],[223773.05655300335,6757907.946605409],[223776.49687522004,6757906.033676929],[223773.16764304796,6757900.503341977],[223778.3858909231,6757896.929525583],[223771.91216361354,6757887.159795637]]]]},"properties":{"pk":602,"id_way":69935937,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224024.02887322375,6757716.98000664],[224020.7927168215,6757718.690201518],[224022.82550574752,6757722.741518673],[224026.14631522962,6757720.918256578],[224024.02887322375,6757716.98000664]]]]},"properties":{"pk":603,"id_way":69935969,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223594.89486755617,6757615.258187694],[223601.67584192724,6757610.497910537],[223592.74432628514,6757597.959646822],[223585.88557817586,6757602.770391195],[223594.89486755617,6757615.258187694]]]]},"properties":{"pk":604,"id_way":69935971,"height":10.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223838.5188834742,6758665.110870958],[223870.2322947063,6758669.580857491],[223873.89827511818,6758642.942764705],[223847.55364656475,6758632.852601329],[223836.76356630566,6758661.167016315],[223836.55577355676,6758662.585017643],[223837.06970408963,6758663.89464322],[223837.87238896327,6758664.81295809],[223838.5188834742,6758665.110870958]]]]},"properties":{"pk":605,"id_way":69935991,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223843.0135187853,6757933.1772051575],[223834.4309999773,6757917.656802433],[223827.43473382402,6757921.691885421],[223835.3681147191,6757936.314013521],[223836.02854712433,6757937.140946783],[223843.0135187853,6757933.1772051575]]]]},"properties":{"pk":606,"id_way":69935994,"height":13.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224037.5597847989,6757606.0558935655],[224042.98844108262,6757607.966054397],[224044.78665493222,6757602.727871846],[224038.52018826068,6757603.319749006],[224037.5597847989,6757606.0558935655]]]]},"properties":{"pk":607,"id_way":69935997,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223824.27534965205,6758178.168838505],[223824.87636862785,6758181.010387577],[223829.8236205407,6758178.353465102],[223829.27868919124,6758175.593920831],[223824.27534965205,6758178.168838505]]]]},"properties":{"pk":608,"id_way":69936018,"height":3.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223999.47079067485,6758028.454360649],[223999.30232152255,6758028.382999501],[223997.46063709637,6758034.298877408],[224002.95077217332,6758035.98846663],[224004.7105498949,6758030.28872564],[223999.47079067485,6758028.454360649]]]]},"properties":{"pk":609,"id_way":69936019,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224221.2461098065,6757638.418994737],[224218.3936846456,6757638.784578658],[224219.01406186458,6757643.87365144],[224221.86730729314,6757643.518423791],[224221.2461098065,6757638.418994737]]]]},"properties":{"pk":610,"id_way":69936023,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224022.00735880603,6758540.414919685],[224025.98286688657,6758532.586132816],[224015.7446163094,6758527.644561727],[224009.6676098939,6758527.282001679],[224009.3512831998,6758530.827552173],[224011.65308765287,6758535.244080181],[224022.00735880603,6758540.414919685]]]]},"properties":{"pk":611,"id_way":69936040,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223760.99155836695,6758414.064876019],[223759.1536481208,6758419.2682215],[223786.99000359126,6758429.166493132],[223794.7156495412,6758407.924292459],[223766.76957712133,6758397.712783482],[223763.86786827192,6758405.231588744],[223765.21882852257,6758408.008358875],[223774.56669564676,6758411.279856381],[223772.4242227033,6758417.048334567],[223774.16112026112,6758417.652021307],[223774.66149991134,6758416.307134244],[223777.24637595855,6758417.215660739],[223775.69380008776,6758421.70567814],[223771.10246255447,6758420.043711002],[223771.52062766443,6758418.705813],[223764.02973351238,6758415.998657627],[223764.29276637157,6758415.253030889],[223760.99155836695,6758414.064876019]]]]},"properties":{"pk":612,"id_way":69936063,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223797.30452692308,6757774.226971451],[223789.05942458904,6757759.614244043],[223780.54832966812,6757764.517900922],[223788.9431826794,6757779.052350205],[223797.30452692308,6757774.226971451]]]]},"properties":{"pk":613,"id_way":69936066,"height":9.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223524.6802540302,6757420.828654536],[223530.59081675773,6757429.096878303],[223583.22787622007,6757392.542484946],[223577.20658059343,6757384.193937183],[223555.9124583059,6757398.966744169],[223537.81526609193,6757373.931923662],[223527.57339959446,6757380.869237491],[223545.7347790469,6757406.063773084],[223524.6802540302,6757420.828654536]]]]},"properties":{"pk":614,"id_way":69936081,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223713.71482857305,6758443.3825442735],[223710.47956886567,6758454.606437264],[223716.29686606475,6758462.679031141],[223725.26457476648,6758462.766046497],[223725.367532605,6758455.903061843],[223719.82219966064,6758455.931288826],[223717.87106839748,6758453.3956837505],[223718.09293100273,6758452.657504014],[223716.11277167592,6758452.137872827],[223716.97077355967,6758449.154270035],[223719.42537033287,6758449.669457738],[223720.65783436486,6758445.3924519075],[223713.71482857305,6758443.3825442735]]]]},"properties":{"pk":615,"id_way":69936089,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223951.33234585894,6758033.615963005],[223950.4271089176,6758032.492324524],[223948.81018455734,6758031.643909568],[223948.0623691273,6758031.539339977],[223948.03777485705,6758031.696510069],[223943.21804474576,6758031.068757419],[223943.19100163775,6758030.912850654],[223942.1968036556,6758030.754041792],[223935.47622718522,6758029.932574722],[223933.48716192303,6758037.999116582],[223949.16718937087,6758042.518838995],[223949.56056283313,6758041.43444152],[223949.74585626152,6758041.522317661],[223950.01020386998,6758040.901485636],[223949.81024378238,6758040.862737592],[223951.54768969072,6758036.16604364],[223951.72563380838,6758036.206380927],[223951.9281759913,6758035.532933429],[223951.55214887747,6758033.957203245],[223951.33234585894,6758033.615963005]]]]},"properties":{"pk":616,"id_way":69936090,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223483.25403952436,6757554.556567075],[223493.95288095638,6757552.321066225],[223499.00271586957,6757575.088520685],[223516.54906095992,6757571.675700857],[223515.1778595871,6757565.353642671],[223511.44951285396,6757566.100651284],[223508.00297715067,6757550.577494528],[223515.02734727264,6757548.977162196],[223513.88247957968,6757546.619713801],[223508.9177723077,6757542.183272311],[223501.0559862741,6757551.564865489],[223495.99170982282,6757547.492038197],[223492.56579936176,6757548.255323477],[223491.33337289156,6757542.680256069],[223481.04148098148,6757544.868076896],[223483.25403952436,6757554.556567075]]]]},"properties":{"pk":617,"id_way":69936092,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223686.35124863905,6758358.612404616],[223668.15118547308,6758351.933833503],[223664.64284987928,6758366.4944564495],[223673.44658042828,6758368.6075444175],[223674.67330620383,6758363.178908784],[223683.53654532606,6758366.481435464],[223686.35124863905,6758358.612404616]]]]},"properties":{"pk":618,"id_way":69936114,"height":13.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224072.30213439075,6758636.383773537],[224086.08103924475,6758642.576456611],[224097.47062498363,6758617.078898096],[224103.95113661143,6758619.978025824],[224109.44103890678,6758607.739690139],[224103.86152773187,6758603.014285066],[224090.47134783305,6758597.020026754],[224092.13834933547,6758593.274167953],[224084.65385029587,6758589.943607793],[224084.98428230872,6758589.192022873],[224081.4294584678,6758587.591181208],[224076.241564734,6758599.091740713],[224081.52713870193,6758603.539350051],[224081.8969196442,6758603.700325832],[224082.2204211608,6758602.948423058],[224086.8742857476,6758605.056076827],[224082.50565063953,6758614.829420866],[224082.0351629468,6758614.588942173],[224072.30213439075,6758636.383773537]]]]},"properties":{"pk":619,"id_way":69936115,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223664.4857940044,6757874.819112055],[223662.7121630228,6757872.336935027],[223656.61619419866,6757876.628600697],[223658.39167346497,6757879.079801264],[223664.4857940044,6757874.819112055]]]]},"properties":{"pk":620,"id_way":69936117,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223498.8259115225,6757299.3949530125],[223485.34513717817,6757298.550454373],[223484.89702824963,6757307.003198412],[223498.5813609946,6757307.721240115],[223498.8259115225,6757299.3949530125]]]]},"properties":{"pk":621,"id_way":69936154,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223963.78703255684,6757958.0758028105],[223961.26740167628,6757964.8299596],[223975.13284526567,6757970.001861427],[223977.4530959739,6757963.857170712],[223978.67117097686,6757964.216442638],[223978.8685685554,6757963.716876699],[223963.78703255684,6757958.0758028105]]]]},"properties":{"pk":622,"id_way":69936163,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223663.81056786928,6758128.297126835],[223664.6184327112,6758126.482416677],[223669.2738394056,6758128.351765004],[223669.8631320208,6758128.807407611],[223670.17385398177,6758129.397042807],[223670.7547232372,6758133.033096804],[223668.9117979639,6758133.338363481],[223669.7652064408,6758140.105274251],[223679.21556261662,6758138.807129675],[223677.71106591568,6758128.580350094],[223677.86570839764,6758127.744288581],[223678.60580491764,6758126.888423729],[223682.58119310255,6758124.024394521],[223683.66707151284,6758125.483275114],[223691.72190653486,6758119.270270317],[223686.11164743922,6758112.021272178],[223675.233038795,6758120.331890334],[223674.64115980378,6758119.783620163],[223674.6389430416,6758120.647983057],[223674.38676169072,6758121.407386772],[223673.68669593646,6758121.834995038],[223672.8404004566,6758121.950336792],[223671.8414662206,6758121.666280866],[223671.31048369026,6758120.948375325],[223671.13879044264,6758120.074631201],[223670.9960680854,6758120.033168664],[223670.75873327692,6758120.95450549],[223661.5139210073,6758117.224925145],[223657.99058818226,6758125.913703782],[223663.81056786928,6758128.297126835]]]]},"properties":{"pk":623,"id_way":69936197,"height":24.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223908.4823752657,6758187.900193742],[223920.80793467088,6758192.451795684],[223925.23807802697,6758190.285699197],[223927.3928626298,6758184.265374461],[223911.8989632767,6758178.654591807],[223908.4823752657,6758187.900193742]]]]},"properties":{"pk":624,"id_way":69936200,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223913.19434967148,6757265.879053494],[223926.79247667364,6757256.2221517],[223921.20513350365,6757248.163140963],[223907.43236126166,6757257.854622889],[223913.19434967148,6757265.879053494]]]]},"properties":{"pk":625,"id_way":69936206,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223981.34420337863,6758464.050076696],[223987.92221813466,6758465.673635136],[223990.0538749598,6758457.3404789865],[223983.5013990829,6758455.639956206],[223981.34420337863,6758464.050076696]]]]},"properties":{"pk":626,"id_way":69936223,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224175.12162861598,6757961.219547318],[224177.92435774152,6757960.961141982],[224176.93578196922,6757951.317933376],[224178.18711832078,6757951.239378637],[224177.94161916102,6757948.196493591],[224176.60857044015,6757948.315106148],[224174.86898069186,6757932.701026463],[224176.29350238503,6757932.63088848],[224175.99288822978,6757929.431526615],[224174.4252405091,6757929.468903694],[224173.75584187466,6757922.7538519595],[224164.24454309762,6757923.783260868],[224164.73590248084,6757928.476774071],[224163.94199189698,6757928.596581632],[224164.72973481275,6757935.549837909],[224165.52847456277,6757935.474364978],[224166.77725437778,6757946.971855501],[224165.97507423087,6757947.092164109],[224166.74197938523,6757954.151260962],[224167.65571858943,6757953.999277871],[224168.41382828105,6757961.903531772],[224175.12162861598,6757961.219547318]]]]},"properties":{"pk":627,"id_way":69936227,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223920.38245204993,6757705.36505271],[223934.19241724326,6757698.374846795],[223923.13570968682,6757678.2743886495],[223920.8581096628,6757679.512676372],[223923.054421673,6757683.250987914],[223923.30409433204,6757683.094746091],[223923.53277475893,6757683.350468611],[223923.61543769573,6757686.208144024],[223916.77338961753,6757689.777771544],[223918.749469487,6757693.576387744],[223915.19608086578,6757695.379197089],[223920.38245204993,6757705.36505271]]]]},"properties":{"pk":628,"id_way":69936251,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223618.62384477208,6758403.496851567],[223643.8195937431,6758409.424507787],[223646.34263688247,6758398.877632259],[223621.61051243823,6758392.954619833],[223618.62384477208,6758403.496851567]]]]},"properties":{"pk":629,"id_way":69936275,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223792.95233081834,6757932.040049863],[223787.08077077926,6757935.361052993],[223788.81130260226,6757938.393816773],[223794.6282858994,6757935.0228289915],[223792.95233081834,6757932.040049863]]]]},"properties":{"pk":630,"id_way":69936276,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223920.15317990744,6757670.392199494],[223923.6678295645,6757677.765242771],[223942.95974164768,6757667.581663328],[223939.74165163437,6757660.836322588],[223920.15317990744,6757670.392199494]]]]},"properties":{"pk":631,"id_way":69936278,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223582.14370857688,6758290.690297124],[223579.75499421873,6758304.901361346],[223589.38447755825,6758306.471899113],[223591.80646079598,6758292.214499019],[223582.14370857688,6758290.690297124]]]]},"properties":{"pk":632,"id_way":69936300,"height":9.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224182.04962354474,6758536.499116901],[224200.29660308678,6758544.131882263],[224201.79765795122,6758540.599417601],[224192.74360917837,6758536.826630982],[224195.47963148856,6758530.397231462],[224191.93876349076,6758528.924323561],[224189.2039728601,6758535.364082634],[224183.43205796662,6758533.02186362],[224182.04962354474,6758536.499116901]]]]},"properties":{"pk":633,"id_way":69936301,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223609.07015975704,6757798.766305294],[223614.76973394206,6757806.670790526],[223625.96294225808,6757799.032554517],[223612.46844550082,6757779.80811611],[223600.77480019856,6757787.853489682],[223606.37144001853,6757795.858210662],[223606.93763783178,6757795.700750587],[223609.07015975704,6757798.766305294]]]]},"properties":{"pk":634,"id_way":69936303,"height":15.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224009.55476414,6757587.867946294],[223998.05190421178,6757593.694502276],[224001.20398274454,6757598.246283621],[224011.5433510269,6757592.591844003],[224009.55476414,6757587.867946294]]]]},"properties":{"pk":635,"id_way":69936305,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224088.99114220298,6757980.319258555],[224087.07091209976,6757985.5754288575],[224089.54254370104,6757986.505250125],[224091.44027344932,6757981.240149985],[224088.99114220298,6757980.319258555]]]]},"properties":{"pk":636,"id_way":69936326,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223739.59289331513,6758514.215013258],[223740.62954829415,6758504.619814642],[223736.71098387105,6758504.278683664],[223736.22719588617,6758508.899349434],[223731.06350854796,6758508.435706659],[223731.4243084797,6758503.7794725895],[223727.5968997538,6758503.388958166],[223726.6769885736,6758513.06243691],[223739.59289331513,6758514.215013258]]]]},"properties":{"pk":637,"id_way":69936347,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223973.53335025764,6757761.408818059],[223975.78491978682,6757766.268020557],[223987.54864959238,6757760.454732298],[223984.4557908862,6757753.884659611],[223973.53335025764,6757761.408818059]]]]},"properties":{"pk":638,"id_way":69936352,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223647.93900504036,6758099.79859747],[223638.5435278867,6758100.939481028],[223639.53417186014,6758107.336025386],[223641.3946435503,6758107.107682088],[223642.23625324195,6758112.3923539985],[223642.017929883,6758113.589402242],[223633.733265444,6758120.021272392],[223639.3413253612,6758127.335102368],[223644.51725675867,6758123.205642714],[223643.36520366982,6758121.693501003],[223645.97469979088,6758119.613875963],[223646.87480390596,6758119.249151056],[223647.50856041134,6758119.375761158],[223652.46209316014,6758121.443799601],[223651.74635632936,6758123.373445692],[223657.80541708667,6758125.838126861],[223661.32844279043,6758117.150105606],[223651.97868638625,6758113.3788855625],[223652.27166385838,6758112.425196419],[223651.2465212691,6758113.065340733],[223650.38053823597,6758112.941873822],[223649.7854440815,6758112.386866695],[223649.46750345128,6758111.839534145],[223649.49619591693,6758110.714104572],[223650.27743450494,6758109.782782059],[223650.20428112362,6758109.644991199],[223649.3103057368,6758109.879184256],[223647.93900504036,6758099.79859747]]]]},"properties":{"pk":639,"id_way":69936375,"height":24.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223772.7033857087,6758107.96944484],[223767.34024740753,6758110.9149230365],[223772.505395782,6758122.467442454],[223778.0131006907,6758120.026627624],[223772.7033857087,6758107.96944484]]]]},"properties":{"pk":640,"id_way":69936376,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223499.33855436766,6757512.666702712],[223502.43659733777,6757527.134761512],[223507.75961627203,6757526.005291833],[223507.49650722847,6757524.422996907],[223511.90646719397,6757523.409694401],[223509.688260138,6757512.775205644],[223506.78505343152,6757513.443719294],[223506.1740704612,6757510.997530585],[223499.33855436766,6757512.666702712]]]]},"properties":{"pk":641,"id_way":69936378,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223651.7699016691,6757905.6500934055],[223654.74893675037,6757903.561604966],[223652.35457912463,6757900.202910883],[223650.84540383975,6757901.2265585065],[223648.83316957837,6757898.538076311],[223647.570931562,6757899.452249624],[223651.7699016691,6757905.6500934055]]]]},"properties":{"pk":642,"id_way":69936401,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223960.37480275502,6757745.970962632],[223965.96641081487,6757742.141340655],[223961.07984836452,6757735.0973176295],[223954.97442872802,6757738.264718111],[223960.37480275502,6757745.970962632]]]]},"properties":{"pk":643,"id_way":69936428,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223824.0425601346,6758606.592446512],[223842.029676612,6758613.191108191],[223845.53197790936,6758604.016217314],[223803.93612926506,6758588.890528116],[223800.67406002493,6758598.043065545],[223824.0425601346,6758606.592446512]]]]},"properties":{"pk":644,"id_way":69936450,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223749.194046104,6757956.812544017],[223752.46205543223,6757962.654228165],[223771.41028708604,6757952.200606157],[223768.02245036748,6757946.09162556],[223749.194046104,6757956.812544017]]]]},"properties":{"pk":645,"id_way":69936453,"height":11.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224052.55539697356,6757634.562606383],[224034.0478836061,6757627.835940225],[224031.89800532986,6757633.914090424],[224050.18799560744,6757640.968048537],[224052.55539697356,6757634.562606383]]]]},"properties":{"pk":646,"id_way":69936455,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223651.59517024783,6758162.22336906],[223656.0925194996,6758166.66765057],[223657.78948178497,6758164.997537632],[223653.3747926055,6758160.502555179],[223651.59517024783,6758162.22336906]]]]},"properties":{"pk":647,"id_way":69936478,"height":3.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224040.268068703,6758073.33027929],[224042.12222292737,6758073.938157093],[224044.0670136345,6758069.350967961],[224043.24169362063,6758069.029817932],[224043.4809888969,6758068.364706419],[224042.5990211874,6758068.028784177],[224040.268068703,6758073.33027929]]]]},"properties":{"pk":648,"id_way":69936479,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223588.0724128428,6757333.461109659],[223597.12934124155,6757326.927332609],[223592.7002263328,6757321.033610339],[223583.78081211046,6757327.371169311],[223588.0724128428,6757333.461109659]]]]},"properties":{"pk":649,"id_way":69936482,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224188.4952704559,6757649.786940081],[224189.39434522265,6757647.205681499],[224196.1116919918,6757649.505606408],[224197.27666425673,6757646.013694184],[224182.83714567366,6757637.828151137],[224173.29615479114,6757664.180358855],[224182.10435548352,6757667.333454714],[224183.73113692735,6757662.970457739],[224184.32949130284,6757660.897438734],[224185.55078916662,6757661.336305003],[224186.55506038063,6757658.483833164],[224185.35511545895,6757658.039176855],[224185.85369994608,6757657.083789135],[224188.4952704559,6757649.786940081]]]]},"properties":{"pk":650,"id_way":69936486,"height":12.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223948.9004551621,6758550.867914765],[223942.45612902349,6758575.002358179],[223977.5687842445,6758584.262231226],[223983.93340469996,6758560.049075225],[223950.241014014,6758545.885373108],[223948.9004551621,6758550.867914765]]]]},"properties":{"pk":651,"id_way":69936505,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224114.6968612052,6757989.69663006],[224112.31138874826,6757988.814188661],[224110.35283770313,6757994.040278491],[224112.76698317353,6757994.92083841],[224114.6968612052,6757989.69663006]]]]},"properties":{"pk":652,"id_way":69936508,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223866.2103175168,6757762.854406247],[223874.62307923663,6757759.077455566],[223873.411122727,6757756.516898325],[223878.65559298563,6757753.766634581],[223874.2097318804,6757745.873039006],[223861.77852932195,6757752.981449278],[223866.2103175168,6757762.854406247]]]]},"properties":{"pk":653,"id_way":69936532,"height":10.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223598.35386528148,6757948.029012149],[223601.6087342473,6757936.8067309735],[223596.51296338043,6757935.351551277],[223593.33707775906,6757946.609080444],[223598.35386528148,6757948.029012149]]]]},"properties":{"pk":654,"id_way":69936560,"height":10.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223691.43587943373,6758472.4044366395],[223690.86232740263,6758471.472779359],[223689.87590521807,6758470.501588185],[223689.0688952717,6758470.044724397],[223687.76754554932,6758469.764325421],[223687.7425114348,6758469.366177535],[223653.34706079628,6758465.846530084],[223652.8064406495,6758470.695131877],[223649.67168567056,6758470.353064875],[223649.91113574515,6758468.381790814],[223648.12923677688,6758468.164851392],[223647.24959942547,6758476.063934743],[223650.86703079627,6758476.479614044],[223651.2923362897,6758472.532975554],[223652.583171445,6758472.6789606195],[223652.190179449,6758476.466058973],[223668.68511053052,6758478.154742871],[223668.62209333212,6758478.67200294],[223671.31876138286,6758478.930739039],[223671.35225914605,6758478.414375878],[223677.68845062706,6758479.078533293],[223678.56877001535,6758480.381849785],[223677.1773422398,6758485.259895054],[223688.0518779536,6758488.390426807],[223692.1677628025,6758473.9527642885],[223691.832118626,6758473.921746325],[223691.43587943373,6758472.4044366395]]]]},"properties":{"pk":655,"id_way":69936561,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224244.0518329666,6757247.781477144],[224244.4098699763,6757248.48911034],[224261.72201779461,6757242.085129328],[224262.4309310084,6757243.97793463],[224268.70095653267,6757241.610574374],[224264.73844991546,6757231.043202705],[224226.44204202268,6757245.424703807],[224225.66576269272,6757246.080404439],[224224.91477708187,6757247.35187699],[224224.73690599832,6757248.106235613],[224224.8509331535,6757249.342660195],[224225.2507944275,6757250.220948911],[224226.081868381,6757251.147584319],[224227.06732048615,6757251.6898228275],[224228.19373616428,6757251.956948067],[224229.07729755103,6757251.842634205],[224231.1226472291,6757250.978248499],[224231.59437218416,6757252.526808245],[224244.0518329666,6757247.781477144]]]]},"properties":{"pk":656,"id_way":69936565,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223689.2648907072,6758314.990701106],[223690.6898879595,6758311.3197751185],[223692.82725662625,6758312.099244058],[223692.26217945997,6758313.673175013],[223695.2149922758,6758314.796939685],[223697.67662213562,6758307.648669919],[223683.0470404006,6758302.181880591],[223679.51070092493,6758304.299997877],[223677.95505780197,6758310.877014002],[223689.2648907072,6758314.990701106]]]]},"properties":{"pk":657,"id_way":69936586,"height":12.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223600.77357512419,6757918.88877198],[223593.40444482418,6757906.166373528],[223584.184354656,6757911.494889198],[223591.78104315806,6757924.100001308],[223600.77357512419,6757918.88877198]]]]},"properties":{"pk":658,"id_way":69936590,"height":10.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223850.89816108238,6758624.052781976],[223860.33144551588,6758627.674919191],[223863.20377275377,6758620.399347384],[223853.68668569496,6758616.740994361],[223850.89816108238,6758624.052781976]]]]},"properties":{"pk":659,"id_way":69936642,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223757.93005106036,6757848.345790913],[223768.13217280136,6757842.426101484],[223765.59743720718,6757837.852328388],[223759.78327977817,6757841.146482436],[223760.4599821846,6757842.361595863],[223756.10606689012,6757844.887778204],[223757.93005106036,6757848.345790913]]]]},"properties":{"pk":660,"id_way":69936645,"height":8.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223836.3043701072,6757728.061479642],[223822.8777844119,6757734.116561086],[223826.36755798556,6757742.195358745],[223839.87747453494,6757736.254504653],[223836.3043701072,6757728.061479642]]]]},"properties":{"pk":661,"id_way":69936647,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223975.3378419566,6758091.018047175],[223976.79137328904,6758086.9551325245],[223975.87597780628,6758086.594848252],[223977.30276649716,6758082.491539896],[223976.4204585112,6758082.172872907],[223978.70313671403,6758075.5160883255],[223969.87539300727,6758073.808349835],[223963.80303177013,6758091.55081534],[223974.83245960952,6758095.5715063345],[223976.33934115412,6758091.416376045],[223975.3378419566,6758091.018047175]]]]},"properties":{"pk":662,"id_way":69936673,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223576.12408260777,6757301.323396974],[223572.19576828965,6757295.787788887],[223569.30300511327,6757292.068887826],[223562.31981343546,6757297.07959115],[223568.93314257372,6757306.405571297],[223576.12408260777,6757301.323396974]]]]},"properties":{"pk":663,"id_way":69936676,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223874.97889827885,6758447.987890941],[223877.67647699048,6758440.640573028],[223873.74250300936,6758439.208260425],[223874.5484138298,6758436.991514082],[223868.16566202318,6758434.637186304],[223866.4403689987,6758439.335175719],[223858.18399199637,6758436.323343456],[223856.40983958053,6758441.144586018],[223874.97889827885,6758447.987890941]]]]},"properties":{"pk":664,"id_way":69936695,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224136.67069215683,6757763.91531935],[224132.96158639548,6757774.106616871],[224146.35324256867,6757778.653626095],[224149.97641064145,6757768.777066035],[224136.67069215683,6757763.91531935]]]]},"properties":{"pk":665,"id_way":69936698,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223697.85834330475,6757751.663562989],[223705.7470671573,6757747.265096625],[223700.22873826692,6757737.3898362005],[223707.05267511008,6757733.449907645],[223699.27497101098,6757719.4768956695],[223685.89901836685,6757728.733102118],[223689.5560471833,6757733.938154938],[223688.6586692308,6757734.662827102],[223697.85834330475,6757751.663562989]]]]},"properties":{"pk":666,"id_way":69936723,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223661.53986701785,6757373.580001144],[223667.29472335408,6757381.604317266],[223711.59639534832,6757349.892234632],[223712.7501430996,6757351.515955513],[223717.44968633345,6757348.17437519],[223716.26570433786,6757346.542801758],[223720.84669479416,6757343.237853714],[223722.0305090193,6757344.85937186],[223726.7871916303,6757341.468305344],[223725.60394884337,6757339.847488357],[223730.21644993295,6757336.539669162],[223731.37028901096,6757338.163607641],[223733.8948486398,6757336.374793889],[223735.39578187247,6757335.08007831],[223737.03713342358,6757332.665192187],[223737.66011427747,6757330.982438206],[223737.9288616397,6757329.341263214],[223737.64776016423,6757326.3691494465],[223735.5700064053,6757325.369115548],[223734.28552465505,6757325.020943076],[223732.67284964252,6757324.864294256],[223730.99998002313,6757324.977305144],[223729.63077475218,6757325.319186826],[223728.1633677378,6757325.9451383585],[223661.53986701785,6757373.580001144]]]]},"properties":{"pk":667,"id_way":69936725,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223710.26908932088,6758008.525231893],[223705.1780230719,6757999.4914912665],[223689.608889619,6758008.91582624],[223694.70651083637,6758017.367489664],[223710.26908932088,6758008.525231893]]]]},"properties":{"pk":668,"id_way":69936745,"height":12.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223994.484888006,6757621.730277033],[223973.97552903616,6757632.258423013],[223981.13850376641,6757645.442208943],[223986.61948094267,6757642.699931569],[223982.7621166448,6757635.232406727],[223988.38584191058,6757632.304322147],[223990.54140852066,6757636.37720777],[223999.58561122883,6757631.667463626],[223994.484888006,6757621.730277033]]]]},"properties":{"pk":669,"id_way":69936748,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223856.93479707607,6758158.471639701],[223844.24295720688,6758161.285743474],[223846.81234269936,6758172.784318522],[223859.50415404487,6758169.970204155],[223856.93479707607,6758158.471639701]]]]},"properties":{"pk":670,"id_way":69936774,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224028.417493308,6758410.941012357],[224025.9679289014,6758409.907077892],[224025.49748749408,6758411.047600525],[224025.92078852555,6758411.2231371775],[224025.83529083148,6758411.463242997],[224027.30659461636,6758412.057924396],[224027.39875257396,6758411.813225428],[224027.8794979278,6758412.091763735],[224028.417493308,6758410.941012357]]]]},"properties":{"pk":671,"id_way":69936775,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223944.244241506,6757858.644262864],[223935.6311992248,6757853.557580957],[223934.4952501396,6757850.351411237],[223935.2667456288,6757850.07817971],[223929.91557841862,6757836.425315339],[223925.5128436356,6757838.085408137],[223930.66190043013,6757851.598611869],[223923.67161887223,6757854.624586491],[223925.444343619,6757858.615857814],[223924.3778059284,6757859.092012097],[223927.83045363508,6757866.836048464],[223936.52785332684,6757871.811101618],[223944.244241506,6757858.644262864]]]]},"properties":{"pk":672,"id_way":69936777,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223978.99081438867,6757523.234346819],[223988.32408059415,6757536.553123882],[223992.5163219426,6757533.595581728],[223991.1893539146,6757531.585952217],[223992.93492224743,6757530.32032447],[223985.08213152003,6757518.976377394],[223978.99081438867,6757523.234346819]]]]},"properties":{"pk":673,"id_way":69936779,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224056.33676559842,6758041.261152415],[224058.4681270393,6758035.366144591],[224053.53662622973,6758033.573584569],[224051.43168774506,6758039.34830472],[224056.33676559842,6758041.261152415]]]]},"properties":{"pk":674,"id_way":69936799,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223963.9649424619,6757883.123125524],[223968.99734889253,6757873.508292295],[223955.65892221066,6757866.776324726],[223949.95279545567,6757878.119780781],[223963.38397031924,6757884.261079358],[223963.9649424619,6757883.123125524]]]]},"properties":{"pk":675,"id_way":69936822,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223977.78438022296,6758108.840269396],[223969.59987331342,6758106.123296747],[223966.539572592,6758115.292788014],[223974.7784892939,6758118.048871989],[223977.78438022296,6758108.840269396]]]]},"properties":{"pk":676,"id_way":69936844,"height":10.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223543.566106632,6757566.483375562],[223542.3698695872,6757560.159027128],[223539.51682713587,6757560.70379242],[223540.76423479407,6757567.032726615],[223543.566106632,6757566.483375562]]]]},"properties":{"pk":677,"id_way":69936847,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223717.04292923815,6757872.36182178],[223708.71891073577,6757861.920187372],[223695.50940686223,6757871.380224985],[223703.24616435872,6757882.2536639245],[223717.04292923815,6757872.36182178]]]]},"properties":{"pk":678,"id_way":69936885,"height":16.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223556.24236762433,6757549.006251629],[223555.1687796237,6757543.164295418],[223552.31202176563,6757543.781136712],[223553.36005416684,6757549.5519773895],[223556.24236762433,6757549.006251629]]]]},"properties":{"pk":679,"id_way":69936939,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223869.6266814629,6758574.915578498],[223873.0504366467,6758575.984798898],[223872.81045718005,6758576.801625635],[223874.19420613078,6758577.150769122],[223874.45616513962,6758576.407437587],[223875.3916408906,6758576.612861506],[223874.7315074489,6758578.713219198],[223877.35213569488,6758579.488920637],[223877.68235397464,6758578.498368658],[223876.08564894355,6758578.01640519],[223876.37865555054,6758576.913633715],[223879.37271651425,6758577.7566120885],[223882.43139132025,6758569.7003470445],[223872.61922918903,6758567.038468172],[223869.6266814629,6758574.915578498]]]]},"properties":{"pk":680,"id_way":69936982,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223871.64138000645,6757302.494726966],[223878.23585124136,6757297.839720076],[223844.63439964602,6757250.26426886],[223837.8303731804,6757255.113298384],[223871.64138000645,6757302.494726966]]]]},"properties":{"pk":681,"id_way":69936994,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223804.1725716777,6758124.334711926],[223799.49113202933,6758126.375124016],[223800.59405575073,6758128.9169994285],[223805.27231841115,6758126.919548174],[223804.1725716777,6758124.334711926]]]]},"properties":{"pk":682,"id_way":69937051,"height":3.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223957.0192363073,6758183.064670088],[223951.15273420518,6758176.497341034],[223943.08976541334,6758183.769244987],[223949.03866478364,6758190.264525426],[223957.0192363073,6758183.064670088]]]]},"properties":{"pk":683,"id_way":69937053,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224036.5624064395,6757575.912096582],[224031.33807108094,6757578.849256138],[224032.57916108516,6757581.360284958],[224037.94497406404,6757578.349455752],[224036.5624064395,6757575.912096582]]]]},"properties":{"pk":684,"id_way":69937066,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224009.03533805837,6757978.7065392025],[224023.78273353938,6757983.767015226],[224031.54937104028,6757962.720591062],[224017.09999392886,6757957.221548009],[224016.98609698022,6757957.411959032],[224016.82431122282,6757957.373362637],[224015.906925647,6757959.804805336],[224016.1152340616,6757959.875940605],[224015.9748393956,6757960.262159936],[224009.03533805837,6757978.7065392025]]]]},"properties":{"pk":685,"id_way":69937113,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223918.60446172403,6757819.801701202],[223932.34593745094,6757814.524217116],[223929.5554335589,6757807.196093461],[223920.29607289485,6757810.854036972],[223916.10719490616,6757813.446118728],[223918.60446172403,6757819.801701202]]]]},"properties":{"pk":686,"id_way":69937196,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223707.6498487787,6757286.7373724785],[223706.28809509455,6757284.830348837],[223702.81558480262,6757287.2788016675],[223704.45046416082,6757289.2518446855],[223707.6498487787,6757286.7373724785]]]]},"properties":{"pk":687,"id_way":69937203,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223653.7935925549,6758367.61933046],[223657.54977950169,6758351.8449447965],[223654.92779119872,6758347.276324601],[223643.04436154693,6758342.766727693],[223639.72298844936,6758352.092739467],[223646.5775026673,6758354.700552065],[223644.0431702862,6758365.161021454],[223653.7935925549,6758367.61933046]]]]},"properties":{"pk":688,"id_way":69937315,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224307.34212358217,6758546.134249598],[224271.2809398655,6758619.551402375],[224283.20064703573,6758625.222087862],[224318.9958772404,6758551.758625414],[224307.34212358217,6758546.134249598]]]]},"properties":{"pk":689,"id_way":69937316,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223565.12274480783,6757922.462945602],[223551.42715885976,6757930.374560544],[223552.05082179132,6757935.106786105],[223558.7835975531,6757936.977876887],[223567.32301024703,6757932.088460368],[223566.7597247107,6757930.984540538],[223569.18826936258,6757929.6419829335],[223565.12274480783,6757922.462945602]]]]},"properties":{"pk":690,"id_way":69937322,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223840.2720002148,6758575.562543169],[223845.6876720671,6758577.076532932],[223844.82059851958,6758580.110407341],[223853.75386302132,6758582.490421455],[223859.77519898987,6758566.744714947],[223857.89917235292,6758563.266222738],[223844.5113280176,6758559.72445786],[223840.2720002148,6758575.562543169]]]]},"properties":{"pk":691,"id_way":69937469,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223615.7601443449,6758441.295436207],[223616.6169822196,6758432.139045898],[223608.47005506663,6758431.393453808],[223607.58058446337,6758440.508958172],[223615.7601443449,6758441.295436207]]]]},"properties":{"pk":692,"id_way":69937475,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223723.71934455013,6757819.534015272],[223723.82480393926,6757819.0885671],[223723.23142797285,6757817.992845286],[223714.4534033086,6757809.504370201],[223709.3870087332,6757812.836360321],[223717.04024208483,6757824.371294336],[223723.05679870342,6757820.417464027],[223723.71934455013,6757819.534015272]]]]},"properties":{"pk":693,"id_way":69937490,"height":13.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224070.86078998944,6758206.126929991],[224074.12347990824,6758193.334817385],[224056.47004744218,6758188.8056219425],[224054.7406105215,6758195.599803349],[224050.0200422807,6758194.3869500505],[224048.48718716385,6758200.396107756],[224070.86078998944,6758206.126929991]]]]},"properties":{"pk":694,"id_way":69937550,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223796.90709630755,6758134.029008862],[223798.03178507654,6758136.579590117],[223802.76892180863,6758134.458046324],[223801.6731835651,6758131.916109233],[223796.90709630755,6758134.029008862]]]]},"properties":{"pk":695,"id_way":69937552,"height":3.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224095.7347457296,6757471.635176098],[224080.6013582967,6757482.274064275],[224086.18559191338,6757490.222287658],[224101.3739706005,6757479.535224341],[224095.7347457296,6757471.635176098]]]]},"properties":{"pk":696,"id_way":69937560,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223739.79747524968,6757892.712950319],[223746.00311489578,6757888.608257089],[223740.8292707734,6757880.86334564],[223734.6567448816,6757884.921815872],[223739.79747524968,6757892.712950319]]]]},"properties":{"pk":697,"id_way":69937601,"height":8.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224017.64665618632,6757706.541975536],[224023.87357215653,6757703.287203363],[224022.3089774697,6757700.341496032],[224016.08549862544,6757703.477446021],[224017.64665618632,6757706.541975536]]]]},"properties":{"pk":698,"id_way":69937639,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223563.65595175544,6757556.0533208195],[223564.79360644752,6757562.373040379],[223567.58346416944,6757561.866491034],[223566.4788119934,6757555.502281757],[223563.65595175544,6757556.0533208195]]]]},"properties":{"pk":699,"id_way":69937644,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223913.09543002286,6757918.501731137],[223908.76653733078,6757910.7741772225],[223901.59425938057,6757914.846479444],[223905.92056053047,6757922.541580878],[223913.09543002286,6757918.501731137]]]]},"properties":{"pk":700,"id_way":69937686,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224046.91209256867,6757594.088032798],[224045.50862237232,6757591.6523692375],[224040.43441568658,6757594.421463946],[224041.81389796897,6757596.826619099],[224046.91209256867,6757594.088032798]]]]},"properties":{"pk":701,"id_way":69937690,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223643.6858251601,6758372.37202865],[223642.41848828204,6758377.519955492],[223650.92220237234,6758379.6228411365],[223652.1891893598,6758374.405778342],[223643.6858251601,6758372.37202865]]]]},"properties":{"pk":702,"id_way":69937729,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224044.3232154048,6758128.19346063],[224040.3915401981,6758140.27439097],[224048.8497030704,6758143.037058976],[224052.89137145333,6758131.034774199],[224044.3232154048,6758128.19346063]]]]},"properties":{"pk":703,"id_way":69937730,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224216.199984595,6757566.450216992],[224225.9210527768,6757564.923155391],[224225.07359733013,6757559.6289959],[224221.42345961925,6757560.18785774],[224221.5700250013,6757561.167267837],[224215.5006135531,6757562.147232955],[224216.199984595,6757566.450216992]]]]},"properties":{"pk":704,"id_way":69937737,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223994.87216264734,6758378.619743818],[224019.271086867,6758388.819778687],[224023.50988685084,6758378.779272856],[224019.57645493682,6758377.115922023],[224019.07019608936,6758378.2936200155],[224002.40356922973,6758371.271205747],[224002.99764923158,6758370.165447919],[223999.10376905903,6758368.579408689],[223994.87216264734,6758378.619743818]]]]},"properties":{"pk":705,"id_way":69937772,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224033.4224792966,6757884.206097846],[224036.42515617126,6757876.063785572],[224028.0610700375,6757872.999658437],[224025.06440712296,6757881.2177494345],[224033.4224792966,6757884.206097846]]]]},"properties":{"pk":706,"id_way":69937823,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223918.94321700602,6758004.503401887],[223924.33565502294,6758014.051749099],[223930.17754091028,6758010.733588601],[223924.72903699678,6758001.22255368],[223918.94321700602,6758004.503401887]]]]},"properties":{"pk":707,"id_way":69937866,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223714.77217685521,6758493.154040227],[223701.65451852532,6758492.006457355],[223700.58082464433,6758504.167087791],[223706.54008558652,6758504.635051489],[223707.41560313725,6758495.557220378],[223714.52097693787,6758496.15355326],[223714.77217685521,6758493.154040227]]]]},"properties":{"pk":708,"id_way":69937868,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224121.3969490355,6757472.277609243],[224123.78231811753,6757470.613854565],[224120.79142681044,6757466.158434357],[224118.32176045547,6757467.851106106],[224121.3969490355,6757472.277609243]]]]},"properties":{"pk":709,"id_way":69937874,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223810.23854354024,6758365.468197276],[223814.06789389392,6758354.642680723],[223814.15985750477,6758353.87383469],[223813.90480531313,6758352.329369215],[223813.1134179827,6758350.965766575],[223812.56855123382,6758350.390268641],[223810.86174834953,6758349.414485418],[223785.74189068648,6758340.158243955],[223780.45008671982,6758354.570496067],[223810.23854354024,6758365.468197276]]]]},"properties":{"pk":710,"id_way":69937910,"height":13.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223810.08393379927,6757917.511398488],[223805.37663805485,6757909.110753172],[223794.6096412966,6757915.113416638],[223799.40828444477,6757923.63833629],[223810.08393379927,6757917.511398488]]]]},"properties":{"pk":711,"id_way":69937916,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223609.19733605615,6757416.620384636],[223608.46260622924,6757414.570210641],[223606.81374383494,6757411.22610504],[223604.01648656,6757407.273903193],[223606.2729188429,6757405.662885228],[223601.75236041172,6757399.256065611],[223575.4701449058,6757417.895869581],[223591.06084614716,6757439.716226088],[223604.29871074253,6757430.266645826],[223603.83075162207,6757429.590995277],[223607.60369838457,6757426.899037819],[223609.73286876542,6757427.821962336],[223610.1536476788,6757425.861278141],[223610.27711276017,6757421.739522244],[223609.9280713782,6757419.458065433],[223609.19733605615,6757416.620384636]]]]},"properties":{"pk":712,"id_way":69937966,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223981.2488849565,6757957.32108703],[223980.09643913223,6757956.802136367],[223982.29623449262,6757950.9348007785],[223968.37460770144,6757945.800482152],[223965.99861415278,6757952.197774523],[223981.05189239225,6757957.809871597],[223981.2488849565,6757957.32108703]]]]},"properties":{"pk":713,"id_way":69938004,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223883.11024243583,6757629.448215022],[223885.59188501726,6757627.678848148],[223882.1003915787,6757622.815961693],[223879.6266121762,6757624.595145047],[223883.11024243583,6757629.448215022]]]]},"properties":{"pk":714,"id_way":69938008,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223904.47044679857,6758233.17252075],[223896.57125942563,6758254.426346525],[223906.88207869252,6758258.136786507],[223910.33719919354,6758248.986782569],[223918.64726482984,6758251.837782388],[223920.33629744363,6758247.255449995],[223913.64805036678,6758244.785102246],[223915.20132296998,6758240.835735049],[223911.40068095148,6758239.401915907],[223916.8285887942,6758236.83192995],[223912.91068511296,6758228.987167939],[223904.47044679857,6758233.17252075]]]]},"properties":{"pk":715,"id_way":69938047,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223606.14774283263,6758109.628866001],[223609.2690745744,6758115.313917348],[223611.9132958175,6758113.835411423],[223608.73439820137,6758108.155757906],[223606.14774283263,6758109.628866001]]]]},"properties":{"pk":716,"id_way":69938049,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223533.7912976656,6757450.228965002],[223532.37671520602,6757448.027156369],[223530.7261652591,6757446.282607653],[223528.38068968343,6757446.19948239],[223520.33868685004,6757447.739897454],[223522.0643168393,6757456.628739321],[223526.23894744812,6757455.749790632],[223533.7912976656,6757450.228965002]]]]},"properties":{"pk":717,"id_way":69938053,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223950.0396582117,6757357.693304354],[223945.28336833548,6757361.215700106],[223951.74959326774,6757370.387961837],[223991.25413950544,6757342.625257018],[223990.632805839,6757341.827679849],[223992.08752337645,6757340.822200216],[223991.52388793434,6757339.210203503],[223990.53215948245,6757337.771957544],[223989.66519339624,6757336.98915388],[223988.48515584838,6757336.325243672],[223989.46542696483,6757335.738292397],[223987.95667633868,6757333.609492744],[223964.71424424864,6757350.077109233],[223963.768957044,6757348.694691752],[223959.4694572303,6757351.849405296],[223933.77945109186,6757316.081895881],[223925.1857383972,6757303.858871557],[223958.31291985957,6757280.541624057],[223956.45334598832,6757279.5912161395],[223954.3141282784,6757278.956792576],[223950.96895916166,6757278.717781576],[223948.66630029044,6757279.074732218],[223946.47295767863,6757276.062436725],[223903.89017166593,6757306.04995287],[223904.70362282998,6757307.689832667],[223905.34477315567,6757308.39464547],[223906.4769723134,6757309.255730593],[223907.81682641336,6757309.79509031],[223909.23395782188,6757309.997264201],[223910.1638857323,6757309.922203675],[223912.1699515601,6757309.216123858],[223913.5649821818,6757309.012305047],[223915.23611923598,6757309.46082667],[223916.09055758792,6757310.079947864],[223916.863035239,6757311.112261026],[223917.83867572297,6757310.31876824],[223931.03102921144,6757328.863544753],[223930.66200282713,6757329.305166728],[223930.0821234887,6757330.694463907],[223930.01968798146,6757331.724896518],[223930.47713433488,6757332.911253606],[223931.35883166155,6757333.787060179],[223932.3309387483,6757334.173591591],[223933.33232836268,6757334.178796928],[223934.44377617582,6757333.618448658],[223950.9980196222,6757356.8810216775],[223950.0396582117,6757357.693304354]]]]},"properties":{"pk":718,"id_way":69938057,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224003.0395784198,6758441.442356245],[224021.43431012504,6758449.416144856],[224023.5310081235,6758444.50797649],[224018.2603587629,6758442.169013034],[224019.65914614743,6758438.925131318],[224011.73955871759,6758435.555441255],[224010.33998801533,6758438.788017052],[224005.07157007023,6758436.649858383],[224003.0395784198,6758441.442356245]]]]},"properties":{"pk":719,"id_way":69938090,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224086.7942190169,6757818.568223647],[224081.62011736902,6757832.59248543],[224096.90520736447,6757838.3181884],[224102.02079133195,6757824.210648407],[224086.7942190169,6757818.568223647]]]]},"properties":{"pk":720,"id_way":69938097,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223620.0289950662,6757774.572199401],[223612.63304249677,6757779.694492854],[223620.87056176757,6757791.4410351375],[223628.1830940587,6757786.391097536],[223620.0289950662,6757774.572199401]]]]},"properties":{"pk":721,"id_way":69938140,"height":12.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223718.65593204784,6758474.932422407],[223718.55105337553,6758486.345163237],[223731.31972629955,6758486.564942747],[223731.37002209533,6758475.112752903],[223718.65593204784,6758474.932422407]]]]},"properties":{"pk":722,"id_way":69938190,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223985.718745114,6757654.263821011],[223982.09377916137,6757656.353866777],[223984.46132933977,6757660.5564473625],[223979.57222650998,6757663.313858751],[223983.54331453392,6757670.2578510875],[223992.05711311713,6757665.474403501],[223985.718745114,6757654.263821011]]]]},"properties":{"pk":723,"id_way":69938193,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223694.5861065909,6758361.620234075],[223691.35498675742,6758370.47193489],[223701.25321347907,6758374.179935714],[223704.52523091642,6758365.292231096],[223694.5861065909,6758361.620234075]]]]},"properties":{"pk":724,"id_way":69938233,"height":9.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224088.17258431454,6758562.348068315],[224083.56629027083,6758571.398837072],[224094.3904793272,6758576.895384807],[224098.75794766162,6758567.809450837],[224088.17258431454,6758562.348068315]]]]},"properties":{"pk":725,"id_way":69938235,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223887.7988841612,6757882.726989952],[223879.9714813737,6757887.153348678],[223890.82258206714,6757906.037574357],[223898.4737498874,6757901.735602041],[223887.7988841612,6757882.726989952]]]]},"properties":{"pk":726,"id_way":69938238,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223942.963619069,6757589.963454337],[223936.32890396094,6757575.995050112],[223927.05567159306,6757580.428230593],[223933.7207275993,6757594.405055755],[223942.963619069,6757589.963454337]]]]},"properties":{"pk":727,"id_way":69938242,"height":13.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224084.02243731043,6757978.5348261595],[224082.15630643576,6757983.829222883],[224084.48179697146,6757984.6416865615],[224086.35092807794,6757979.378209923],[224084.02243731043,6757978.5348261595]]]]},"properties":{"pk":728,"id_way":69938279,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223994.46061086803,6757828.998932299],[223981.26909702798,6757821.29505908],[223970.19115695806,6757840.247583756],[223983.44536465633,6757847.95926532],[223994.46061086803,6757828.998932299]]]]},"properties":{"pk":729,"id_way":69938323,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223572.60520202862,6758120.337655171],[223581.53534199743,6758115.273693164],[223580.9991754717,6758114.205265578],[223582.2144258269,6758113.461866885],[223579.88109316202,6758109.156198973],[223585.83322538223,6758105.702703472],[223588.31484130357,6758110.09356745],[223589.76239569497,6758109.230349177],[223590.38303102984,6758110.296379581],[223595.1319790804,6758107.567748915],[223587.17941504886,6758093.421830487],[223564.6750357568,6758106.190527414],[223572.60520202862,6758120.337655171]]]]},"properties":{"pk":730,"id_way":69938363,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223763.66434750558,6758126.625185726],[223754.53840290487,6758130.6731292],[223757.28649098304,6758136.938092493],[223780.81334210926,6758126.399976989],[223778.09362781138,6758120.209700528],[223763.66434750558,6758126.625185726]]]]},"properties":{"pk":731,"id_way":69938365,"height":7.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223536.4965090299,6757496.16176157],[223538.49032421928,6757504.853683854],[223542.55404276296,6757504.185058746],[223540.43301097117,6757493.756121542],[223536.4965090299,6757496.16176157]]]]},"properties":{"pk":732,"id_way":69938369,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223990.9974598015,6757261.355129482],[224016.5298806846,6757243.529020395],[224008.76398806804,6757232.579389511],[223979.86978096826,6757252.6998336045],[223987.5779879683,6757263.655828762],[223990.9974598015,6757261.355129482]]]]},"properties":{"pk":733,"id_way":69938372,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223606.03796120457,6757884.466155491],[223607.52247987982,6757883.747916175],[223609.10974603798,6757877.966071678],[223605.93537278657,6757874.837430308],[223603.49460216827,6757875.1558160735],[223607.34779567795,6757878.933801867],[223606.03796120457,6757884.466155491]]]]},"properties":{"pk":734,"id_way":69938414,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223938.63987759055,6757728.513381583],[223946.81259151257,6757724.277861126],[223938.82404062996,6757710.923139195],[223931.46837050215,6757714.609619002],[223938.63987759055,6757728.513381583]]]]},"properties":{"pk":735,"id_way":69938458,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223804.15701023725,6758588.766646193],[223806.89670702995,6758589.775937705],[223808.49476572647,6758585.148618564],[223805.81320012655,6758584.145698019],[223804.15701023725,6758588.766646193]]]]},"properties":{"pk":736,"id_way":69938518,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223766.29480084518,6757946.83387516],[223767.92238869148,6757945.918440653],[223762.68287152343,6757936.558408528],[223761.08182182457,6757937.482351386],[223766.29480084518,6757946.83387516]]]]},"properties":{"pk":737,"id_way":69938522,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224032.70679413754,6757619.902108908],[224038.2258330862,6757621.903344259],[224039.05877641935,6757619.412285809],[224033.56067317902,6757617.409035356],[224032.70679413754,6757619.902108908]]]]},"properties":{"pk":738,"id_way":69938529,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223642.18942413546,6758154.691998532],[223643.38486903624,6758156.776876318],[223648.72827551074,6758153.688921643],[223647.55373077426,6758151.602754174],[223642.18942413546,6758154.691998532]]]]},"properties":{"pk":739,"id_way":69938572,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224080.70138370307,6758041.725947512],[224077.67421240822,6758050.136371756],[224094.0869515363,6758056.151485857],[224097.08403682226,6758047.73262019],[224080.70138370307,6758041.725947512]]]]},"properties":{"pk":740,"id_way":69938575,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224135.73820075786,6757455.712138614],[224133.4115313234,6757457.336587997],[224136.42747742598,6757461.678966036],[224138.72561364446,6757460.057210654],[224135.73820075786,6757455.712138614]]]]},"properties":{"pk":741,"id_way":69938582,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223927.7210747972,6758529.87621668],[223924.8432815645,6758535.613296888],[223936.19558979972,6758540.103491904],[223938.60013839917,6758535.380189974],[223927.7210747972,6758529.87621668]]]]},"properties":{"pk":742,"id_way":69938619,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224066.6436234729,6757880.512649033],[224061.29703985393,6757878.510653462],[224060.2981416759,6757881.208488444],[224065.58588176622,6757883.280267979],[224066.6436234729,6757880.512649033]]]]},"properties":{"pk":743,"id_way":69938626,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223535.03257616976,6758581.737572225],[223533.06678247952,6758581.017752634],[223530.26317457392,6758588.8301347755],[223565.77266390796,6758601.534614954],[223564.64197381266,6758604.379250925],[223602.95325945946,6758618.0879207635],[223604.61988864336,6758613.594744801],[223611.6613969243,6758616.126967218],[223611.54955747217,6758616.837518328],[223611.7998281808,6758617.548175284],[223612.63308466872,6758618.145016951],[223613.59582093116,6758618.033861626],[223614.17971788888,6758617.545515627],[223614.38723972198,6758617.088639196],[223683.94915843857,6758642.4958698815],[223694.57516212427,6758646.148113163],[223689.52016778933,6758659.836601876],[223701.6945239115,6758663.088273499],[223706.30707931353,6758650.361006808],[223702.54900739854,6758648.970184524],[223704.43327540127,6758643.809781054],[223708.1575495581,6758645.158616925],[223721.99226522932,6758607.338239572],[223718.3288256938,6758605.985004835],[223720.26295952263,6758600.4450148195],[223723.8797618161,6758601.03310294],[223723.78969374613,6758601.583636828],[223724.53926671654,6758601.682728106],[223724.77058943117,6758600.668745932],[223724.27431289203,6758600.510240255],[223726.0390893469,6758589.786373247],[223726.542905739,6758589.868676812],[223726.80717021672,6758588.36949208],[223725.99785800814,6758588.237469332],[223725.69728469526,6758589.82326517],[223686.6894332684,6758583.064795459],[223685.97086035096,6758587.292555391],[223652.37810734578,6758581.191732555],[223653.15849265232,6758577.6401241],[223613.39908539812,6758570.5628094515],[223613.67536732217,6758569.426184915],[223550.52953167752,6758558.42788376],[223550.05560548094,6758561.118311647],[223539.190716976,6758559.320776873],[223537.44803476505,6758568.932101327],[223543.55769776754,6758569.954056899],[223541.58516295347,6758581.92166077],[223535.03257616976,6758581.737572225]]]]},"properties":{"pk":744,"id_way":69938675,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223860.3667127835,6757805.102683489],[223857.6844437202,6757806.989889153],[223859.07454430277,6757809.043619007],[223861.7628403917,6757807.145526506],[223860.3667127835,6757805.102683489]]]]},"properties":{"pk":745,"id_way":69938680,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223567.87981616985,6757933.20494366],[223567.27144273705,6757935.413264228],[223568.53640786547,6757935.72704991],[223569.1651935113,6757933.585555809],[223567.87981616985,6757933.20494366]]]]},"properties":{"pk":746,"id_way":69938786,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223764.15571133816,6758427.025577342],[223758.4823792824,6758425.022160592],[223756.85737294675,6758429.340661724],[223762.43626115212,6758431.261956305],[223763.51055006435,6758428.400333456],[223763.68563130547,6758428.483683802],[223764.15571133816,6758427.025577342]]]]},"properties":{"pk":747,"id_way":69938879,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223742.48548032925,6757842.900193019],[223734.074219705,6757830.106696435],[223733.48024326414,6757829.7781414315],[223732.33125904953,6757830.041821332],[223721.15466081264,6757837.345750765],[223730.16503383097,6757850.977580371],[223742.48548032925,6757842.900193019]]]]},"properties":{"pk":748,"id_way":69938886,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223854.59169696076,6757610.166340588],[223811.34756598272,6757640.41955532],[223839.60752573007,6757680.244221383],[223882.49916239167,6757649.708711242],[223875.73163597993,6757640.138932866],[223870.1560976524,6757644.077562749],[223864.15955690097,6757635.728516865],[223861.7576849853,6757635.340229127],[223851.25622287465,6757642.78114637],[223856.12362564265,6757649.537702983],[223855.8127994099,6757651.516309264],[223849.0661901191,6757656.367517333],[223850.36658187606,6757658.224594675],[223842.58454237756,6757663.782030781],[223830.83146771634,6757647.317232342],[223833.74397816398,6757645.108537183],[223831.0211505535,6757641.201320712],[223861.29643473306,6757619.686815962],[223854.59169696076,6757610.166340588]]]]},"properties":{"pk":749,"id_way":69938891,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223745.70089973713,6758236.038033284],[223733.12114064445,6758270.234435715],[223742.22918233814,6758273.737140347],[223744.92791189402,6758266.498983571],[223743.23355639365,6758265.821624833],[223744.2615511965,6758263.152227519],[223745.85742710126,6758263.747491654],[223751.11622833973,6758249.7566043325],[223749.51900184932,6758249.082194052],[223750.6283992272,6758246.299281823],[223752.1039061361,6758246.814541045],[223754.83498923277,6758239.505592577],[223745.70089973713,6758236.038033284]]]]},"properties":{"pk":750,"id_way":69938945,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223887.2048353812,6758045.245458242],[223884.3818054251,6758040.238882208],[223881.91781118728,6758041.645830988],[223884.71146483137,6758046.644666764],[223887.2048353812,6758045.245458242]]]]},"properties":{"pk":751,"id_way":69938947,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223526.94683741292,6757288.437094546],[223540.0108819978,6757289.281059846],[223540.79251533007,6757278.581940016],[223528.9116042533,6757277.853647035],[223528.3895699193,6757286.743254484],[223527.0837391904,6757286.703645404],[223526.94683741292,6757288.437094546]]]]},"properties":{"pk":752,"id_way":69938951,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224165.18229744295,6757449.071152929],[224155.39679130728,6757450.636351057],[224157.0027956949,6757460.404771998],[224166.75931561095,6757458.754505866],[224165.18229744295,6757449.071152929]]]]},"properties":{"pk":753,"id_way":69938953,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224052.04325885884,6757752.2618331],[224049.64102721566,6757759.0160120865],[224052.2044416148,6757759.899000856],[224054.57777887478,6757753.146692288],[224052.04325885884,6757752.2618331]]]]},"properties":{"pk":754,"id_way":69938991,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223902.6405017245,6757812.480947669],[223897.3173197149,6757804.225293217],[223887.6599280777,6757810.621900662],[223892.50723205853,6757821.523310519],[223901.3404965859,6757817.314411759],[223900.01458667952,6757814.246114427],[223902.6405017245,6757812.480947669]]]]},"properties":{"pk":755,"id_way":69939046,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223631.7187280854,6757321.027305934],[223621.03098053465,6757328.708531893],[223624.10323010982,6757332.938312286],[223634.84915036676,6757325.41654814],[223631.7187280854,6757321.027305934]]]]},"properties":{"pk":756,"id_way":69939051,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223687.95308044422,6758047.918880318],[223694.97569868347,6758060.494714432],[223702.03461204897,6758056.618138093],[223689.9797634121,6758035.047216364],[223679.74587404839,6758040.849336314],[223684.80989444352,6758049.689171354],[223687.95308044422,6758047.918880318]]]]},"properties":{"pk":757,"id_way":69939114,"height":10.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223888.59503363978,6757610.708692111],[223891.9670849183,6757615.479299413],[223894.38453949837,6757613.748804125],[223891.04321414084,6757609.006916142],[223888.59503363978,6757610.708692111]]]]},"properties":{"pk":758,"id_way":69939118,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223842.14926137545,6758236.036217429],[223864.18536120505,6758244.026906584],[223871.34572392996,6758223.592659422],[223868.8499179317,6758212.2951152185],[223847.7480731371,6758216.792680278],[223848.2870309072,6758219.130061467],[223846.21247270232,6758224.884963324],[223852.48460893438,6758225.732604419],[223852.5548442594,6758222.430286732],[223853.50190464864,6758222.431812162],[223853.5674796305,6758218.952889706],[223854.6010785561,6758219.025235608],[223854.6001598963,6758218.860922612],[223860.14408059683,6758217.768244042],[223860.69724104306,6758220.528571247],[223862.1756837211,6758220.175649057],[223862.42119701533,6758221.183489872],[223861.77058045682,6758221.480104046],[223861.4527897218,6758221.83842908],[223861.27803004955,6758222.973583392],[223861.61053581425,6758223.867605009],[223862.1159320046,6758224.288747697],[223861.92782814224,6758225.256997384],[223860.4611379648,6758224.688186741],[223858.14661650156,6758231.20439738],[223845.56893744206,6758226.635073385],[223842.14926137545,6758236.036217429]]]]},"properties":{"pk":759,"id_way":69939164,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224015.530321983,6758426.132738425],[224023.87296365382,6758429.712890936],[224030.75090371343,6758413.627716203],[224027.50269591672,6758412.104712687],[224027.42119273724,6758412.31983076],[224025.582255999,6758411.576557017],[224025.66863876028,6758411.33502242],[224022.3888412507,6758410.094981564],[224015.530321983,6758426.132738425]]]]},"properties":{"pk":760,"id_way":69939167,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224060.13503080234,6757507.129413751],[224060.92931830787,6757506.667614298],[224057.7115300493,6757502.283259139],[224049.4184917747,6757507.054349063],[224052.1641184495,6757511.764496736],[224060.13503080234,6757507.129413751]]]]},"properties":{"pk":761,"id_way":69939176,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224037.3190417466,6757927.336166584],[224045.4481551227,6757930.36290721],[224048.94906985725,6757921.044479204],[224040.79240374692,6757918.0522142425],[224037.3190417466,6757927.336166584]]]]},"properties":{"pk":762,"id_way":69939220,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223800.58328809676,6757834.511461413],[223796.77347660615,6757828.910085089],[223792.41344119664,6757831.331379222],[223795.84588260567,6757836.818489565],[223796.50677020496,6757836.461686122],[223796.59458743007,6757836.62287106],[223800.58328809676,6757834.511461413]]]]},"properties":{"pk":763,"id_way":69939264,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223928.99112623165,6758093.814140531],[223914.70117741314,6758088.6295982655],[223912.25293263546,6758084.413942111],[223894.76104126673,6758094.280297163],[223905.3696501058,6758112.628348729],[223920.06646058985,6758118.171720142],[223928.99112623165,6758093.814140531]]]]},"properties":{"pk":764,"id_way":69939319,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223531.49418630428,6757641.150209735],[223540.45656782086,6757653.697013616],[223551.7964932314,6757645.627266236],[223542.81293310237,6757633.093137489],[223531.49418630428,6757641.150209735]]]]},"properties":{"pk":765,"id_way":69939325,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224102.39851157708,6758623.932647228],[224094.16989377447,6758642.353024088],[224109.22898358238,6758648.9362753285],[224123.3895497615,6758619.464970586],[224109.6000991631,6758607.873758418],[224102.39851157708,6758623.932647228]]]]},"properties":{"pk":766,"id_way":69939377,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223696.36285277543,6757895.157512909],[223680.03797221748,6757906.897030793],[223691.55830104294,6757924.842249915],[223709.0628941738,6757913.139728175],[223696.36285277543,6757895.157512909]]]]},"properties":{"pk":767,"id_way":69939381,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223627.98998958064,6757519.655711202],[223624.50488329187,6757514.714336295],[223617.16365951413,6757519.799910404],[223620.6485138304,6757524.817056781],[223627.98998958064,6757519.655711202]]]]},"properties":{"pk":768,"id_way":69939431,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223763.1022616048,6758495.2385257585],[223768.71733326055,6758479.7580429595],[223765.90811122235,6758475.616173985],[223750.6381269733,6758475.381390805],[223750.40987235744,6758486.356819714],[223754.32736574757,6758486.366869935],[223751.25949714228,6758495.285910095],[223763.1022616048,6758495.2385257585]]]]},"properties":{"pk":769,"id_way":69939469,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223565.51710178622,6758390.271046552],[223564.38603922166,6758397.067595209],[223576.97225555818,6758399.145661605],[223578.04874915068,6758392.396848177],[223565.51710178622,6758390.271046552]]]]},"properties":{"pk":770,"id_way":69939473,"height":6.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223874.1075783443,6757242.823972634],[223867.34964065824,6757247.582648595],[223864.06988905856,6757242.9985621255],[223858.3635556022,6757247.013735705],[223864.06316182748,6757255.086391431],[223876.5637230588,6757246.29840788],[223874.1075783443,6757242.823972634]]]]},"properties":{"pk":771,"id_way":69939480,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223942.21916831678,6758196.376525877],[223948.88993679715,6758190.398254081],[223942.94110994975,6758183.9030528255],[223936.38106447438,6758189.796101408],[223942.21916831678,6758196.376525877]]]]},"properties":{"pk":772,"id_way":69939522,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223566.8575996032,6758136.770580944],[223563.85856832977,6758131.376492806],[223561.57388894772,6758132.658652824],[223564.60161520564,6758138.049963891],[223566.8575996032,6758136.770580944]]]]},"properties":{"pk":773,"id_way":69939523,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224110.56122480196,6757579.944500025],[224115.1331814158,6757583.767873377],[224122.3289167044,6757575.7132622525],[224118.12015627368,6757572.2593164425],[224113.69404730015,6757568.974891444],[224109.1760961676,6757565.988683592],[224108.9961474789,6757566.345720709],[224105.58998073736,6757564.243555525],[224100.48966711308,6757573.3378360495],[224105.616267709,6757576.414423949],[224110.56122480196,6757579.944500025]]]]},"properties":{"pk":774,"id_way":69939532,"height":18.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224020.93086823355,6757945.32674247],[224021.81355920163,6757942.9855469],[224019.00859737673,6757941.947136433],[224018.101991922,6757944.248658833],[224020.93086823355,6757945.32674247]]]]},"properties":{"pk":775,"id_way":69939612,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223901.13159704334,6757784.828585958],[223909.9365332924,6757776.622509359],[223903.2532172558,6757768.96841027],[223893.3559991671,6757774.632844729],[223901.13159704334,6757784.828585958]]]]},"properties":{"pk":776,"id_way":69939656,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223652.1799745618,6757278.76109251],[223647.88854508367,6757272.5157222375],[223639.3372532628,6757278.6201491095],[223643.71074712905,6757284.793660359],[223652.1799745618,6757278.76109251]]]]},"properties":{"pk":777,"id_way":69939660,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223646.0297805706,6758443.894020925],[223646.08571590908,6758445.034196748],[223646.711800513,6758446.3778804485],[223647.60481631508,6758447.185615487],[223648.40133215275,6758447.529914527],[223666.08284351052,6758449.41321221],[223667.05409451734,6758440.69260623],[223656.28497086116,6758439.573409876],[223647.55201315283,6758437.564863591],[223646.0297805706,6758443.894020925]]]]},"properties":{"pk":778,"id_way":69939700,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223557.4713216775,6757557.265996254],[223554.58650671705,6757557.812195815],[223555.61060137686,6757564.171957407],[223558.55090519722,6757563.5897195265],[223557.4713216775,6757557.265996254]]]]},"properties":{"pk":779,"id_way":69939704,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223664.8363861556,6758322.208307166],[223667.65416087577,6758310.401029687],[223659.73736649228,6758308.505615476],[223658.9360757626,6758311.700963798],[223657.36650084067,6758311.337564843],[223655.2945115438,6758319.910522186],[223664.8363861556,6758322.208307166]]]]},"properties":{"pk":780,"id_way":69939749,"height":12.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223559.28188129305,6757870.602533602],[223549.8216672509,6757867.793936059],[223546.27163036843,6757879.998191563],[223555.84594028734,6757882.7646404095],[223559.28188129305,6757870.602533602]]]]},"properties":{"pk":781,"id_way":69939757,"height":15.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224152.5061547661,6757720.815556454],[224145.8244996452,6757738.984134647],[224153.67961230568,6757741.811495746],[224156.35866349415,6757734.191693674],[224157.6958052322,6757734.709213394],[224158.75363244524,6757731.929027136],[224157.4508808284,6757731.421682666],[224160.27645297628,6757723.68245353],[224152.5061547661,6757720.815556454]]]]},"properties":{"pk":782,"id_way":69939762,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224114.45136652,6757998.953822858],[224115.45531094004,6757996.101933657],[224110.28493511735,6757994.228399967],[224109.28324566747,6757997.112209423],[224114.45136652,6757998.953822858]]]]},"properties":{"pk":783,"id_way":69939815,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223739.02442935793,6758561.141779341],[223749.27916103808,6758533.116627519],[223741.9515325925,6758532.2076617675],[223738.4149272016,6758532.046047268],[223730.82887484605,6758552.904104301],[223732.61625249902,6758553.222762508],[223731.53570742536,6758559.852550348],[223739.02442935793,6758561.141779341]]]]},"properties":{"pk":784,"id_way":69939865,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223595.66184826795,6758402.851003308],[223594.26105177787,6758411.140461958],[223602.5841967674,6758412.547803558],[223603.965741519,6758404.292569183],[223595.66184826795,6758402.851003308]]]]},"properties":{"pk":785,"id_way":69939869,"height":10.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224009.01089064725,6757878.941960015],[224011.411871933,6757872.497836934],[223997.51269426016,6757867.372446452],[223995.1106699315,6757873.816186188],[224009.01089064725,6757878.941960015]]]]},"properties":{"pk":786,"id_way":69939871,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224024.97804524473,6758188.062287345],[224025.01200377304,6758187.94327136],[224023.75617601772,6758187.59200705],[224023.7183056175,6758187.75697874],[224024.97804524473,6758188.062287345]]]]},"properties":{"pk":787,"id_way":69939923,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223799.2804879141,6758113.181648607],[223794.663491876,6758115.1948783565],[223795.792157468,6758117.855466138],[223800.4063112668,6758115.810395673],[223799.2804879141,6758113.181648607]]]]},"properties":{"pk":788,"id_way":69939924,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223506.47852858095,6757539.492386146],[223508.9759846921,6757541.967073321],[223514.0451079746,6757546.496786715],[223515.38076257685,6757549.28557539],[223519.68453858138,6757548.261777755],[223519.2007984526,6757542.54879225],[223518.45764941475,6757537.000657202],[223506.47852858095,6757539.492386146]]]]},"properties":{"pk":789,"id_way":69939929,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224080.43774162486,6757482.38908422],[224062.9579596393,6757494.676686041],[224068.60167587182,6757502.543239533],[224086.021911485,6757490.337216856],[224080.43774162486,6757482.38908422]]]]},"properties":{"pk":790,"id_way":69939934,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223735.6190053237,6757871.165745795],[223731.80348124486,6757865.362794375],[223721.82723200353,6757871.900752739],[223725.82019172193,6757877.63559878],[223735.6190053237,6757871.165745795]]]]},"properties":{"pk":791,"id_way":69939978,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223998.5695028753,6757730.010162497],[224014.53775085637,6757722.46093183],[224011.20101610394,6757715.4484487055],[223995.14128965535,6757722.872716614],[223998.5695028753,6757730.010162497]]]]},"properties":{"pk":792,"id_way":69940030,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223572.6004132284,6757554.3278609235],[223573.85212353762,6757560.616114361],[223576.67914916988,6757560.106340847],[223575.45401568234,6757553.784546239],[223572.6004132284,6757554.3278609235]]]]},"properties":{"pk":793,"id_way":69940034,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223997.96562594434,6757908.747064151],[224001.67159387606,6757898.710183678],[223987.75226137793,6757893.696633112],[223984.0662057284,6757903.610989404],[223997.96562594434,6757908.747064151]]]]},"properties":{"pk":794,"id_way":69940084,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224119.14615360502,6757718.814090368],[224114.39227026174,6757731.811746499],[224124.55971372468,6757735.511387534],[224129.31361458363,6757722.513739521],[224119.14615360502,6757718.814090368]]]]},"properties":{"pk":795,"id_way":69940089,"height":16.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224055.82784588245,6758086.469303533],[224053.87392811693,6758091.761283265],[224061.34846732143,6758094.4411625],[224063.2173840414,6758089.178082944],[224055.82784588245,6758086.469303533]]]]},"properties":{"pk":796,"id_way":69940132,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224221.04442467875,6757694.342421091],[224223.98850913078,6757686.007314065],[224207.57253008845,6757680.234613141],[224204.0962466236,6757689.99811035],[224206.0109671205,6757690.717263273],[224206.546346463,6757689.260959888],[224209.27614350832,6757690.200911186],[224208.65484156547,6757692.102082189],[224215.6588491033,6757694.577770638],[224216.37472337965,6757692.635318368],[224221.04442467875,6757694.342421091]]]]},"properties":{"pk":797,"id_way":69940139,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223963.58676782175,6758510.646654533],[223970.568089172,6758514.214190964],[223974.72483535885,6758506.223885643],[223967.62315078656,6758502.622380336],[223963.58676782175,6758510.646654533]]]]},"properties":{"pk":798,"id_way":69940178,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224028.1546951276,6757806.741444874],[224032.16857457775,6757796.027707671],[224025.69656227194,6757793.603298515],[224020.07110752288,6757808.515694517],[224019.39617759327,6757808.34756],[224018.35558940866,6757811.136369671],[224023.1094697505,6757812.971865752],[224025.78690605695,6757805.985563723],[224028.1546951276,6757806.741444874]]]]},"properties":{"pk":799,"id_way":69940234,"height":15.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223694.45555727938,6758418.0311468365],[223707.2546526836,6758421.708911319],[223711.36934349829,6758407.452519451],[223701.32426716687,6758404.6103111515],[223698.93902414717,6758413.330240863],[223695.98018270292,6758412.532491322],[223694.45555727938,6758418.0311468365]]]]},"properties":{"pk":800,"id_way":69940275,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223921.7310397318,6758026.76851318],[223928.9986400261,6758022.6239143],[223918.76920569903,6758004.601992665],[223911.50274380186,6758008.715575735],[223921.7310397318,6758026.76851318]]]]},"properties":{"pk":801,"id_way":69940277,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224131.4644186265,6757416.144875595],[224115.34735572775,6757427.395771696],[224121.60833760333,6757437.152717983],[224125.489918216,6757434.1180962855],[224123.5391758832,6757430.9184041815],[224125.1124290358,6757429.74575907],[224125.59591320454,6757430.307438992],[224126.19178449165,6757430.415656639],[224133.01819830376,6757426.758149161],[224134.4975865296,6757429.607366149],[224138.8680409326,6757427.479770475],[224138.65944483678,6757426.509949581],[224136.06665101004,6757422.212450721],[224131.8021100767,6757416.346726956],[224131.4644186265,6757416.144875595]]]]},"properties":{"pk":802,"id_way":69940282,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223701.28471645564,6758333.751209887],[223690.69252521708,6758333.197774891],[223689.3745137688,6758338.16783029],[223699.51142416243,6758338.420738725],[223701.28471645564,6758333.751209887]]]]},"properties":{"pk":803,"id_way":69940321,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223776.68451726992,6757906.158180037],[223772.0614605454,6757908.7507403325],[223773.88006838405,6757911.934203721],[223798.98793600424,6757897.785362362],[223795.2223496579,6757891.159526279],[223784.45759859247,6757897.195020498],[223786.46420356564,6757900.722985845],[223776.68451726992,6757906.158180037]]]]},"properties":{"pk":804,"id_way":69940326,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223961.6034180401,6757828.365238138],[223970.65714077122,6757812.762023922],[223957.0424041628,6757804.76873115],[223954.05630712607,6757809.872005062],[223951.47139880608,6757811.696368119],[223948.92470323297,6757804.829746446],[223940.69955691122,6757808.022252817],[223946.5181090287,6757823.5201163655],[223950.43996744897,6757821.893752305],[223961.6034180401,6757828.365238138]]]]},"properties":{"pk":805,"id_way":69940414,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223876.0224648113,6757619.525770389],[223879.5105249637,6757624.432281665],[223881.9838300819,6757622.653439424],[223878.49870687767,6757617.788782795],[223876.0224648113,6757619.525770389]]]]},"properties":{"pk":806,"id_way":69940417,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223972.26914613027,6758016.285859949],[223986.72412585176,6758021.533463127],[223987.35233641823,6758019.721298973],[223993.85679161982,6758022.104408086],[223995.94669387082,6758015.500787205],[223984.67643949945,6758011.39853042],[223984.59094600158,6758011.638007534],[223975.17790517828,6758008.373492873],[223972.26914613027,6758016.285859949]]]]},"properties":{"pk":807,"id_way":69940459,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223815.17994229912,6758161.936484679],[223813.96911760548,6758159.23619972],[223809.11003393272,6758161.433795841],[223810.29276841678,6758164.136086922],[223815.17994229912,6758161.936484679]]]]},"properties":{"pk":808,"id_way":69940461,"height":3.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223929.51256528584,6758429.410918031],[223932.02596903368,6758428.706531997],[223934.43130048737,6758437.560125007],[223926.31546156795,6758439.831671929],[223927.65424218978,6758444.850373714],[223933.68808652085,6758446.253886084],[223933.86050038302,6758445.503597504],[223937.85041326238,6758446.459145866],[223937.6704105177,6758447.2094359975],[223946.11338861389,6758449.240297504],[223946.5211978994,6758447.37662552],[223947.20535508834,6758448.080518499],[223950.5528098748,6758444.937313999],[223950.03211743798,6758444.40707393],[223952.32798073805,6758443.887808399],[223947.4362520544,6758425.310059366],[223944.9235553968,6758425.936504978],[223942.6627178301,6758417.361943197],[223945.18051358004,6758416.701656447],[223942.8285509431,6758407.682914527],[223943.42509789098,6758407.534649834],[223941.1840970398,6758399.073785561],[223936.5073788779,6758400.242351742],[223935.83119120554,6758397.913527063],[223923.89783428854,6758401.159337345],[223924.4246883424,6758403.34850827],[223924.13066177923,6758403.50578666],[223926.3189643205,6758411.912290277],[223928.03224365876,6758411.439622558],[223930.34748077462,6758420.322049897],[223927.3285070464,6758421.189911773],[223929.51256528584,6758429.410918031]]]]},"properties":{"pk":809,"id_way":69940515,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224185.80255610534,6757798.550040989],[224181.76910431965,6757797.225694829],[224179.47229111497,6757803.941188161],[224183.40277060546,6757805.422483614],[224185.80255610534,6757798.550040989]]]]},"properties":{"pk":810,"id_way":69940522,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223620.19362184257,6757774.4586299285],[223628.34781591565,6757786.277665939],[223635.7388272707,6757781.188661284],[223627.52925680118,6757769.417967308],[223620.19362184257,6757774.4586299285]]]]},"properties":{"pk":811,"id_way":69940559,"height":13.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223574.08290917936,6758452.0671318],[223571.4621299149,6758459.252080829],[223573.9729597642,6758458.950241784],[223573.19038961825,6758465.470588331],[223578.43550384007,6758463.709770066],[223577.7985565304,6758469.723627123],[223580.35008958957,6758469.982686329],[223582.2315608291,6758450.910448925],[223574.85863168552,6758450.090487506],[223574.08290917936,6758452.0671318]]]]},"properties":{"pk":812,"id_way":69940577,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223876.0346336068,6758387.06750212],[223869.89236888153,6758384.794728945],[223868.82986117946,6758387.728872269],[223874.97405217602,6758389.926113438],[223876.0346336068,6758387.06750212]]]]},"properties":{"pk":813,"id_way":69940602,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223786.30901812893,6757919.762279082],[223791.14475251824,6757928.363834031],[223794.04826239712,6757926.73082409],[223789.1900174581,6757918.120829427],[223786.30901812893,6757919.762279082]]]]},"properties":{"pk":814,"id_way":69940607,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223960.61164547468,6757649.7732783025],[223960.34396191186,6757649.921821138],[223963.56741138012,6757656.714329179],[223982.25560516876,6757647.910904117],[223978.63424983373,6757641.242840355],[223975.24913157424,6757642.894433276],[223976.90386504238,6757646.530020675],[223971.4216632796,6757649.0927539505],[223969.6799481555,6757645.488401381],[223960.61164547468,6757649.7732783025]]]]},"properties":{"pk":815,"id_way":69940612,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223888.73993921556,6758275.517527811],[223890.89798644985,6758276.423732533],[223907.5679860665,6758282.481056065],[223911.41104941987,6758271.797664989],[223892.66059823157,6758264.95662107],[223888.73993921556,6758275.517527811]]]]},"properties":{"pk":816,"id_way":69940660,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224084.7114313257,6758560.599228671],[224079.29507031466,6758557.85888055],[224074.8064343511,6758566.9994535195],[224083.38776160424,6758571.308682148],[224088.79536937503,6758560.6348803975],[224085.45259481788,6758559.054583604],[224084.7114313257,6758560.599228671]]]]},"properties":{"pk":817,"id_way":69940663,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223891.28119146128,6757851.051789372],[223871.40314898593,6757859.977227391],[223871.23474633473,6757859.671418327],[223865.2559870141,6757863.632906697],[223861.45376473595,6757866.638096114],[223860.58533932897,6757865.831883355],[223854.2459250452,6757869.764533359],[223855.30572126913,6757871.619327239],[223846.65312536896,6757876.745296532],[223853.40246250475,6757888.827698025],[223858.6445953578,6757885.951527431],[223859.79462869134,6757888.088540122],[223869.9479124353,6757882.586701882],[223869.37828341487,6757881.242758278],[223889.77332628513,6757872.3523675455],[223898.95775196017,6757868.18948665],[223891.28119146128,6757851.051789372]]]]},"properties":{"pk":818,"id_way":69940667,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224013.5269506087,6757570.444565952],[224008.6422958199,6757561.957507414],[224001.90944141455,6757565.7175173545],[224006.67745067205,6757574.312127203],[224013.5269506087,6757570.444565952]]]]},"properties":{"pk":819,"id_way":69940671,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224070.08745546525,6757973.450175253],[224067.5378028889,6757980.51951092],[224070.30527868273,6757981.569912072],[224072.85717554623,6757974.447943801],[224070.08745546525,6757973.450175253]]]]},"properties":{"pk":820,"id_way":69940731,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223966.37918760738,6757890.351591288],[223968.33063778133,6757884.902630705],[223965.20307228414,6757883.702763258],[223963.1364888561,6757889.159983906],[223966.37918760738,6757890.351591288]]]]},"properties":{"pk":821,"id_way":69940799,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223988.5310371053,6758134.953426305],[223987.70925011777,6758132.771481701],[223974.5079693404,6758128.377174063],[223972.45431414864,6758134.456028399],[223975.91722694066,6758135.615107886],[223974.34358413485,6758140.029025347],[223985.5743809054,6758143.199130417],[223988.5310371053,6758134.953426305]]]]},"properties":{"pk":822,"id_way":69940835,"height":13.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223739.60851503746,6758030.620305192],[223744.46608359326,6758039.219744765],[223758.28567211406,6758031.443709111],[223753.48403687272,6758022.806931245],[223739.60851503746,6758030.620305192]]]]},"properties":{"pk":823,"id_way":69940836,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223560.70843561104,6757492.81394335],[223555.47339165755,6757484.562553909],[223547.43434838054,6757489.502171206],[223552.63842019715,6757497.910137896],[223560.70843561104,6757492.81394335]]]]},"properties":{"pk":824,"id_way":69940839,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223931.59865792244,6757392.824962712],[223938.7948164946,6757387.698431785],[223926.74238611528,6757370.507575759],[223919.37337650286,6757375.703755197],[223931.59865792244,6757392.824962712]]]]},"properties":{"pk":825,"id_way":69940843,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223651.43670788044,6758494.30073695],[223643.58296939422,6758493.554417737],[223642.57090309745,6758504.32841172],[223650.45836282143,6758505.039377593],[223651.43670788044,6758494.30073695]]]]},"properties":{"pk":826,"id_way":69940878,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223569.2394982998,6757347.338024703],[223570.27369742325,6757348.713020589],[223578.71083986232,6757342.647892806],[223577.78979354008,6757341.344340001],[223569.2394982998,6757347.338024703]]]]},"properties":{"pk":827,"id_way":69940926,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223911.6512665717,6758594.373935087],[223913.49719534567,6758581.20636164],[223910.99333046796,6758577.395172547],[223902.99348295393,6758575.201248275],[223898.27852651777,6758592.523743484],[223911.6512665717,6758594.373935087]]]]},"properties":{"pk":828,"id_way":69940959,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223842.7674393713,6757297.22557953],[223820.7953660326,6757265.943402445],[223814.20057813206,6757270.587274488],[223836.22753802597,6757301.90828316],[223842.7674393713,6757297.22557953]]]]},"properties":{"pk":829,"id_way":69940969,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223646.12959432747,6758149.062245655],[223644.90428257216,6758146.901475198],[223639.5631835095,6758150.021785691],[223640.79264784566,6758152.225064392],[223646.12959432747,6758149.062245655]]]]},"properties":{"pk":830,"id_way":69941002,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223831.64225369855,6758071.085446962],[223835.97601617602,6758078.780166989],[223844.59948430344,6758073.877345389],[223840.21834309504,6758066.142718672],[223831.64225369855,6758071.085446962]]]]},"properties":{"pk":831,"id_way":69941003,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224130.66943623437,6757442.611785576],[224130.87702919333,6757443.201360232],[224131.8017468357,6757442.9700341085],[224132.0048630986,6757443.630626692],[224132.91163115186,6757443.372874324],[224132.73867467945,6757442.710372662],[224133.97343793727,6757442.310538166],[224133.4856444461,6757440.6851841165],[224130.66943623437,6757442.611785576]]]]},"properties":{"pk":832,"id_way":69941008,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223834.87130872547,6757793.680586577],[223843.68724947068,6757788.647890466],[223838.18371051093,6757776.95456934],[223833.54250889653,6757768.740943499],[223823.81452709247,6757774.31195651],[223828.43787515277,6757782.439833779],[223830.75096837844,6757781.104874235],[223834.39044644104,6757787.523740972],[223832.1381545463,6757788.864852716],[223834.87130872547,6757793.680586577]]]]},"properties":{"pk":833,"id_way":69941079,"height":13.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223586.47509312668,6758361.992084769],[223585.90985390058,6758365.266162342],[223591.664143862,6758366.234618982],[223592.22617877505,6758362.917754769],[223586.47509312668,6758361.992084769]]]]},"properties":{"pk":834,"id_way":69941158,"height":3.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223997.4328497524,6758492.90677694],[223999.50613591206,6758484.2586413305],[223988.86923817164,6758481.789625346],[223986.82730853985,6758490.369539206],[223997.4328497524,6758492.90677694]]]]},"properties":{"pk":835,"id_way":69941203,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223754.35834244813,6758423.569500983],[223750.78786878573,6758422.322749623],[223749.42388042138,6758426.3174162125],[223752.99435208354,6758427.564166727],[223754.35834244813,6758423.569500983]]]]},"properties":{"pk":836,"id_way":69941249,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223667.33537763337,6757832.223160711],[223673.36643558566,6757840.682512239],[223675.89889049358,6757838.896768146],[223669.87312790996,6757830.405065117],[223667.33537763337,6757832.223160711]]]]},"properties":{"pk":837,"id_way":69941258,"height":3.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223785.6532083757,6757451.996508114],[223804.76218110268,6757479.285822589],[223808.2158107564,6757476.911077593],[223789.08012862454,6757449.549028715],[223785.6532083757,6757451.996508114]]]]},"properties":{"pk":838,"id_way":69941264,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223711.78358293697,6758149.130216286],[223728.05442350058,6758142.086620877],[223731.37602038265,6758149.743658675],[223715.1996919183,6758156.823853085],[223717.52907792947,6758162.097530226],[223743.57315369145,6758150.807361334],[223731.8041019441,6758123.880252115],[223722.0291983254,6758128.127614786],[223723.00443873194,6758130.451131818],[223707.0887511845,6758138.513064594],[223711.78358293697,6758149.130216286]]]]},"properties":{"pk":839,"id_way":69941306,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223887.18827278863,6758084.689038169],[223893.06053994995,6758081.3676693225],[223884.18873329717,6758065.601440586],[223878.25758941082,6758068.927969606],[223887.18827278863,6758084.689038169]]]]},"properties":{"pk":840,"id_way":69941308,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224160.70173093784,6757421.691080557],[224156.89971089995,6757398.537457],[224156.6496978552,6757398.455637773],[224145.79077267266,6757406.0487798145],[224149.18094577215,6757412.0945140915],[224149.92280062416,6757411.619172989],[224150.64943301305,6757413.11935679],[224149.34257778685,6757414.694054483],[224150.2017010809,6757416.296954275],[224150.6179628199,6757415.612991845],[224152.28077683307,6757415.6111378465],[224152.72639769618,6757416.63782487],[224151.26679678448,6757417.227286324],[224153.00814973103,6757423.062829875],[224160.70173093784,6757421.691080557]]]]},"properties":{"pk":841,"id_way":69941316,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224085.80286009712,6757904.08336359],[224094.63917268315,6757907.321110192],[224096.8477841946,6757901.158077891],[224098.02182452328,6757901.576243084],[224098.66183287938,6757901.224273243],[224099.22850939946,6757899.63900143],[224098.9100173533,6757899.081178946],[224097.70249715023,6757898.615924894],[224100.23230697997,6757891.869811979],[224091.48076054535,6757888.644723399],[224085.80286009712,6757904.08336359]]]]},"properties":{"pk":842,"id_way":69941357,"height":9.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223866.29208891527,6757763.036926008],[223869.5685627032,6757770.364459111],[223882.9338173927,6757764.502296942],[223881.39527857388,6757761.077550546],[223876.9455531289,6757758.89352863],[223875.00493646166,6757759.778948952],[223874.71428157322,6757759.255741262],[223866.29208891527,6757763.036926008]]]]},"properties":{"pk":843,"id_way":69941399,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223665.78056504615,6757432.555662334],[223667.3555383767,6757431.457385796],[223667.79279769884,6757432.124618806],[223675.15915095585,6757427.005382102],[223674.04013248257,6757425.345543722],[223676.42562473344,6757423.692549065],[223677.5520082243,6757425.35152714],[223684.91872791195,6757420.232059678],[223677.85741936057,6757410.029884664],[223671.6162227343,6757414.366896219],[223672.41233442098,6757415.47306247],[223670.08220660078,6757417.089306907],[223663.37183173024,6757407.415240588],[223666.2823945329,6757403.671495717],[223667.08824699168,6757404.558883495],[223672.07664266802,6757400.150947785],[223670.430922766,6757398.268638587],[223672.01150380456,6757396.249750848],[223670.48576233612,6757393.984028911],[223668.2395993486,6757395.552570176],[223667.26813491905,6757394.445149659],[223662.17402287835,6757398.732487927],[223662.73871222048,6757399.419313779],[223649.24143361958,6757408.795574899],[223661.76598424444,6757426.784014151],[223663.2772498168,6757425.759038963],[223664.89703625496,6757428.097347461],[223663.415598631,6757429.119941091],[223665.78056504615,6757432.555662334]]]]},"properties":{"pk":844,"id_way":69941403,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223895.58078442296,6757941.61905401],[223885.55989660666,6757923.994748989],[223878.76112429987,6757927.877389541],[223888.72637197407,6757945.531476254],[223895.58078442296,6757941.61905401]]]]},"properties":{"pk":845,"id_way":69941450,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223826.7691179726,6758190.060932396],[223827.3428999858,6758192.751368274],[223832.3174532783,6758190.167637911],[223831.74095229228,6758187.445233764],[223826.7691179726,6758190.060932396]]]]},"properties":{"pk":846,"id_way":69941500,"height":3.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224014.27998531962,6758019.356124208],[224017.1702803039,6758020.251056953],[224017.52059147623,6758019.255549661],[224014.68537599387,6758018.292278077],[224014.27998531962,6758019.356124208]]]]},"properties":{"pk":847,"id_way":69941502,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224011.82578355345,6758494.661987545],[224020.24157500494,6758495.136803372],[224020.861631745,6758486.792966433],[224012.50342302278,6758486.135321456],[224011.82578355345,6758494.661987545]]]]},"properties":{"pk":848,"id_way":69941566,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224025.10931045722,6757912.343415427],[224014.98879959073,6757908.598257781],[224011.63307917214,6757917.7716630455],[224028.51947869596,6757924.0488059595],[224031.935995407,6757914.804553228],[224025.10931045722,6757912.343415427]]]]},"properties":{"pk":849,"id_way":69941576,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223768.02847567174,6758452.548674595],[223777.28434046856,6758455.777664632],[223779.95235222182,6758448.42033048],[223770.7024979294,6758445.081671456],[223768.02847567174,6758452.548674595]]]]},"properties":{"pk":850,"id_way":69941629,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223794.5570412183,6757816.620350604],[223799.983124072,6757813.535804125],[223793.82265157573,6757802.228652708],[223796.56874443137,6757800.674922822],[223802.94160114636,6757811.819905064],[223808.34018664417,6757808.770550808],[223797.40815413397,6757789.3703598315],[223783.7674919676,6757797.141991931],[223794.5570412183,6757816.620350604]]]]},"properties":{"pk":851,"id_way":69941636,"height":12.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223912.427064244,6758084.315536201],[223914.8376823655,6758088.46636879],[223929.06023636533,6758093.626458078],[223934.76135671,6758078.221184163],[223927.79769932723,6758075.6131360205],[223912.427064244,6758084.315536201]]]]},"properties":{"pk":852,"id_way":69941703,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223954.01779088384,6758026.318095357],[223948.79438270733,6758024.4374643965],[223947.88241991622,6758026.904644203],[223953.08001288693,6758028.819826884],[223954.01779088384,6758026.318095357]]]]},"properties":{"pk":853,"id_way":69941707,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223763.02870680604,6758361.0641218955],[223758.99973608667,6758359.924702394],[223757.0271395347,6758367.241107767],[223759.15745229338,6758367.851375013],[223759.84227785884,6758368.948413068],[223763.02870680604,6758361.0641218955]]]]},"properties":{"pk":854,"id_way":69941774,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224044.4161937539,6758600.331917397],[224055.98726824703,6758605.228133398],[224049.41458938865,6758620.182074022],[224063.72799404417,6758626.213617023],[224072.56907225752,6758606.69441025],[224047.66822555193,6758592.79923972],[224044.4161937539,6758600.331917397]]]]},"properties":{"pk":855,"id_way":69941777,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223665.34649089607,6757889.322126295],[223662.04207685633,6757891.573896914],[223665.31496273805,6757896.075123479],[223668.56674289337,6757893.795942932],[223665.34649089607,6757889.322126295]]]]},"properties":{"pk":856,"id_way":69941783,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223609.24853273924,6757508.455421056],[223614.125252243,6757515.445879103],[223621.4047803733,6757510.355844128],[223616.49886576278,6757503.367727355],[223609.24853273924,6757508.455421056]]]]},"properties":{"pk":857,"id_way":69941833,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223827.89541125632,6758489.598465935],[223835.34521136884,6758469.271570664],[223826.20734515725,6758465.847750123],[223814.37686206764,6758498.014393606],[223862.0855892145,6758511.990128263],[223865.83712843372,6758500.781546021],[223827.89541125632,6758489.598465935]]]]},"properties":{"pk":858,"id_way":69941868,"height":10.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223963.58833591128,6758000.671993172],[223967.444504728,6757990.366376581],[223957.33443878405,6757986.590067215],[223954.5825135513,6757985.994124195],[223952.7311642259,6757986.033129584],[223950.8879278118,6757986.456992011],[223944.61622525137,6757989.980518274],[223950.09668809958,6757999.688836082],[223953.90517021553,6757997.564570098],[223954.9255543825,6757997.447501981],[223955.746904871,6757997.6453038175],[223963.58833591128,6758000.671993172]]]]},"properties":{"pk":859,"id_way":69941875,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223592.43370398364,6758117.330876028],[223589.84740114943,6758118.803794979],[223592.99366501684,6758124.442455184],[223595.6087418719,6758122.966836558],[223592.43370398364,6758117.330876028]]]]},"properties":{"pk":860,"id_way":69941918,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223916.75846812266,6758165.361770603],[223936.27908042682,6758172.4416113105],[223938.6175149285,6758166.0371598145],[223919.12778881838,6758158.877145493],[223916.75846812266,6758165.361770603]]]]},"properties":{"pk":861,"id_way":69941919,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224050.459107012,6757535.811618655],[224057.24653661042,6757531.894546052],[224054.35245106157,6757526.876622711],[224057.1214593826,6757525.334911301],[224052.5166387639,6757515.826203351],[224049.52608331307,6757517.404260317],[224047.96610664998,6757514.3572107935],[224040.60983834742,6757518.629802984],[224050.459107012,6757535.811618655]]]]},"properties":{"pk":862,"id_way":69941929,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223914.91750525564,6758486.007231233],[223920.07610279036,6758472.35079568],[223910.0007242946,6758468.578925167],[223905.78818932097,6758479.70843982],[223905.86993945428,6758480.455157937],[223906.14972730368,6758481.141063189],[223907.17998307533,6758482.101835937],[223914.91750525564,6758486.007231233]]]]},"properties":{"pk":863,"id_way":69941975,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224101.09947805313,6757951.129534265],[224104.15813249254,6757942.750562352],[224084.16715054997,6757935.440981326],[224081.1123044009,6757943.776133591],[224101.09947805313,6757951.129534265]]]]},"properties":{"pk":864,"id_way":69941983,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223772.9637099945,6758637.026586294],[223775.96154924165,6758628.728431632],[223767.71872087783,6758625.667058549],[223764.71478990972,6758634.074581821],[223772.9637099945,6758637.026586294]]]]},"properties":{"pk":865,"id_way":69942030,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223826.92185483803,6757757.344456485],[223818.55027116652,6757742.641979346],[223812.55995374668,6757746.093968675],[223820.92755953246,6757760.742420162],[223826.92185483803,6757757.344456485]]]]},"properties":{"pk":866,"id_way":69942036,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223634.55376667244,6758407.471351573],[223633.79745632422,6758410.875798425],[223636.84406701705,6758411.633321358],[223635.3787960371,6758417.8699097745],[223641.4898253571,6758419.299151518],[223643.77336415657,6758409.619092775],[223634.55376667244,6758407.471351573]]]]},"properties":{"pk":867,"id_way":69942079,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224034.61001312104,6757614.497865871],[224040.0769121643,6757616.416267901],[224041.01896161816,6757613.725815888],[224035.5590729089,6757611.806757401],[224034.61001312104,6757614.497865871]]]]},"properties":{"pk":868,"id_way":69942084,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223596.05442903383,6758317.581275053],[223597.066105385,6758311.339664937],[223588.80806519213,6758309.899890265],[223589.3511534658,6758306.669106659],[223579.721759379,6758305.098583449],[223578.10738543308,6758314.654156864],[223596.05442903383,6758317.581275053]]]]},"properties":{"pk":869,"id_way":69942126,"height":9.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224269.09104225622,6758514.441480316],[224296.09412371714,6758525.902892149],[224301.39557637088,6758513.580690613],[224274.3916054549,6758502.108271363],[224269.09104225622,6758514.441480316]]]]},"properties":{"pk":870,"id_way":69942128,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223593.79695114333,6757809.439994322],[223609.62939012854,6757832.454130039],[223636.47461636044,6757813.945354748],[223626.0780800426,6757799.196114192],[223614.72149781036,6757806.945835548],[223608.96459179878,6757798.961854987],[223593.79695114333,6757809.439994322]]]]},"properties":{"pk":871,"id_way":69942132,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223912.2744458445,6757609.239333694],[223906.66484063643,6757601.259596097],[223899.46896247964,6757606.386183358],[223905.02617414092,6757614.446640891],[223912.2744458445,6757609.239333694]]]]},"properties":{"pk":872,"id_way":69942136,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224096.77773595916,6757983.179188946],[224094.87961576498,6757988.432277976],[224097.38471045066,6757989.318864168],[224099.30828641957,6757984.105771995],[224096.77773595916,6757983.179188946]]]]},"properties":{"pk":873,"id_way":69942187,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223836.89180273257,6758531.826599061],[223868.79022133118,6758540.13941946],[223868.75629193665,6758540.303404816],[223869.6772756093,6758540.603629572],[223873.29490311403,6758531.124954577],[223872.40152467694,6758530.897646221],[223872.31403173195,6758531.218041471],[223861.76023306808,6758528.378895631],[223861.82020303083,6758528.183063035],[223839.60909668083,6758521.832925682],[223836.89180273257,6758531.826599061]]]]},"properties":{"pk":874,"id_way":69942227,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223583.39383864214,6758415.117615985],[223575.09439328866,6758413.71951012],[223574.379266138,6758418.142640626],[223582.64627010282,6758419.586688883],[223583.39383864214,6758415.117615985]]]]},"properties":{"pk":875,"id_way":69942231,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223983.59473922706,6757896.676295711],[223985.55577549298,6757891.37102587],[223982.7819630592,6757890.331557181],[223980.82382534244,6757895.668087919],[223983.59473922706,6757896.676295711]]]]},"properties":{"pk":876,"id_way":69942233,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223788.47515546906,6758114.701170219],[223789.57473960743,6758117.210125185],[223794.4015061534,6758115.091198494],[223793.2980685058,6758112.539743246],[223788.47515546906,6758114.701170219]]]]},"properties":{"pk":877,"id_way":69942286,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223958.69344716493,6758154.3947532475],[223960.2082437856,6758149.930711867],[223956.75887308788,6758148.836500948],[223955.3049023186,6758153.338197797],[223958.69344716493,6758154.3947532475]]]]},"properties":{"pk":878,"id_way":69942289,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223541.95002964517,6757532.0367496805],[223535.27612902768,6757533.442475005],[223537.08206466713,6757542.851425866],[223543.93520008304,6757541.47436537],[223541.95002964517,6757532.0367496805]]]]},"properties":{"pk":879,"id_way":69942293,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224030.36666957368,6757487.110513705],[224036.6975100752,6757497.349635838],[224048.5562006947,6757489.703048478],[224041.14602068084,6757479.462131843],[224030.36666957368,6757487.110513705]]]]},"properties":{"pk":880,"id_way":69942298,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223824.6836128242,6757873.949957714],[223828.06361389125,6757871.867303176],[223821.96921671863,6757865.504257864],[223816.73590524253,6757857.590924976],[223809.5779876978,6757862.320258102],[223818.83273274207,6757877.146406274],[223824.59410314503,6757873.758803339],[223824.6836128242,6757873.949957714]]]]},"properties":{"pk":881,"id_way":69942349,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223988.11683593685,6757682.767719541],[223993.15820536736,6757692.11990255],[224002.58404614244,6757686.81748714],[223997.4603759287,6757677.548763816],[223988.11683593685,6757682.767719541]]]]},"properties":{"pk":882,"id_way":69942404,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223624.63095794167,6757594.341475916],[223639.53994807907,6757583.817968786],[223639.78601142106,6757584.166167761],[223648.52045492965,6757578.012189915],[223648.292934634,6757577.697804363],[223649.7629023956,6757576.620061515],[223640.81221345038,6757564.047941715],[223639.34580815097,6757565.069415792],[223622.3666488611,6757541.1047280915],[223613.63873269534,6757547.258693119],[223633.80871180227,6757575.72585344],[223618.82267567056,6757586.29890211],[223624.63095794167,6757594.341475916]]]]},"properties":{"pk":883,"id_way":69942409,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223777.25042049107,6758598.86335381],[223789.4566347801,6758603.168547775],[223791.95087361865,6758596.060855382],[223779.7712855895,6758591.720514028],[223777.25042049107,6758598.86335381]]]]},"properties":{"pk":884,"id_way":69942455,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223703.23845010903,6757976.710075205],[223718.65688241948,6758003.7393640755],[223736.41864675735,6757993.684129828],[223728.91868406505,6757980.680227622],[223742.97208215605,6757972.60026353],[223735.33718931008,6757958.862858386],[223703.23845010903,6757976.710075205]]]]},"properties":{"pk":885,"id_way":69942462,"height":12.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224138.92869521404,6757696.234015203],[224128.75741846996,6757692.4907556735],[224124.0075274865,6757705.443586714],[224134.17142845894,6757709.187420839],[224138.92869521404,6757696.234015203]]]]},"properties":{"pk":886,"id_way":69942467,"height":16.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223620.54445767848,6758241.683131003],[223663.6983905037,6758257.586327244],[223667.38991580077,6758247.356569642],[223668.81661377323,6758247.877483275],[223670.586355316,6758243.2119206805],[223669.6110164938,6758242.856245285],[223674.0813655521,6758230.846479757],[223673.54826711334,6758230.56681135],[223680.43208562766,6758211.526752493],[223682.11910951402,6758212.115293561],[223684.43220090136,6758205.866839922],[223682.71330133989,6758205.236901541],[223683.96605728363,6758201.757750911],[223674.15443784805,6758198.09831238],[223656.82584860353,6758245.545208138],[223649.03837580828,6758242.657341251],[223649.39576639756,6758241.591725791],[223624.01437807322,6758232.166412762],[223620.54445767848,6758241.683131003]]]]},"properties":{"pk":887,"id_way":69942512,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224078.12321321256,6758072.096238579],[224069.084734472,6758097.210324003],[224078.18640931122,6758100.472980347],[224087.34821210906,6758075.4043702865],[224078.12321321256,6758072.096238579]]]]},"properties":{"pk":888,"id_way":69942515,"height":9.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223597.9856856617,6757317.25042915],[223602.26965818755,6757323.262756936],[223604.1570695293,6757321.875149366],[223599.92699358848,6757315.870091305],[223597.9856856617,6757317.25042915]]]]},"properties":{"pk":889,"id_way":69942519,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224204.61531355878,6757651.464291321],[224203.93891636122,6757646.046119265],[224201.0854497304,6757646.411845572],[224201.70339463864,6757651.824381713],[224204.61531355878,6757651.464291321]]]]},"properties":{"pk":890,"id_way":69942521,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223961.17782217977,6758499.330407111],[223957.0757039765,6758507.359970483],[223963.4084437098,6758510.556094609],[223967.44490667613,6758502.531661369],[223961.17782217977,6758499.330407111]]]]},"properties":{"pk":891,"id_way":69942555,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224022.54096973565,6757842.539085794],[224008.6738870927,6757837.257223479],[224006.21229571887,6757843.894408549],[224020.10757154043,6757849.064085269],[224022.54096973565,6757842.539085794]]]]},"properties":{"pk":892,"id_way":69942610,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223802.93235610885,6758121.525507334],[223798.28720268878,6758123.573896825],[223799.41185249426,6758126.191506946],[223804.092992857,6758124.1512253005],[223802.93235610885,6758121.525507334]]]]},"properties":{"pk":893,"id_way":69942666,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223669.57499235222,6758506.795471032],[223682.44260535366,6758507.987402138],[223687.99694366174,6758488.582734434],[223682.8954942115,6758487.125718457],[223679.88805734724,6758497.652055471],[223670.4627825453,6758496.8000536235],[223669.57499235222,6758506.795471032]]]]},"properties":{"pk":894,"id_way":69942670,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223971.4495659339,6757616.845151073],[223976.19489927153,6757614.121576141],[223973.39826115375,6757608.344061635],[223964.1744093339,6757613.518110928],[223968.33134852143,6757621.635810997],[223972.77733064926,6757619.144610118],[223971.4495659339,6757616.845151073]]]]},"properties":{"pk":895,"id_way":69942676,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223732.21740028023,6758331.383720657],[223734.25805747558,6758324.330530713],[223732.47061340063,6758320.64680868],[223720.40929102784,6758316.1299057305],[223717.59398489064,6758323.874456352],[223723.8915921338,6758326.017935419],[223723.1145643438,6758328.309782961],[223732.21740028023,6758331.383720657]]]]},"properties":{"pk":896,"id_way":69942740,"height":16.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223898.93540641523,6757835.954234117],[223912.4134081697,6757829.895130359],[223909.63347995598,6757823.599513312],[223896.18658738994,6757829.765965323],[223898.93540641523,6757835.954234117]]]]},"properties":{"pk":897,"id_way":69942750,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223774.1505926337,6757787.470792629],[223788.76965525176,6757779.151791698],[223780.37505500318,6757764.617780609],[223774.61487123178,6757767.939679276],[223776.53671970437,6757771.261595916],[223772.23694231227,6757773.782488612],[223774.23894786515,6757777.2547628125],[223769.79411525506,6757779.8547317395],[223774.1505926337,6757787.470792629]]]]},"properties":{"pk":898,"id_way":69942894,"height":9.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223862.91393615652,6757683.721436951],[223857.38619994742,6757687.708380981],[223865.678543226,6757699.229966691],[223869.40749722897,6757696.61124044],[223866.46131051483,6757692.424783263],[223868.19506356047,6757691.181352673],[223862.91393615652,6757683.721436951]]]]},"properties":{"pk":899,"id_way":69942898,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223805.3630357835,6758153.087066129],[223806.55234207824,6758155.712184056],[223811.46899672682,6758153.595807037],[223810.275854304,6758150.928153332],[223805.3630357835,6758153.087066129]]]]},"properties":{"pk":900,"id_way":69942950,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223976.77233259904,6758038.266380837],[223965.05954768718,6758034.624131555],[223962.6319202729,6758041.22584755],[223977.47756429107,6758045.916786094],[223976.77233259904,6758038.266380837]]]]},"properties":{"pk":901,"id_way":69942952,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223620.76814574198,6757275.424866608],[223611.37293308318,6757262.099371551],[223602.54998620774,6757268.40535069],[223607.4223913751,6757275.480712566],[223605.7929994318,6757276.626857069],[223610.19732880217,6757283.062508904],[223620.76814574198,6757275.424866608]]]]},"properties":{"pk":902,"id_way":69942955,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223891.74570375265,6758374.46487085],[223893.7174368275,6758375.180516931],[223893.89576738613,6758374.67200531],[223894.190000555,6758374.792228507],[223894.71913494062,6758373.20867342],[223892.5065346501,6758372.358445522],[223891.74570375265,6758374.46487085]]]]},"properties":{"pk":903,"id_way":69942990,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224146.60033807365,6757784.798233009],[224131.19298888958,6757778.960353692],[224128.9997834315,6757784.929621196],[224144.3748539219,6757790.726450245],[224146.60033807365,6757784.798233009]]]]},"properties":{"pk":904,"id_way":69942997,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223678.42245741212,6757765.880418611],[223685.64188387964,6757760.79614568],[223680.3568827366,6757753.352997316],[223682.17480982814,6757752.085198101],[223680.23962466524,6757748.423226699],[223673.79033889782,6757748.603373237],[223668.76866907,6757752.042779028],[223678.42245741212,6757765.880418611]]]]},"properties":{"pk":905,"id_way":69943037,"height":13.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223724.7011528573,6757386.837060633],[223726.07983483747,6757385.86593669],[223713.17560107532,6757367.796333342],[223711.60326045737,6757368.904420666],[223709.27035805717,6757365.615431988],[223699.58703686317,6757372.514165271],[223702.77741895273,6757376.979133285],[223704.44396561664,6757375.830195446],[223715.68971091427,6757391.579041661],[223714.0255916416,6757392.761318046],[223717.1931163489,6757397.226333728],[223726.8695568709,6757390.327871283],[223724.5083802602,6757386.973481099],[223724.7011528573,6757386.837060633]]]]},"properties":{"pk":906,"id_way":69943041,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223705.49706391356,6757999.666703305],[223710.44288964733,6758008.42626739],[223718.48300588652,6758003.838191971],[223713.50790714167,6757995.081005637],[223705.49706391356,6757999.666703305]]]]},"properties":{"pk":907,"id_way":69943079,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223978.53871255997,6757641.066917909],[223973.68082655585,6757632.147758996],[223968.76770942076,6757634.813521864],[223969.24429006566,6757635.548393506],[223970.1076903918,6757635.120780755],[223974.7445227026,6757642.908329002],[223978.53871255997,6757641.066917909]]]]},"properties":{"pk":908,"id_way":69943083,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223881.44553237097,6758138.308969846],[223866.63740742116,6758141.542847257],[223868.15143072605,6758148.176689233],[223882.39517791517,6758144.930978593],[223885.13741242632,6758137.4908091575],[223881.44553237097,6758138.308969846]]]]},"properties":{"pk":909,"id_way":69943113,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224052.37566898493,6758544.132623942],[224045.0150454874,6758540.493535045],[224040.43655474947,6758549.631878153],[224047.79608278995,6758553.347279653],[224052.37566898493,6758544.132623942]]]]},"properties":{"pk":910,"id_way":69943117,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223829.29927544613,6757849.243958887],[223841.05262723577,6757865.734653451],[223847.97796058387,6757861.190326098],[223836.83810399956,6757844.275008407],[223829.29927544613,6757849.243958887]]]]},"properties":{"pk":911,"id_way":69943121,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224027.57591945244,6757552.299188009],[224031.8709404272,6757560.062262157],[224037.83655166742,6757556.700597655],[224033.44698986306,6757549.04296969],[224027.57591945244,6757552.299188009]]]]},"properties":{"pk":912,"id_way":69943125,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224064.201502254,6758020.213846768],[224085.43710360743,6758028.046429322],[224087.35904747748,6758022.7132649785],[224066.07144633017,6758015.072519955],[224064.201502254,6758020.213846768]]]]},"properties":{"pk":913,"id_way":69943166,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223969.08988746564,6757873.330967768],[223975.2404506832,6757861.50926424],[223962.16401529434,6757854.313147672],[223955.74857146828,6757866.597541947],[223969.08988746564,6757873.330967768]]]]},"properties":{"pk":914,"id_way":69943216,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223885.75459462174,6757627.562547825],[223887.9593588274,6757625.98267291],[223884.50840338902,6757621.083806938],[223882.26275429083,6757622.699178225],[223885.75459462174,6757627.562547825]]]]},"properties":{"pk":915,"id_way":69943219,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223929.88450775077,6758129.601341533],[223941.97827282434,6758133.826447713],[223942.96101936532,6758131.018241352],[223946.7153063851,6758132.253921849],[223948.34549014788,6758127.778588358],[223932.52313408736,6758122.446813807],[223929.88450775077,6758129.601341533]]]]},"properties":{"pk":916,"id_way":69943258,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223726.90861649037,6758073.921084966],[223727.6193181622,6758073.743625845],[223727.86406507023,6758074.073177742],[223732.03965621002,6758081.38045897],[223732.03991132334,6758081.926572639],[223731.5659770445,6758082.257837434],[223737.17210609108,6758092.2538474845],[223748.0550732161,6758086.097695701],[223744.77547132428,6758080.209350787],[223752.95762918497,6758075.603007374],[223743.55593938677,6758059.043405962],[223736.7199462538,6758062.857417724],[223736.96605716948,6758062.066142765],[223736.50243684952,6758061.275714918],[223735.77948663695,6758061.0526808975],[223734.43035005385,6758061.832602472],[223732.10171142538,6758057.7620636895],[223721.3009201445,6758063.922344595],[223726.90861649037,6758073.921084966]]]]},"properties":{"pk":917,"id_way":69943260,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223546.64471974366,6757565.888935616],[223545.39067551933,6757559.569965381],[223542.56622137365,6757560.120990932],[223543.7624295962,6757566.445186987],[223546.64471974366,6757565.888935616]]]]},"properties":{"pk":918,"id_way":69943265,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223724.8318867248,6757854.484920065],[223729.9978540229,6757851.087358572],[223720.98724957654,6757837.45517972],[223715.728189198,6757840.89358946],[223724.8318867248,6757854.484920065]]]]},"properties":{"pk":919,"id_way":69943311,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223569.11984323367,6757347.1776570035],[223577.67447041895,6757341.180935645],[223567.27772576833,6757326.43264374],[223554.28233589107,6757335.694233826],[223561.1913261261,6757345.263562646],[223565.43067913566,6757342.190800171],[223569.11984323367,6757347.1776570035]]]]},"properties":{"pk":920,"id_way":69943364,"height":15.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223812.81343572104,6758571.813413624],[223810.55450746912,6758571.2248297315],[223808.83062350604,6758576.055507543],[223811.24039693875,6758576.789041659],[223812.81343572104,6758571.813413624]]]]},"properties":{"pk":921,"id_way":69943401,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223743.63884402317,6757271.601731378],[223747.2710815855,6757276.699057867],[223757.57294394728,6757269.448087381],[223750.1900374554,6757258.969941261],[223746.8249258783,6757261.335643954],[223750.57587668853,6757266.638858024],[223743.63884402317,6757271.601731378]]]]},"properties":{"pk":922,"id_way":69943409,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223810.76405002177,6758105.13091852],[223816.0905946961,6758114.605670934],[223823.7749636532,6758110.181315723],[223822.4588663337,6758107.904034724],[223820.64560447852,6758108.920334642],[223816.63612172953,6758101.809550942],[223810.76405002177,6758105.13091852]]]]},"properties":{"pk":923,"id_way":69943458,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223572.93979216585,6758136.961747062],[223551.15510456116,6758149.227908022],[223591.6779767347,6758221.135184779],[223612.1236316492,6758209.455130083],[223627.25338863558,6758194.735643245],[223624.11284086455,6758189.105192799],[223643.8209641375,6758178.005265163],[223637.98782353094,6758167.657411439],[223633.6626924412,6758170.135732381],[223630.3304619102,6758164.251190594],[223623.80362067602,6758167.926772681],[223627.14030349543,6758173.776792792],[223594.0864378738,6758192.398196787],[223595.0613305975,6758194.136347351],[223591.7451361319,6758196.004180431],[223583.50563651233,6758181.406369359],[223585.25298702868,6758180.417715764],[223583.28355442715,6758176.879886821],[223581.53632018046,6758177.856780844],[223575.74683551586,6758167.6116533745],[223574.0045271913,6758168.566146226],[223571.0101875022,6758163.242833567],[223583.7254032957,6758156.118374944],[223572.93979216585,6758136.961747062]]]]},"properties":{"pk":924,"id_way":69943459,"height":22.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224038.89219777353,6757591.643928777],[224043.92792178868,6757588.867879486],[224042.55671804832,6757586.473138498],[224037.50994852555,6757589.207166472],[224038.89219777353,6757591.643928777]]]]},"properties":{"pk":925,"id_way":69943468,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224033.49480553187,6757965.12835704],[224031.19466426133,6757964.283029199],[224027.39413372372,6757974.438775394],[224029.8117251225,6757975.287565502],[224033.49480553187,6757965.12835704]]]]},"properties":{"pk":926,"id_way":69943521,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223935.70630037598,6757794.712646427],[223945.8302456627,6757790.929696701],[223944.07109919353,6757786.289065935],[223950.96513516273,6757781.496745183],[223944.7327647185,6757772.51977521],[223930.93968997942,6757781.993527602],[223935.70630037598,6757794.712646427]]]]},"properties":{"pk":927,"id_way":69943579,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223710.59680103417,6757290.891219607],[223702.6960063649,6757296.399776472],[223708.01909466012,6757303.91156496],[223715.92014701644,6757298.315657621],[223710.59680103417,6757290.891219607]]]]},"properties":{"pk":928,"id_way":69943584,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223578.87891137492,6758364.112787425],[223579.98449406595,6758357.562982334],[223571.20836786978,6758356.037216038],[223570.13522980575,6758362.627937329],[223578.87891137492,6758364.112787425]]]]},"properties":{"pk":929,"id_way":69943682,"height":11.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224212.66800038223,6758635.769710437],[224212.1208834376,6758636.941171231],[224224.0116259298,6758642.5261855805],[224239.22988010544,6758610.938827574],[224227.54711393232,6758605.151643637],[224212.66800038223,6758635.769710437]]]]},"properties":{"pk":930,"id_way":69943685,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223558.150794802,6757902.191997785],[223555.75731837467,6757898.269054196],[223554.75795223116,6757899.5626706155],[223561.34664227467,6757910.6518394705],[223569.49985936817,6757905.954270012],[223564.99601063787,6757898.173405329],[223558.150794802,6757902.191997785]]]]},"properties":{"pk":931,"id_way":69943689,"height":10.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223732.95695549186,6758462.831957648],[223739.7173528425,6758462.913943834],[223739.9072075968,6758454.069226948],[223733.11671120307,6758453.978824411],[223732.95695549186,6758462.831957648]]]]},"properties":{"pk":932,"id_way":69943766,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223716.87289916546,6757824.480829252],[223709.21995928767,6757812.946337561],[223703.0184357318,6757817.007089526],[223710.6982906408,6757828.506595326],[223716.87289916546,6757824.480829252]]]]},"properties":{"pk":933,"id_way":69943771,"height":12.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223831.74444631796,6757425.5839441065],[223811.3537649651,6757395.684145928],[223801.38925808825,6757380.327872227],[223788.21380050463,6757389.670100359],[223832.9533365683,6757455.028829781],[223845.76495434638,6757446.390252248],[223831.74444631796,6757425.5839441065]]]]},"properties":{"pk":934,"id_way":69943775,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223538.4776125752,6757341.111595042],[223551.90473766712,6757331.802049123],[223548.44344088912,6757326.639653226],[223535.37797758164,6757335.8769396255],[223525.0923810919,6757339.107431196],[223527.0053082736,6757344.776948399],[223538.4776125752,6757341.111595042]]]]},"properties":{"pk":935,"id_way":69943800,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223698.33097304267,6758218.172157849],[223695.3702792915,6758225.444103081],[223696.9707749869,6758226.084108291],[223695.8789254635,6758228.743689131],[223694.2873551977,6758228.19285086],[223688.85651329727,6758242.064087648],[223690.4251406235,6758242.66276996],[223689.3055199813,6758245.371414239],[223687.73620148472,6758244.807990996],[223684.8323308885,6758252.363775377],[223694.11677569538,6758255.74387947],[223707.28976340423,6758221.751971872],[223698.33097304267,6758218.172157849]]]]},"properties":{"pk":936,"id_way":69943813,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223872.51906041944,6758092.969137839],[223867.595427314,6758084.374205418],[223854.78830958877,6758091.555593469],[223859.6519025227,6758100.23230201],[223872.51906041944,6758092.969137839]]]]},"properties":{"pk":937,"id_way":69943817,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224119.3503365016,6757249.015622555],[224127.86888941345,6757252.739030603],[224117.9146113225,6757226.066530427],[224110.0177371989,6757228.994649951],[224109.45646749376,6757230.26745323],[224107.4494719265,6757229.515845473],[224104.5190632973,6757236.361377437],[224107.50518160788,6757237.870365226],[224106.22739046707,6757240.874259164],[224109.11865583947,6757242.455858983],[224108.01647233847,6757245.374896237],[224110.79646427344,6757246.844767574],[224109.61072896255,6757249.998780904],[224113.90479981693,6757251.826492768],[224114.3521670647,6757250.923924076],[224119.3503365016,6757249.015622555]]]]},"properties":{"pk":938,"id_way":69943824,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223819.51511748438,6757907.480147504],[223837.66527633238,6757897.304146261],[223833.66116030066,6757890.240511202],[223828.38238389394,6757893.180828353],[223830.38359248565,6757896.7415655],[223826.06154265843,6757899.192844598],[223824.0569946611,6757895.597703886],[223815.57115194938,6757900.346008711],[223819.51511748438,6757907.480147504]]]]},"properties":{"pk":939,"id_way":69943860,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224027.22543779225,6757715.241353855],[224024.20511971158,6757716.885469798],[224026.8859141632,6757721.849422181],[224029.85042488333,6757720.3263210775],[224027.22543779225,6757715.241353855]]]]},"properties":{"pk":940,"id_way":69943905,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223879.65769046245,6758643.5942414],[223904.17462164882,6758647.099355537],[223907.77772746398,6758621.700936582],[223883.2063961608,6758618.165356769],[223879.65769046245,6758643.5942414]]]]},"properties":{"pk":941,"id_way":69943954,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223838.4154929743,6757924.439822004],[223843.1875236205,6757933.078578942],[223853.29936670285,6757927.35375021],[223848.38243231023,6757918.836024243],[223838.4154929743,6757924.439822004]]]]},"properties":{"pk":942,"id_way":69943960,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224051.40122321114,6757602.023990884],[224048.4884370828,6757596.907571321],[224043.4144767557,6757599.687708668],[224044.98700252268,6757602.509274454],[224051.40122321114,6757602.023990884]]]]},"properties":{"pk":943,"id_way":69943964,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223824.91963663907,6758181.214167919],[223825.49295877814,6758183.896038117],[223830.46666947223,6758181.398598023],[223829.86581673162,6758178.557821065],[223824.91963663907,6758181.214167919]]]]},"properties":{"pk":944,"id_way":69944002,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224025.04171183667,6758037.0909980405],[224029.41069610525,6758025.005350958],[224003.2992536643,6758015.933982082],[224000.14086611793,6758025.619701777],[224000.4355247967,6758025.740373359],[223999.62888031264,6758028.29779896],[224025.04171183667,6758037.0909980405]]]]},"properties":{"pk":945,"id_way":69944005,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224221.89076468957,6757643.717047409],[224219.03789540342,6757644.072228229],[224219.67807984885,6757649.491827683],[224222.5052208266,6757649.086658251],[224221.89076468957,6757643.717047409]]]]},"properties":{"pk":946,"id_way":69944012,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224018.23571709005,6758521.68137943],[224018.946730577,6758512.915486578],[224010.6832287268,6758512.276587877],[224010.08526247297,6758521.076915061],[224018.23571709005,6758521.68137943]]]]},"properties":{"pk":947,"id_way":69944044,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223761.44265969077,6758463.161954412],[223774.50600283337,6758463.306317057],[223777.21560537975,6758455.965506702],[223761.60672123297,6758450.480631773],[223761.44265969077,6758463.161954412]]]]},"properties":{"pk":948,"id_way":69944088,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224042.6941257293,6757912.270216599],[224044.6807327316,6757906.808050787],[224036.29021990285,6757903.625099481],[224034.27468525482,6757909.089737199],[224042.6941257293,6757912.270216599]]]]},"properties":{"pk":949,"id_way":69944093,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223935.248085107,6758030.0224089585],[223928.30167196773,6758033.911203383],[223931.29971226153,6758039.148829676],[223933.28026362974,6758038.002797849],[223935.248085107,6758030.0224089585]]]]},"properties":{"pk":950,"id_way":69944142,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223709.24692303332,6758382.659277946],[223706.52858525128,6758392.255618928],[223715.09721949178,6758394.746396377],[223717.84462468413,6758385.148509731],[223709.24692303332,6758382.659277946]]]]},"properties":{"pk":951,"id_way":69944144,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224123.41946393368,6757464.307772859],[224126.4896669785,6757468.689377725],[224128.8227811252,6757467.031925966],[224125.80534674082,6757462.68741413],[224123.41946393368,6757464.307772859]]]]},"properties":{"pk":952,"id_way":69944152,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223748.6182728667,6758347.530209308],[223741.9150734759,6758345.676944591],[223739.22629225475,6758355.4704195885],[223745.8417523731,6758357.330200828],[223748.6182728667,6758347.530209308]]]]},"properties":{"pk":953,"id_way":69944191,"height":13.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224058.28018468665,6758598.466809577],[224068.47835793754,6758578.056274381],[224057.65454982105,6758572.66878045],[224047.7522289696,6758592.61711547],[224058.28018468665,6758598.466809577]]]]},"properties":{"pk":954,"id_way":69944193,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223662.21238349206,6757944.068195589],[223671.1154056695,6757938.272567639],[223666.50394806286,6757931.351754892],[223657.56900197046,6757937.117121511],[223662.21238349206,6757944.068195589]]]]},"properties":{"pk":955,"id_way":69944196,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223707.24913269567,6757443.660547784],[223704.95112852758,6757445.282446037],[223707.11645783696,6757448.399900575],[223709.41217470382,6757446.746823504],[223707.24913269567,6757443.660547784]]]]},"properties":{"pk":956,"id_way":69944248,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223961.19760963056,6757965.01738714],[223959.0686433598,6757970.745211948],[223959.2297789404,6757971.4844516255],[223972.72750154318,6757976.438488297],[223975.06251936933,6757970.189089837],[223961.19760963056,6757965.01738714]]]]},"properties":{"pk":957,"id_way":69944289,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223926.04645634675,6758283.2446587235],[223920.78678142148,6758281.299217311],[223920.8432752604,6758281.072586273],[223913.4515635409,6758278.426090444],[223911.46511349955,6758283.888690024],[223924.13358201718,6758288.500676901],[223926.04645634675,6758283.2446587235]]]]},"properties":{"pk":958,"id_way":69944316,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223603.73141115913,6758118.441799845],[223600.60796857558,6758112.725427872],[223597.90965122692,6758114.272557038],[223601.1490425075,6758119.883318935],[223603.73141115913,6758118.441799845]]]]},"properties":{"pk":959,"id_way":69944318,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223913.485995833,6757253.359653124],[223921.09083947874,6757247.999012399],[223916.77720024023,6757241.832073546],[223909.14094064359,6757247.163144886],[223913.485995833,6757253.359653124]]]]},"properties":{"pk":960,"id_way":69944323,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223990.12774909692,6758457.822817235],[223988.11626578146,6758465.72207479],[223996.86539109243,6758467.9304997865],[223995.02778497225,6758458.98235608],[223990.12774909692,6758457.822817235]]]]},"properties":{"pk":961,"id_way":69944341,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224084.2796302716,6757847.395271827],[224079.67249442014,6757860.068535874],[224087.94531267227,6757863.030138415],[224092.5247574884,6757850.380806227],[224084.2796302716,6757847.395271827]]]]},"properties":{"pk":962,"id_way":69944344,"height":10.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223764.64780885726,6758634.2630326785],[223758.3876966048,6758651.968022095],[223759.48833269457,6758653.900093146],[223773.22383538363,6758655.923143353],[223773.94375993084,6758650.867213497],[223768.32851870096,6758650.112075943],[223772.89658178345,6758637.214984489],[223764.64780885726,6758634.2630326785]]]]},"properties":{"pk":963,"id_way":69944376,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223913.47817238697,6757708.840921383],[223904.5044622924,6757691.570941787],[223897.45443180596,6757694.173318509],[223903.80382703827,6757710.908992788],[223904.9206391745,6757712.368876051],[223906.5580040663,6757712.363715873],[223913.47817238697,6757708.840921383]]]]},"properties":{"pk":964,"id_way":69944381,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223789.14821994066,6757925.235994666],[223783.27166119506,6757928.601300569],[223785.09425569128,6757931.827853742],[223790.9708117736,6757928.462549676],[223789.14821994066,6757925.235994666]]]]},"properties":{"pk":965,"id_way":69944412,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223733.45692279507,6758545.108309994],[223731.3689652914,6758544.418818242],[223730.18207833957,6758547.707663958],[223729.1595534629,6758552.621465882],[223730.62872081724,6758552.869220974],[223733.45692279507,6758545.108309994]]]]},"properties":{"pk":966,"id_way":69944413,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224150.02984486066,6757622.7652320415],[224148.53004015057,6757617.260282135],[224146.67195363244,6757611.731023732],[224144.53773653595,6757606.409900515],[224135.02817232002,6757610.654002043],[224136.73098679064,6757614.563785741],[224136.4028703571,6757614.759708413],[224138.52750258194,6757621.109355398],[224138.8535969106,6757620.992430911],[224139.91772171907,6757625.308715222],[224150.02984486066,6757622.7652320415]]]]},"properties":{"pk":967,"id_way":69944415,"height":15.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223620.06159559495,6758291.734054654],[223625.39843947045,6758284.396080383],[223624.10821869178,6758280.50663907],[223614.65874148655,6758277.062715414],[223611.45554010393,6758285.790585367],[223612.53214319205,6758286.202179409],[223620.06159559495,6758291.734054654]]]]},"properties":{"pk":968,"id_way":69944437,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224134.6675994096,6758539.924053169],[224139.11275349153,6758537.582020352],[224118.02448622935,6758500.699371954],[224113.4594184702,6758503.246966716],[224134.6675994096,6758539.924053169]]]]},"properties":{"pk":969,"id_way":69944438,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223654.2777996091,6757785.504116446],[223662.08174117183,6757796.549414854],[223660.27586501327,6757797.667531841],[223655.46156069692,6757801.113981798],[223660.87192866526,6757809.009347196],[223671.88651543757,6757801.409892941],[223658.62530858023,6757782.467795524],[223654.2777996091,6757785.504116446]]]]},"properties":{"pk":970,"id_way":69944440,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223906.54978892498,6757601.095997055],[223893.67086739207,6757582.789870936],[223877.4035598632,6757594.167214547],[223883.28384986627,6757602.437579622],[223890.96412737184,6757597.0797788],[223898.019715491,6757607.197897548],[223906.54978892498,6757601.095997055]]]]},"properties":{"pk":971,"id_way":69944442,"height":16.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224087.78926959043,6758012.078878711],[224096.70815888644,6758015.310967688],[224100.5427672825,6758004.806530699],[224097.0592143504,6758003.553401912],[224096.1686671652,6758005.844118262],[224090.78590279425,6758003.860553206],[224087.78926959043,6758012.078878711]]]]},"properties":{"pk":972,"id_way":69944467,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223875.37437966166,6758494.668921656],[223868.2002678606,6758513.766390296],[223878.69509675386,6758516.848809687],[223889.1601473985,6758489.315288278],[223872.3989175105,6758483.073591324],[223868.9816669926,6758492.208829976],[223875.37437966166,6758494.668921656]]]]},"properties":{"pk":973,"id_way":69944487,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223977.85384185196,6757894.563762096],[223979.81241448363,6757889.226039943],[223977.16107697852,6757888.221756107],[223975.17759124856,6757893.603265848],[223977.85384185196,6757894.563762096]]]]},"properties":{"pk":974,"id_way":69944490,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223611.63446655704,6758106.522597423],[223614.842786768,6758112.200696822],[223617.54000893314,6758110.724727215],[223614.3952702326,6758105.0108812675],[223611.63446655704,6758106.522597423]]]]},"properties":{"pk":975,"id_way":69944512,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223780.80594590103,6758095.106591645],[223781.69383552586,6758096.606623709],[223784.66056463058,6758094.902954937],[223783.80502562012,6758093.433372925],[223793.02002863228,6758088.196926024],[223787.63633166064,6758078.836473671],[223770.0256124038,6758088.824149462],[223775.32649746415,6758098.256745193],[223780.80594590103,6758095.106591645]]]]},"properties":{"pk":976,"id_way":69944513,"height":12.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223538.81447888125,6757519.469538257],[223545.37455462347,6757518.062727466],[223543.76968715576,6757510.274166157],[223537.09464036123,6757511.527920548],[223538.81447888125,6757519.469538257]]]]},"properties":{"pk":977,"id_way":69944515,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223596.35270770686,6758510.419655434],[223585.12260712648,6758509.355674314],[223581.5265765543,6758531.666404286],[223580.7594912844,6758531.550310329],[223580.701679,6758531.947520524],[223592.4339779156,6758533.400689304],[223596.35270770686,6758510.419655434]]]]},"properties":{"pk":978,"id_way":69944535,"height":21.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223948.2747054168,6757705.4324791],[223951.9029522685,6757711.983975412],[223955.36810871298,6757710.210763063],[223956.51991155653,6757712.270741579],[223963.01409996997,6757709.097893133],[223958.41682327943,6757699.553032742],[223948.2747054168,6757705.4324791]]]]},"properties":{"pk":979,"id_way":69944561,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223831.9437395933,6758598.862404422],[223845.60340822118,6758603.829379207],[223849.6086233268,6758593.36959094],[223835.59102462124,6758589.014519249],[223831.9437395933,6758598.862404422]]]]},"properties":{"pk":980,"id_way":69944582,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223775.8022614135,6757945.615173409],[223773.98277674746,6757942.344977378],[223768.0521961591,6757945.746461671],[223769.84360709344,6757948.977000116],[223775.8022614135,6757945.615173409]]]]},"properties":{"pk":981,"id_way":69944584,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224082.14039286558,6757695.974386714],[224085.76634733204,6757685.743179902],[224078.19320520287,6757682.920926193],[224089.41614733357,6757651.697155882],[224080.91484764835,6757648.610042595],[224068.66452152835,6757683.248206159],[224076.35646073543,6757686.307104918],[224073.80982477422,6757692.930509074],[224082.14039286558,6757695.974386714]]]]},"properties":{"pk":982,"id_way":69944587,"height":9.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223655.3932428039,6758158.551689245],[223659.76925880605,6758163.114138291],[223661.58953978322,6758161.32442404],[223657.1473360942,6758156.842113584],[223655.3932428039,6758158.551689245]]]]},"properties":{"pk":983,"id_way":69944607,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224014.58480531813,6758064.199791303],[224007.6156372599,6758061.695996917],[224004.87019936557,6758061.001477267],[224004.04704795676,6758063.404449124],[224004.428388177,6758064.553186536],[224006.4341242236,6758065.28129967],[224004.37849153753,6758071.361359567],[224011.20318858777,6758073.446155694],[224014.58480531813,6758064.199791303]]]]},"properties":{"pk":984,"id_way":69944608,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223585.95070608292,6757378.614245682],[223591.6946862236,6757386.507347564],[223602.62377727768,6757378.814290554],[223601.10227118654,6757376.611272421],[223603.0788607308,6757375.083926177],[223597.20336484257,6757367.621102329],[223591.25213391287,6757372.120283468],[223592.52142329517,6757373.858749162],[223585.95070608292,6757378.614245682]]]]},"properties":{"pk":985,"id_way":69944610,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224145.9998599202,6757477.778788888],[224139.6082213949,6757482.228383126],[224145.25504110803,6757490.216215504],[224151.60928220415,6757485.758844597],[224145.9998599202,6757477.778788888]]]]},"properties":{"pk":986,"id_way":69944612,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223936.7219913169,6758512.03901278],[223932.95044686928,6758519.51733458],[223943.86380142882,6758524.975513689],[223947.64208742784,6758517.584215411],[223936.7219913169,6758512.03901278]]]]},"properties":{"pk":987,"id_way":69944629,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224117.3870000174,6757990.694900713],[224114.8844015652,6757989.766118562],[224112.95501919632,6757994.988985145],[224115.52217013566,6757995.913437587],[224117.3870000174,6757990.694900713]]]]},"properties":{"pk":988,"id_way":69944632,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223865.46720880544,6757825.300140392],[223869.98853328126,6757831.465968304],[223879.62337481228,6757825.497929835],[223877.06536378743,6757819.694848475],[223876.78035446117,6757819.20418008],[223876.28307420755,6757818.795795951],[223875.8599090118,6757818.720243712],[223874.88497613603,6757819.024464697],[223865.46720880544,6757825.300140392]]]]},"properties":{"pk":989,"id_way":69944657,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223683.72221415528,6758421.273167942],[223668.0374582275,6758417.523372816],[223672.64789015416,6758398.623788053],[223687.59478877636,6758402.24186044],[223690.53932049416,6758387.828283679],[223662.5905000819,6758380.95185143],[223659.08105863963,6758395.358353376],[223662.19051179942,6758396.155180409],[223659.39532013488,6758407.293523597],[223656.35039854288,6758406.536477922],[223651.64910461515,6758425.719079133],[223681.3505491067,6758432.765876662],[223683.72221415528,6758421.273167942]]]]},"properties":{"pk":990,"id_way":69944680,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223600.96637281077,6757939.750084371],[223598.5463879506,6757948.083212842],[223609.7492427173,6757951.220543348],[223613.94376598272,6757949.096226375],[223617.24371601437,6757937.427439655],[223608.25916812214,6757934.824287038],[223606.99650802006,6757939.149324267],[223607.35065202284,6757939.343471486],[223606.61615742257,6757941.844931489],[223604.19196190196,6757941.1625709655],[223604.24688537003,6757940.7222444005],[223600.96637281077,6757939.750084371]]]]},"properties":{"pk":991,"id_way":69944681,"height":13.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224170.05336370072,6757239.725662413],[224168.49538174094,6757235.088689029],[224165.6049529238,6757236.310251364],[224163.53944614343,6757231.880545213],[224153.23011355725,6757235.702773965],[224156.09945226717,6757243.259380079],[224166.6217884102,6757239.334799732],[224167.23838328652,6757240.83277134],[224170.05336370072,6757239.725662413]]]]},"properties":{"pk":992,"id_way":69944685,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223701.23712382218,6758322.366695528],[223698.9848740997,6758328.979393401],[223702.55793035493,6758330.301669298],[223709.4230732316,6758312.016048299],[223697.8640877492,6758307.718540396],[223694.33439188948,6758317.967693428],[223694.7800937358,6758318.042207618],[223694.6512590312,6758318.4173117485],[223700.97707484083,6758320.800670077],[223700.72756270805,6758321.8606651295],[223701.23712382218,6758322.366695528]]]]},"properties":{"pk":993,"id_way":69944708,"height":15.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223574.8136606919,6757916.856281958],[223579.93664322962,6757925.536811656],[223582.70607578682,6757923.959609763],[223583.05974456226,6757924.710543088],[223589.60680783485,6757920.9172941735],[223584.01094736374,6757911.594608455],[223574.8136606919,6757916.856281958]]]]},"properties":{"pk":994,"id_way":69944711,"height":9.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223765.49981584304,6757837.677768055],[223759.10655548712,6757826.349679789],[223746.77244149309,6757833.492120282],[223752.63481068535,6757844.93964718],[223765.49981584304,6757837.677768055]]]]},"properties":{"pk":995,"id_way":69944762,"height":16.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223831.79645807506,6757717.311933249],[223842.16118159806,6757709.71405937],[223836.94392806754,6757702.314713865],[223826.4859390714,6757709.7665063],[223831.79645807506,6757717.311933249]]]]},"properties":{"pk":996,"id_way":69944764,"height":10.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223493.68757875005,6757473.398574665],[223499.53513922082,6757471.99817534],[223498.27978843515,6757466.227323435],[223503.07251713207,6757464.970711106],[223500.94827934177,6757455.28392513],[223496.0082090965,6757456.423728928],[223496.1591528466,6757457.365827281],[223490.32854435645,6757459.006001958],[223493.68757875005,6757473.398574665]]]]},"properties":{"pk":997,"id_way":69944788,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223773.39193401576,6758296.312073037],[223795.67615094915,6758236.620728766],[223780.5356607965,6758231.005959683],[223758.42912219738,6758290.5844316855],[223773.39193401576,6758296.312073037]]]]},"properties":{"pk":998,"id_way":69944795,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223952.74391531094,6758067.869695187],[223963.83192352153,6758072.399528602],[223972.70082249184,6758074.131931437],[223973.98934408577,6758070.010885463],[223963.77479783713,6758066.631502057],[223964.6417973409,6758064.203244031],[223965.7364410206,6758064.433986097],[223965.70219285614,6758064.675906097],[223975.6757177619,6758067.375002711],[223976.12170931222,6758065.911372652],[223979.82211649712,6758066.950518076],[223980.3288748383,6758065.326732583],[223975.9764679456,6758064.259978517],[223975.97819017805,6758064.099964125],[223956.28418208042,6758058.337705653],[223952.74391531094,6758067.869695187]]]]},"properties":{"pk":999,"id_way":69944796,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224406.27343323166,6757475.90061054],[224405.27776466872,6757475.310982302],[224404.44733016103,6757475.074495522],[224402.7345108606,6757475.158335126],[224401.20640106284,6757475.923428962],[224400.42139426572,6757476.772111735],[224399.72477753018,6757478.30422808],[224399.66382219113,6757479.4670125535],[224400.0106458081,6757480.852272482],[224401.04962760792,6757482.24894345],[224402.25423246532,6757482.974978149],[224403.35770472817,6757483.246001376],[224404.80617641617,6757483.140113963],[224405.85074823158,6757482.7186589055],[224407.11615535704,6757481.518193362],[224407.6449276174,6757480.517512888],[224407.87836919024,6757479.396609686],[224407.7050190312,6757477.980643732],[224407.17555593498,6757476.814504201],[224407.90347126324,6757476.201274081],[224407.20138628894,6757475.364081334],[224406.44570806928,6757476.02466826],[224406.27343323166,6757475.90061054]]]]},"properties":{"pk":1000,"id_way":69944800,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223867.95461246584,6758467.125655149],[223874.9099761007,6758448.1756413765],[223850.5378939296,6758439.192751225],[223843.61226026816,6758458.140160512],[223867.95461246584,6758467.125655149]]]]},"properties":{"pk":1001,"id_way":69944817,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224197.25696643264,6757797.936709684],[224198.11020916162,6757798.258368425],[224195.40303864272,6757805.787310253],[224204.21034270583,6757808.94019571],[224217.27448841484,6757772.855464428],[224208.4950004273,6757769.591194972],[224206.79921087675,6757774.286171026],[224205.79285147914,6757773.921688587],[224203.21038693076,6757781.161730963],[224204.21263832718,6757781.560281432],[224200.54435131053,6757791.738731701],[224199.5952106751,6757791.3363109715],[224197.25696643264,6757797.936709684]]]]},"properties":{"pk":1002,"id_way":69944820,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223673.8098892831,6757748.402749131],[223680.35830166694,6757748.219832761],[223682.34510322177,6757751.979388183],[223686.9361315152,6757749.412125174],[223684.5502162959,6757745.945459773],[223684.92417817598,6757742.111630585],[223686.3212196524,6757741.105381466],[223688.08438795968,6757742.143645809],[223689.1222156772,6757744.262739532],[223688.61298519862,6757746.22919165],[223693.14514666804,6757754.296261597],[223697.68359764924,6757751.760876983],[223688.40359238346,6757734.611845599],[223689.28476811826,6757733.899969488],[223685.73461156266,6757728.8469974585],[223668.57676222702,6757740.74434426],[223673.8098892831,6757748.402749131]]]]},"properties":{"pk":1003,"id_way":69944844,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223645.6680769923,6757329.701723324],[223654.51790417978,6757323.360568308],[223645.77496811567,6757310.941287686],[223636.83195711873,6757317.323025453],[223645.6680769923,6757329.701723324]]]]},"properties":{"pk":1004,"id_way":69944846,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223727.9274647443,6758030.809389196],[223720.56963797976,6758017.651296776],[223701.32873743027,6758028.572896737],[223716.21428198752,6758055.1225059135],[223735.42766565716,6758044.324775019],[223727.9274647443,6758030.809389196]]]]},"properties":{"pk":1005,"id_way":69944867,"height":13.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223972.2349122627,6757629.053760926],[223973.87623189515,6757632.084583529],[223994.39365155937,6757621.552299722],[223990.73807347735,6757614.411974552],[223981.8151343351,6757619.4287201455],[223983.64505010846,6757622.995058132],[223972.2349122627,6757629.053760926]]]]},"properties":{"pk":1006,"id_way":69944869,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223844.2268464137,6758201.303654632],[223847.70342689054,6758216.5977091715],[223853.31565921078,6758215.390577942],[223849.83576762615,6758200.0536840465],[223844.2268464137,6758201.303654632]]]]},"properties":{"pk":1007,"id_way":69944890,"height":3.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223842.9642565936,6757840.228414958],[223854.07367747024,6757857.224041277],[223859.80136845753,6757853.436691126],[223854.02128076725,6757844.696215388],[223860.39462482685,6757840.480634149],[223859.00169833383,6757838.353789971],[223854.66409106136,6757832.5002991315],[223842.9642565936,6757840.228414958]]]]},"properties":{"pk":1008,"id_way":69944893,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223973.04501184786,6757551.418655964],[223990.1939103722,6757539.436546084],[223978.82679743954,6757523.348795242],[223963.1544205322,6757534.26534695],[223963.7755874853,6757535.133228837],[223963.2801460059,6757535.447105039],[223963.11451132066,6757536.393387638],[223963.73559937696,6757537.338685209],[223963.467972443,6757537.537890498],[223973.04501184786,6757551.418655964]]]]},"properties":{"pk":1009,"id_way":69944895,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224040.04651794146,6758028.687272984],[224033.8289940088,6758045.514712468],[224042.28406374683,6758048.506733756],[224048.43799844658,6758031.71693429],[224040.04651794146,6758028.687272984]]]]},"properties":{"pk":1010,"id_way":69944935,"height":10.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223803.7575921146,6757822.15825513],[223802.39196354905,6757820.070535626],[223798.40782669865,6757822.723913802],[223799.80054071214,6757824.772415968],[223803.7575921146,6757822.15825513]]]]},"properties":{"pk":1011,"id_way":69944981,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223956.76356760485,6758112.0463069305],[223959.17350940924,6758104.779636948],[223941.27388596832,6758098.800074289],[223938.5826947068,6758106.035945633],[223956.76356760485,6758112.0463069305]]]]},"properties":{"pk":1012,"id_way":69945021,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223539.90331224955,6757557.50376815],[223540.42841794292,6757560.348724827],[223544.0497314455,6757559.643820659],[223543.47575323074,6757556.802914299],[223539.90331224955,6757557.50376815]]]]},"properties":{"pk":1013,"id_way":69945028,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224036.3974307065,6758632.123074089],[224050.56035493384,6758638.077025379],[224056.51416978333,6758624.453193196],[224048.88840370256,6758621.270186102],[224044.81266386175,6758630.472387335],[224038.33740933772,6758627.7290962385],[224036.3974307065,6758632.123074089]]]]},"properties":{"pk":1014,"id_way":69945079,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223708.62204475005,6757889.800891295],[223722.47918783777,6757879.95598265],[223717.1636068573,6757872.521392707],[223703.36215687357,6757882.416593922],[223708.62204475005,6757889.800891295]]]]},"properties":{"pk":1015,"id_way":69945081,"height":15.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223575.11299757633,6757525.064536474],[223562.67550020627,6757527.684216977],[223564.63100348468,6757536.8571502855],[223578.51572569786,6757533.847336515],[223575.11299757633,6757525.064536474]]]]},"properties":{"pk":1016,"id_way":69945106,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223781.64624954746,6757252.513688642],[223776.80458549067,6757245.631771373],[223769.45252573714,6757251.028729268],[223765.618233069,6757245.730501202],[223758.89957596612,6757250.539822212],[223767.40282151665,6757262.599945656],[223781.64624954746,6757252.513688642]]]]},"properties":{"pk":1017,"id_way":69945129,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223957.35483016714,6758224.399411261],[223960.24045470546,6758216.628998953],[223955.73579485886,6758207.739577165],[223944.76734319906,6758213.154666861],[223951.79213994308,6758227.170641274],[223957.35483016714,6758224.399411261]]]]},"properties":{"pk":1018,"id_way":69945150,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223805.3524776571,6758127.102790141],[223800.67355504865,6758129.100523169],[223801.77705200834,6758131.652128841],[223806.48010574747,6758129.609952106],[223805.3524776571,6758127.102790141]]]]},"properties":{"pk":1019,"id_way":69945151,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224032.6692477862,6757581.539069769],[224033.9599124338,6757584.047672092],[224039.44374253484,6757580.992594178],[224038.04363962842,6757578.5234268475],[224032.6692477862,6757581.539069769]]]]},"properties":{"pk":1020,"id_way":69945155,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223996.5810003812,6757950.075979599],[223995.55111751668,6757952.85442211],[224015.80906284833,6757960.131732438],[224015.85722271918,6757959.999246821],[224015.6471965256,6757959.926630798],[224016.63249600242,6757957.315194508],[224016.31648961615,6757957.199925574],[224016.4080952825,6757956.848921067],[223996.5810003812,6757950.075979599]]]]},"properties":{"pk":1021,"id_way":69945176,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223912.43340454146,6757794.267194345],[223903.3304802188,6757800.254126382],[223908.7384143794,6757808.469433007],[223913.25327123664,6757805.470812714],[223911.54387013149,6757802.822903359],[223915.8445370611,6757799.91059681],[223912.43340454146,6757794.267194345]]]]},"properties":{"pk":1022,"id_way":69945199,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223719.02451850288,6757285.018207941],[223715.24954403128,6757287.743455537],[223714.54588703063,6757286.673331619],[223712.29970364922,6757288.249756809],[223712.88691448187,6757289.283594478],[223710.7606794951,6757290.776549882],[223716.0835139286,6757298.200274443],[223724.25111472205,6757292.447898439],[223719.02451850288,6757285.018207941]]]]},"properties":{"pk":1023,"id_way":69945202,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223587.93222889674,6758488.91948699],[223579.1073130687,6758488.128385471],[223578.18508014223,6758498.438994726],[223586.9548258868,6758499.26735923],[223587.93222889674,6758488.91948699]]]]},"properties":{"pk":1024,"id_way":69945211,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223618.41862319974,6758357.911187351],[223619.2854705753,6758353.285121284],[223617.46923031213,6758352.760227275],[223619.73054239803,6758344.512148152],[223620.79017971788,6758344.901790048],[223622.6088421514,6758335.030177179],[223619.439587394,6758333.832593799],[223607.8508235487,6758331.897320017],[223603.93648642217,6758354.758624326],[223611.24150978998,6758355.984241804],[223618.41862319974,6758357.911187351]]]]},"properties":{"pk":1025,"id_way":69945294,"height":3.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223555.9929437138,6757905.434325839],[223557.50939846484,6757904.581625793],[223554.61044910696,6757899.7059304705],[223553.1943612627,6757900.843014197],[223555.9929437138,6757905.434325839]]]]},"properties":{"pk":1026,"id_way":69945301,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223790.76731181185,6758561.407026486],[223800.43011946726,6758564.254852112],[223802.65343534847,6758558.216980617],[223804.47256461723,6758557.721100115],[223813.37098698207,6758560.132450026],[223815.49513787567,6758551.991207872],[223797.51846445128,6758547.246874899],[223795.8059735048,6758548.157181968],[223790.76731181185,6758561.407026486]]]]},"properties":{"pk":1027,"id_way":69945347,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223610.13246393861,6758428.565683432],[223610.6842259406,6758423.539342432],[223609.28175791746,6758423.154036631],[223608.75779949705,6758428.46243675],[223610.13246393861,6758428.565683432]]]]},"properties":{"pk":1028,"id_way":69945349,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223590.86251269584,6757811.44964754],[223605.06939664544,6757831.932482678],[223607.78497193346,6757830.1164138615],[223593.63222525548,6757809.553419996],[223590.86251269584,6757811.44964754]]]]},"properties":{"pk":1029,"id_way":69945350,"height":3.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223669.6890184965,6758259.7947352985],[223672.871923047,6758260.959100322],[223674.98182184185,6758255.261069044],[223671.7596756758,6758253.983226768],[223669.6890184965,6758259.7947352985]]]]},"properties":{"pk":1030,"id_way":69945374,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223801.69762366984,6758118.715230724],[223797.05004992307,6758120.720551973],[223798.2079324631,6758123.3902704045],[223802.8517087679,6758121.342488184],[223801.69762366984,6758118.715230724]]]]},"properties":{"pk":1031,"id_way":69945375,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223547.51955412273,6757550.69276809],[223550.22471013427,6757550.183402647],[223549.06746081603,6757544.492141206],[223546.44481436006,6757545.036059579],[223547.51955412273,6757550.69276809]]]]},"properties":{"pk":1032,"id_way":69945377,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224088.07301507797,6757446.381211067],[224095.15968136676,6757456.45967226],[224109.25500832498,6757446.573866585],[224102.13788804025,6757436.574811863],[224088.07301507797,6757446.381211067]]]]},"properties":{"pk":1033,"id_way":69945379,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223817.47653003136,6757884.012693218],[223814.99448245767,6757879.620780401],[223806.69246813832,6757884.331128979],[223811.57903069156,6757893.173190416],[223829.6076333186,6757883.073772613],[223824.50594724793,6757874.042140141],[223819.31456093892,6757877.080059674],[223821.76899263682,6757881.587186613],[223817.47653003136,6757884.012693218]]]]},"properties":{"pk":1034,"id_way":69945406,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224008.47629457005,6757671.349766352],[224013.37601777446,6757681.028013261],[224012.66063811717,6757681.463845475],[224014.84797953427,6757685.618435688],[224008.68407166196,6757688.814021074],[224012.75305625927,6757696.859744193],[224028.72920144483,6757688.448948344],[224017.34277360296,6757666.370610107],[224008.47629457005,6757671.349766352]]]]},"properties":{"pk":1035,"id_way":69945431,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223563.45955245238,6757556.091180983],[223560.6050076779,6757556.634681225],[223561.714321989,6757562.966168312],[223564.59701766487,6757562.409847975],[223563.45955245238,6757556.091180983]]]]},"properties":{"pk":1036,"id_way":69945433,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223843.72125059014,6757907.681209389],[223844.52745681212,6757911.7413002765],[223853.47332972402,6757927.255063209],[223860.29388371273,6757923.377974203],[223849.52993260836,6757904.376072071],[223843.72125059014,6757907.681209389]]]]},"properties":{"pk":1037,"id_way":69945455,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224035.5649102539,6757597.922029034],[224040.65808166837,6757595.216340681],[224039.2549308439,6757592.705297982],[224034.21042429408,6757595.557651981],[224035.5649102539,6757597.922029034]]]]},"properties":{"pk":1038,"id_way":69945457,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223601.09804562206,6758278.082057401],[223603.11190882768,6758272.816992375],[223595.96509201525,6758270.197172438],[223585.8562648869,6758268.532234164],[223584.1570802959,6758278.718989434],[223593.81281674939,6758280.331294864],[223594.60052878375,6758275.688477244],[223601.09804562206,6758278.082057401]]]]},"properties":{"pk":1039,"id_way":69945487,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224072.64061946986,6758115.706503646],[224050.82067920704,6758108.296696294],[224044.38506207475,6758128.003259829],[224052.95551268474,6758130.8453343045],[224056.77173443383,6758119.636022044],[224069.6404525304,6758123.881929487],[224072.64061946986,6758115.706503646]]]]},"properties":{"pk":1040,"id_way":69945488,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224213.49716501829,6757650.291732358],[224212.82164558046,6757644.884304448],[224210.11830316318,6757645.247826798],[224210.73619879884,6757650.660005078],[224213.49716501829,6757650.291732358]]]]},"properties":{"pk":1041,"id_way":69945497,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223984.1196394692,6758560.127289577],[223977.76208840145,6758584.31355125],[223985.32061395195,6758586.333705147],[223991.41808912423,6758563.1902394],[223984.1196394692,6758560.127289577]]]]},"properties":{"pk":1042,"id_way":69945526,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224039.7288849186,6757867.069369029],[224031.3642928984,6757864.005055584],[224028.12965124613,6757872.811784356],[224036.4942334907,6757875.876093237],[224039.7288849186,6757867.069369029]]]]},"properties":{"pk":1043,"id_way":69945553,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223547.6144548651,6757358.495484141],[223541.46555462637,6757349.487418762],[223532.2618609894,6757354.630880322],[223525.11199188457,6757357.82009009],[223519.29509877294,6757359.752887862],[223515.2805527421,6757360.580518319],[223487.62755708856,6757361.314618138],[223487.8969605507,6757372.049090299],[223516.98986819296,6757371.087069271],[223519.61300294177,6757370.730778265],[223524.73707761551,6757369.559825482],[223529.14130231013,6757368.347436352],[223533.8139019497,6757366.345080953],[223538.22361160626,6757364.341734324],[223547.6144548651,6757358.495484141]]]]},"properties":{"pk":1044,"id_way":69945567,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223704.7128176214,6758365.361594697],[223701.4408357088,6758374.2492028205],[223704.99052844752,6758375.540434452],[223705.1835629891,6758376.145193222],[223705.5916476321,6758376.47237981],[223706.04732353587,6758376.586050843],[223706.93706585545,6758376.267375238],[223710.22369973577,6758377.479586592],[223713.4290844166,6758368.58620413],[223704.7128176214,6758365.361594697]]]]},"properties":{"pk":1045,"id_way":69945575,"height":10.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223944.4819100254,6758052.277229476],[223945.60048018198,6758049.245706685],[223936.47057369965,6758045.859502917],[223933.3704351426,6758043.152534054],[223928.1273524142,6758034.009259162],[223922.31942423465,6758037.292079205],[223934.13558741024,6758058.159624986],[223944.4819100254,6758052.277229476]]]]},"properties":{"pk":1046,"id_way":69945576,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224120.95574307692,6757466.044373441],[224123.94585896935,6757470.498638542],[224126.32665078613,6757468.805255031],[224123.25520017755,6757464.421869719],[224120.95574307692,6757466.044373441]]]]},"properties":{"pk":1047,"id_way":69945580,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223684.3317088646,6758340.1995243225],[223682.16092364985,6758346.167305051],[223690.82128476413,6758349.3521822905],[223693.04283296835,6758343.380118989],[223684.3317088646,6758340.1995243225]]]]},"properties":{"pk":1048,"id_way":69945600,"height":7.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223805.2786209028,6757908.936416845],[223799.08647920354,6757897.959401277],[223780.08207714002,6757908.650645732],[223782.14152330667,6757912.3047281485],[223790.40961791825,6757907.701426336],[223792.42547600454,6757911.354401113],[223784.21924518424,6757916.0407346785],[223786.21092685417,6757919.58798274],[223805.2786209028,6757908.936416845]]]]},"properties":{"pk":1049,"id_way":69945605,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223585.50153468433,6757463.96363031],[223600.3711866878,6757453.4238991365],[223596.27591363204,6757447.679768907],[223600.670162076,6757444.560540614],[223598.74391727473,6757441.867409226],[223594.5058635289,6757444.873741121],[223573.50401638026,6757415.437343927],[223558.75096243428,6757425.757933397],[223566.89899703194,6757437.739281578],[223564.1119357187,6757439.7141409675],[223569.39983661415,6757447.308987643],[223572.31002506247,6757445.368790288],[223585.50153468433,6757463.96363031]]]]},"properties":{"pk":1050,"id_way":69945644,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223888.55263400864,6757945.630551403],[223878.58922539427,6757927.979722705],[223842.2458829834,6757948.697270387],[223852.0945605735,6757966.401411446],[223888.55263400864,6757945.630551403]]]]},"properties":{"pk":1051,"id_way":69945670,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223881.0970554429,6757615.98345224],[223884.5551132843,6757620.80431695],[223886.82379455178,6757619.185733403],[223883.39433693653,6757614.362109813],[223881.0970554429,6757615.98345224]]]]},"properties":{"pk":1052,"id_way":69945672,"height":3.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223980.52372486173,6758065.373717897],[223980.01454280477,6758067.005269605],[223981.48467435065,6758067.428763606],[223982.0147274823,6758065.726520964],[223980.52372486173,6758065.373717897]]]]},"properties":{"pk":1053,"id_way":69945700,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223822.42696952997,6758169.433341597],[223823.0005958424,6758172.201096907],[223828.00236672477,6758169.582486178],[223827.4330122159,6758166.782287678],[223822.42696952997,6758169.433341597]]]]},"properties":{"pk":1054,"id_way":69945701,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223521.92594064667,6757456.943712607],[223520.14237137182,6757447.7781105805],[223510.23882772707,6757449.736611264],[223512.13897469448,6757458.947149046],[223521.92594064667,6757456.943712607]]]]},"properties":{"pk":1055,"id_way":69945705,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223985.71746652498,6758427.708334096],[223988.42445924607,6758427.052449677],[223986.88506643267,6758419.507377984],[223983.8277555283,6758420.277436581],[223985.71746652498,6758427.708334096]]]]},"properties":{"pk":1056,"id_way":69945755,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224092.59306805578,6757850.19283357],[224096.83698151304,6757838.506203001],[224071.49159277268,6757829.043811185],[224069.71294534713,6757833.909070128],[224083.87850380124,6757839.080529393],[224084.44706071087,6757837.537841935],[224086.49752912944,6757838.365068827],[224083.36859325046,6757846.882404917],[224092.59306805578,6757850.19283357]]]]},"properties":{"pk":1057,"id_way":69945764,"height":13.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223569.4408692533,6757790.51174204],[223580.0378376571,6757783.1360668745],[223575.72534599356,6757777.058412001],[223566.71127591218,6757783.393790255],[223564.83013578135,6757780.699804372],[223565.98550653033,6757779.837471055],[223562.5831476184,6757775.009425008],[223557.5916561621,6757778.444778491],[223561.0170774331,6757783.301487962],[223561.75838037976,6757782.795660766],[223565.8634757036,6757788.651993516],[223567.43459268485,6757787.622005402],[223569.4408692533,6757790.51174204]]]]},"properties":{"pk":1058,"id_way":69945822,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223889.46534971168,6758408.544716262],[223881.6058131083,6758405.6738583045],[223878.57834690172,6758413.973825269],[223886.41130304273,6758416.879476341],[223889.46534971168,6758408.544716262]]]]},"properties":{"pk":1059,"id_way":69945872,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223718.71443308966,6758426.06563041],[223744.0991917038,6758435.248285936],[223745.8490518525,6758430.18751789],[223733.75538282067,6758426.096065919],[223734.67946269742,6758422.276997641],[223733.20127090946,6758421.793001331],[223736.12162787557,6758411.48710289],[223724.2667259923,6758406.913684702],[223718.71443308966,6758426.06563041]]]]},"properties":{"pk":1060,"id_way":69945875,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223979.11513310083,6757649.621089577],[223963.65318875067,6757656.895002207],[223966.92732787735,6757663.788353303],[223974.27003653292,6757660.289523654],[223982.04634779016,6757656.136640334],[223979.11513310083,6757649.621089577]]]]},"properties":{"pk":1061,"id_way":69945879,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223779.68044787573,6758368.009735086],[223781.09216009453,6758364.333984997],[223777.43629682387,6758362.890399349],[223776.10110473627,6758366.464451994],[223779.68044787573,6758368.009735086]]]]},"properties":{"pk":1062,"id_way":69945901,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224101.22865108046,6758514.820552851],[224101.5210464923,6758514.94233012],[224111.04106779184,6758496.214133914],[224093.87803357202,6758487.460555073],[224084.2549958539,6758506.346165825],[224101.22865108046,6758514.820552851]]]]},"properties":{"pk":1063,"id_way":69945902,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223899.0388715578,6757868.372303857],[223889.94535141168,6757872.493981427],[223896.5853627054,6757887.496773373],[223905.65149879968,6757883.399105932],[223899.0388715578,6757868.372303857]]]]},"properties":{"pk":1064,"id_way":69945904,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224024.07232584708,6757593.789592947],[224024.59712462674,6757595.053124614],[224024.9422165149,6757594.901909955],[224024.35290541695,6757593.557226601],[224029.08019950392,6757591.421054585],[224028.99436265873,6757591.103531426],[224030.9682448611,6757590.245095544],[224030.61822014538,6757589.340400267],[224035.26391976632,6757587.107165988],[224029.87009771916,6757576.3324962575],[224019.2431757173,6757582.379740272],[224024.07232584708,6757593.789592947]]]]},"properties":{"pk":1065,"id_way":69945906,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224078.70002218956,6757976.590234902],[224076.80171513482,6757981.843881009],[224079.45479148816,6757982.805599125],[224081.29471549066,6757977.545464169],[224078.70002218956,6757976.590234902]]]]},"properties":{"pk":1066,"id_way":69945929,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223969.25024075495,6757891.422526965],[223971.31945442155,6757886.010300506],[223968.5178184416,6757884.9731588],[223966.56716032446,6757890.4199077515],[223969.25024075495,6757891.422526965]]]]},"properties":{"pk":1067,"id_way":69945955,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223618.01714415412,6758094.554321248],[223626.58448989526,6758089.688481743],[223626.05801102656,6758088.741054806],[223627.2999188764,6758087.993479993],[223624.99974382453,6758083.639274592],[223631.07292093744,6758080.280600538],[223633.51538600834,6758084.581653458],[223634.82357807225,6758083.763437917],[223635.38333746055,6758084.714067057],[223645.97076688716,6758078.704101269],[223640.8118395876,6758069.698681614],[223641.8797058131,6758068.954572866],[223639.0548028649,6758063.972705467],[223609.9716145963,6758080.449386901],[223618.01714415412,6758094.554321248]]]]},"properties":{"pk":1068,"id_way":69945981,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223758.38096425583,6758114.879130743],[223749.35168074223,6758118.853125028],[223754.4580498475,6758130.489978873],[223763.49207923634,6758126.482805709],[223758.38096425583,6758114.879130743]]]]},"properties":{"pk":1069,"id_way":69945982,"height":13.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223532.4497401917,6757520.797828813],[223538.61880562454,6757519.5109255565],[223536.89828769464,6757511.566170568],[223535.15262838773,6757511.919015665],[223532.85377026442,6757501.369362797],[223534.5718326109,6757500.862860334],[223533.88864011626,6757497.775155149],[223528.4304628694,6757501.127965231],[223532.4497401917,6757520.797828813]]]]},"properties":{"pk":1070,"id_way":69945984,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223660.07327831152,6758505.946462014],[223669.3758143641,6758506.777351674],[223670.26358425673,6758496.782162823],[223661.02075988761,6758495.957421219],[223660.07327831152,6758505.946462014]]]]},"properties":{"pk":1071,"id_way":69946026,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223607.98409824705,6757924.15301109],[223619.828748273,6757927.28939048],[223620.7604317601,6757923.528796826],[223620.8506679719,6757922.361398598],[223620.64746329826,6757921.293821062],[223618.34901907816,6757917.398374416],[223607.98409824705,6757924.15301109]]]]},"properties":{"pk":1072,"id_way":69946033,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223948.15538984758,6757678.379956564],[223943.04623921716,6757667.762162047],[223935.2557935333,6757671.878640923],[223936.84738482517,6757675.1738591185],[223938.83102839917,6757674.109937964],[223940.7768720541,6757678.366460775],[223938.87675330532,6757679.388229664],[223940.56168434327,6757682.8402604805],[223948.15538984758,6757678.379956564]]]]},"properties":{"pk":1073,"id_way":69946103,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223798.68268065242,6758586.788970063],[223801.45096322478,6758587.786172453],[223803.05121704837,6758583.080735741],[223800.3401620525,6758582.07949893],[223798.68268065242,6758586.788970063]]]]},"properties":{"pk":1074,"id_way":69946177,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223772.15033715562,6757939.1036855895],[223766.22135146326,6757942.474057018],[223767.95174599814,6757945.57351384],[223773.88492741596,6757942.170537841],[223772.15033715562,6757939.1036855895]]]]},"properties":{"pk":1075,"id_way":69946184,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223782.19162304027,6757338.855595142],[223748.73870379702,6757291.278831249],[223742.13667787396,6757295.923393678],[223775.71617534378,6757343.499662033],[223782.19162304027,6757338.855595142]]]]},"properties":{"pk":1076,"id_way":69946186,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223643.48349961356,6758156.950872807],[223644.71157145326,6758159.14289182],[223650.0552620187,6758155.979779589],[223648.82750908297,6758153.862569662],[223643.48349961356,6758156.950872807]]]]},"properties":{"pk":1077,"id_way":69946213,"height":3.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224003.7569582756,6758054.376731697],[224005.07266077865,6758054.756618613],[224005.66974669916,6758052.732406783],[224007.84380572115,6758053.43645318],[224007.27901447006,6758055.361828519],[224009.5889788385,6758056.001371065],[224007.77023586765,6758061.539023451],[224014.64989228616,6758064.010659229],[224018.76211302492,6758051.294750924],[224005.90082278944,6758047.30298288],[224003.7569582756,6758054.376731697]]]]},"properties":{"pk":1078,"id_way":69946214,"height":10.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224143.55441150803,6757416.306934315],[224149.01556222682,6757412.208494456],[224145.62615629664,6757406.16412828],[224135.0202614454,6757413.608454352],[224134.9411408302,6757414.035935421],[224142.1904564591,6757424.265991388],[224142.35060866826,6757424.980808461],[224152.81003119325,6757423.098339142],[224151.08120500747,6757417.304774708],[224145.59641656282,6757419.656350545],[224143.55441150803,6757416.306934315]]]]},"properties":{"pk":1079,"id_way":69946222,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223927.28745863732,6758492.2971448535],[223933.73638453125,6758495.529392646],[223937.77493600026,6758487.538451564],[223931.30321978923,6758484.297126217],[223927.28745863732,6758492.2971448535]]]]},"properties":{"pk":1080,"id_way":69946258,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224074.37152647536,6757871.82801514],[224071.6701363747,6757870.765223378],[224072.7409218071,6757867.8390202625],[224066.00739003523,6757865.411449935],[224063.6927467287,6757871.847137216],[224082.29435605663,6757878.611687371],[224084.6380147953,6757872.173741005],[224075.47109312168,6757868.861779349],[224074.37152647536,6757871.82801514]]]]},"properties":{"pk":1081,"id_way":69946264,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223853.37773505208,6757766.46503041],[223845.72057435787,6757770.963562386],[223851.62986629715,6757784.228934236],[223859.68664910167,6757780.580977323],[223853.37773505208,6757766.46503041]]]]},"properties":{"pk":1082,"id_way":69946293,"height":9.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223567.65351630707,6757939.487503993],[223577.76035378862,6757942.292470819],[223579.57747583886,6757936.601839863],[223573.5050512016,6757934.906104927],[223573.5052473326,6757934.307550358],[223572.92751667343,6757933.574958288],[223569.62783143882,6757932.693082305],[223567.65351630707,6757939.487503993]]]]},"properties":{"pk":1083,"id_way":69946391,"height":10.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223996.50092267036,6758494.316313731],[223996.331420787,6758497.272490385],[224001.6390759001,6758497.585482442],[224001.8385294303,6758494.744903356],[223996.50092267036,6758494.316313731]]]]},"properties":{"pk":1084,"id_way":69946425,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223758.29352250512,6758424.9561635135],[223754.54608952117,6758423.638589807],[223753.0377794082,6758428.021929496],[223756.66822453795,6758429.275439666],[223758.29352250512,6758424.9561635135]]]]},"properties":{"pk":1085,"id_way":69946455,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223727.6454106073,6757796.943474685],[223738.91459451072,6757790.54509744],[223735.23888129267,6757784.082570238],[223729.8391398464,6757787.402667259],[223731.19961871376,6757789.665887463],[223725.18109103918,6757792.53849999],[223727.6454106073,6757796.943474685]]]]},"properties":{"pk":1086,"id_way":69946459,"height":10.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223754.6842277,6757516.545552929],[223794.60656579,6757488.622127249],[223785.0368735986,6757474.899624013],[223774.81691271134,6757482.155085108],[223778.12565432812,6757487.0941683985],[223748.5327546843,6757507.729800302],[223754.6842277,6757516.545552929]]]]},"properties":{"pk":1087,"id_way":69946461,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223742.8248875428,6758176.050127116],[223752.6827699003,6758171.730314905],[223743.6531224486,6758150.990679634],[223733.79752231046,6758155.244572716],[223742.8248875428,6758176.050127116]]]]},"properties":{"pk":1088,"id_way":69946486,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223910.48776801513,6758071.522829994],[223900.02480190957,6758053.076319083],[223893.90943320494,6758056.550556565],[223896.7370612282,6758061.5244288575],[223900.29578856536,6758059.509274599],[223902.9903924892,6758064.2782827765],[223892.61919880132,6758070.115467895],[223889.98268433847,6758065.39810942],[223893.4164895051,6758063.426809716],[223890.59352337307,6758058.429494451],[223882.79825898304,6758062.776245892],[223893.23465007663,6758081.269252795],[223910.48776801513,6758071.522829994]]]]},"properties":{"pk":1089,"id_way":69946488,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224359.88132533626,6757394.977700735],[224365.7919063877,6757420.987073488],[224385.60865197142,6757416.430878234],[224386.49514567025,6757415.713177598],[224389.57098224421,6757410.793858142],[224390.2137406432,6757409.095214159],[224385.66182530508,6757389.148451333],[224359.88132533626,6757394.977700735]]]]},"properties":{"pk":1090,"id_way":69946493,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223843.4246754965,6758458.07078813],[223850.35024414348,6758439.123556712],[223837.81640122418,6758434.501741015],[223832.17176447916,6758450.0579011515],[223832.4882591559,6758452.15228455],[223833.18360684026,6758453.462187236],[223833.81870330707,6758454.160440451],[223834.98309160073,6758454.943158567],[223843.4246754965,6758458.07078813]]]]},"properties":{"pk":1091,"id_way":69946515,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224105.7513617784,6757748.5822836645],[224066.40477906205,6757734.784096841],[224065.4211392892,6757737.506279096],[224064.12002335934,6757737.031840852],[224060.6777354402,6757746.634098634],[224062.00889970278,6757747.106226204],[224060.59896366,6757751.045149664],[224059.24388477296,6757750.609698011],[224058.91324743046,6757751.647859669],[224060.28257541798,6757752.163792455],[224059.36084166513,6757754.610351032],[224098.67063426517,6757768.443828019],[224105.7513617784,6757748.5822836645]]]]},"properties":{"pk":1092,"id_way":69946519,"height":49.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223883.6768180568,6757759.599748599],[223879.96427680436,6757755.993124315],[223876.78337905995,6757758.257669083],[223877.02040487123,6757758.707475574],[223881.4676091039,6757760.890260024],[223883.6768180568,6757759.599748599]]]]},"properties":{"pk":1093,"id_way":69946545,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223637.5980646967,6757372.985656114],[223636.4522600476,6757371.362098634],[223631.5456391209,6757374.832230866],[223632.72163936147,6757376.453840319],[223628.71613687067,6757379.2862140965],[223631.20390562867,6757382.838761328],[223632.86775582345,6757381.745518009],[223634.5115299406,6757384.113252891],[223632.8824472598,6757385.259107507],[223643.42484927003,6757400.397531651],[223645.8003795386,6757398.746866321],[223646.18037679917,6757399.2623654725],[223653.16630327067,6757394.416855712],[223643.12924941798,6757379.97979587],[223651.6677088051,6757373.906739849],[223648.68082028243,6757369.679783802],[223649.42560922063,6757369.1291721845],[223646.14625490023,6757364.504250721],[223638.86434006988,6757369.6713554375],[223640.01841275083,6757371.295395441],[223637.5980646967,6757372.985656114]]]]},"properties":{"pk":1094,"id_way":69946547,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223492.021068688,6757278.130728747],[223481.5697631909,6757277.559503659],[223481.6948051365,6757275.6661200635],[223479.41177074818,6757275.5534025775],[223478.75363219297,6757285.385372678],[223491.45838834927,6757286.147809654],[223492.021068688,6757278.130728747]]]]},"properties":{"pk":1095,"id_way":69946560,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223677.89569208032,6757949.3490323275],[223672.1617060232,6757953.136645083],[223681.41292603768,6757966.775556725],[223687.05388485518,6757963.333207239],[223677.89569208032,6757949.3490323275]]]]},"properties":{"pk":1096,"id_way":69946568,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223921.3411124686,6757622.095072593],[223912.38959575738,6757609.402866947],[223905.1396874617,6757614.611354317],[223908.98060399212,6757620.187131915],[223898.09751110064,6757627.942542086],[223903.1180254722,6757635.055855496],[223921.3411124686,6757622.095072593]]]]},"properties":{"pk":1097,"id_way":69946571,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223856.89151728607,6758158.276378696],[223855.3192071203,6758151.124729252],[223834.01003281944,6758156.324636503],[223835.5513203618,6758163.015369988],[223856.89151728607,6758158.276378696]]]]},"properties":{"pk":1098,"id_way":69946592,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224036.57904129493,6757497.5383543875],[224030.20298630674,6757487.226086754],[224024.758154902,6757491.053923692],[224035.2041784269,6757509.244292721],[224046.5005492554,6757502.963857704],[224043.96216559224,6757498.305647254],[224038.57937240478,6757500.655118496],[224036.57904129493,6757497.5383543875]]]]},"properties":{"pk":1099,"id_way":69946597,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224099.01288335875,6757926.955087538],[224100.85375143483,6757921.928279873],[224097.27999765388,6757920.649573269],[224095.4463170429,6757925.675841878],[224099.01288335875,6757926.955087538]]]]},"properties":{"pk":1100,"id_way":69946618,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223797.4780391749,6757774.127490305],[223806.97013966079,6757768.720346357],[223802.5255649898,6757761.023368636],[223793.14222136536,6757766.410973398],[223797.4780391749,6757774.127490305]]]]},"properties":{"pk":1101,"id_way":69946650,"height":10.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223950.71731046852,6758101.734320168],[223953.41395237233,6758094.450262375],[223944.16295282304,6758091.023526399],[223941.34361041774,6758098.612495358],[223950.71731046852,6758101.734320168]]]]},"properties":{"pk":1102,"id_way":69946678,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223521.13264019263,6757570.82588529],[223528.8123194986,6757569.335957495],[223527.56234548733,6757562.971447972],[223519.90261710642,6757564.535936355],[223521.13264019263,6757570.82588529]]]]},"properties":{"pk":1103,"id_way":69946681,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224013.05105999412,6758622.280594957],[224021.47486127075,6758625.854698205],[224027.17004045387,6758612.1529772775],[224018.8013817536,6758608.618297508],[224013.05105999412,6758622.280594957]]]]},"properties":{"pk":1104,"id_way":69946704,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223687.30409162,6757882.373326055],[223682.01414827886,6757874.902581852],[223673.96205986408,6757880.578526436],[223679.2482310504,6757888.093247751],[223687.30409162,6757882.373326055]]]]},"properties":{"pk":1105,"id_way":69946706,"height":9.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223656.91794730184,6757571.580092006],[223666.51275175254,6757564.79890599],[223664.77375463958,6757562.3430363685],[223675.1791923062,6757554.826795003],[223670.898314839,6757549.015595001],[223652.3212316569,6757522.781571595],[223652.55708131072,6757522.628495781],[223649.99144124467,6757518.988101303],[223629.89977825055,6757533.29357354],[223656.91794730184,6757571.580092006]]]]},"properties":{"pk":1106,"id_way":69946732,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223868.44073791237,6758493.036189657],[223872.21150900653,6758483.0037478395],[223853.4581105053,6758476.009268914],[223849.86429455192,6758485.960018256],[223868.44073791237,6758493.036189657]]]]},"properties":{"pk":1107,"id_way":69946750,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223584.193008788,6758121.975956691],[223581.57758365088,6758123.451778],[223584.69450214988,6758129.092100335],[223587.30992510996,6758127.6162804635],[223584.193008788,6758121.975956691]]]]},"properties":{"pk":1108,"id_way":69946800,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223940.40683274937,6758149.458012772],[223942.87065703396,6758142.542986702],[223927.22811116293,6758136.854529525],[223924.70571131055,6758143.775439161],[223940.40683274937,6758149.458012772]]]]},"properties":{"pk":1109,"id_way":69946803,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224043.54446764363,6757543.120539268],[224040.57525137198,6757537.958150905],[224033.905946828,6757541.831010365],[224035.9317966158,6757545.19268662],[224036.847344946,6757544.717926817],[224037.8487433741,6757546.3395024175],[224043.54446764363,6757543.120539268]]]]},"properties":{"pk":1110,"id_way":69946811,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223985.33802730875,6758485.888914668],[223987.85541122308,6758476.179433494],[223980.76485976172,6758474.428041081],[223977.66278074784,6758483.835882471],[223985.33802730875,6758485.888914668]]]]},"properties":{"pk":1111,"id_way":69946841,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224048.54802786733,6757945.609608734],[224039.43933762432,6757942.183292409],[224036.32643249937,6757950.522351381],[224045.4913292777,6757953.823972641],[224048.54802786733,6757945.609608734]]]]},"properties":{"pk":1112,"id_way":69946844,"height":9.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223779.81555219294,6758633.0916409455],[223774.63833477293,6758647.489691272],[223773.42184548848,6758655.951285867],[223796.28409282627,6758659.166418771],[223799.41357796846,6758637.354230314],[223780.7641872677,6758630.465430287],[223779.81555219294,6758633.0916409455]]]]},"properties":{"pk":1113,"id_way":69946867,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223899.4883312593,6757752.411895975],[223907.6895130001,6757749.06776393],[223905.1993551248,6757742.493421419],[223899.83387925735,6757744.587139951],[223899.89481360852,6757744.784096132],[223896.88175866692,6757745.916799131],[223899.4883312593,6757752.411895975]]]]},"properties":{"pk":1114,"id_way":69946874,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223672.2841037882,6757270.511156823],[223674.0566017766,6757273.033241237],[223681.78305575417,6757267.519593452],[223680.2107068092,6757265.188333289],[223672.2841037882,6757270.511156823]]]]},"properties":{"pk":1115,"id_way":69946878,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223658.89741197627,6758427.658806975],[223650.41826680308,6758425.671266037],[223647.598829088,6758437.370409415],[223656.22631704053,6758439.354689153],[223658.89741197627,6758427.658806975]]]]},"properties":{"pk":1116,"id_way":69946917,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223547.7386928509,6757559.122578604],[223545.58681089035,6757559.530837951],[223546.84099192117,6757565.850497536],[223549.57715218732,6757565.306796451],[223548.46853512528,6757558.985153171],[223547.7386928509,6757559.122578604]]]]},"properties":{"pk":1117,"id_way":69946920,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223648.60392948487,6758326.084022428],[223645.5283281687,6758325.052154355],[223644.93538618908,6758312.9889332615],[223635.4904578141,6758315.94333984],[223636.23508739794,6758319.263383374],[223636.64413078115,6758322.740612656],[223636.7226944835,6758326.232748722],[223636.48215480594,6758329.6376949195],[223646.17235968672,6758333.2273465],[223648.60392948487,6758326.084022428]]]]},"properties":{"pk":1118,"id_way":69946963,"height":10.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223678.0055655845,6757812.334995706],[223683.05492849168,6757819.523086844],[223693.3001628683,6757812.232913265],[223688.30567155505,6757805.0843500355],[223678.0055655845,6757812.334995706]]]]},"properties":{"pk":1119,"id_way":69946971,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224168.96955737754,6757532.919522562],[224151.995217024,6757533.165210297],[224152.1104299172,6757550.3450546125],[224169.17300686432,6757550.180382967],[224168.96955737754,6757532.919522562]]]]},"properties":{"pk":1120,"id_way":69946974,"height":45.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224104.59006673406,6757985.993143787],[224102.69228806187,6757991.258350851],[224105.19327341302,6757992.176533841],[224107.1207323931,6757986.919773335],[224104.59006673406,6757985.993143787]]]]},"properties":{"pk":1121,"id_way":69947003,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223839.52410930174,6758547.865757326],[223864.46551150928,6758554.383147369],[223869.60617542337,6758540.79081038],[223868.52475265556,6758540.438234759],[223868.55592245242,6758540.285074737],[223843.22934430838,6758533.688741284],[223839.52410930174,6758547.865757326]]]]},"properties":{"pk":1122,"id_way":69947023,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223590.60109011314,6758432.929652079],[223597.3847351294,6758433.517946471],[223597.7014381237,6758430.445122937],[223591.05591610612,6758429.812449671],[223590.60109011314,6758432.929652079]]]]},"properties":{"pk":1123,"id_way":69947025,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224006.4713895341,6757885.803626331],[223992.60255784754,6757880.588053179],[223990.23239159057,6757886.9622340305],[224004.09312454032,6757892.16753115],[224006.4713895341,6757885.803626331]]]]},"properties":{"pk":1124,"id_way":69947026,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223793.30538287762,6758125.73780648],[223794.4368908554,6758128.354566216],[223799.22847195977,6758126.271334828],[223798.10397247417,6758123.654074575],[223793.30538287762,6758125.73780648]]]]},"properties":{"pk":1125,"id_way":69947049,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223985.70004720206,6758178.076148357],[223982.67901726937,6758189.656522148],[223982.9711595383,6758189.733226497],[223981.36021346555,6758195.848022075],[223990.88283081635,6758198.231792706],[223990.68731162854,6758200.080351019],[223991.23697983968,6758201.7815248165],[223992.44724599033,6758203.052766085],[223994.16583973097,6758203.787952058],[223991.24743350898,6758212.706598363],[223997.9785315745,6758215.124322036],[223998.64412198347,6758214.729201045],[224002.92802690977,6758201.207410636],[224004.42179035104,6758201.661411155],[224005.77809749608,6758200.605474318],[224007.45227482138,6758195.359789576],[224007.00676862,6758194.672463513],[224008.42554258773,6758193.917437295],[224009.50084669614,6758192.953829062],[224010.05239107748,6758192.135240738],[224010.64327406912,6758190.736386612],[224010.7891907775,6758188.79857955],[224010.61454223955,6758187.825800632],[224009.806614028,6758186.041818707],[224008.8179699189,6758184.9499372095],[224007.0221035692,6758183.940730857],[224007.10467868685,6758183.639034763],[223985.70004720206,6758178.076148357]]]]},"properties":{"pk":1126,"id_way":69947050,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223544.5636048904,6757538.718694342],[223544.3950522025,6757537.848865702],[223543.7361801337,6757537.99639976],[223543.92971421158,6757538.872571348],[223544.5636048904,6757538.718694342]]]]},"properties":{"pk":1127,"id_way":69947052,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224046.51121783047,6757321.122760059],[224047.24269054094,6757322.105082472],[224047.06801895244,6757323.1587271625],[224045.3178690247,6757322.909636758],[224044.26894815714,6757328.857018767],[224045.25115442768,6757330.258046889],[224051.91919690103,6757331.790463655],[224066.6334507387,6757321.478751205],[224065.50743320413,6757319.855653616],[224081.9297250756,6757308.1533393245],[224081.3119115168,6757307.290061238],[224082.9839121314,6757306.070752327],[224083.6346464216,6757306.935491887],[224085.33985446254,6757305.7908866275],[224079.6976899774,6757297.570744284],[224046.51121783047,6757321.122760059]]]]},"properties":{"pk":1128,"id_way":69947054,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223758.70767934376,6757869.053318606],[223747.31215809094,6757876.576016089],[223752.4858053876,6757884.320647162],[223763.88040469217,6757876.7870646315],[223758.70767934376,6757869.053318606]]]]},"properties":{"pk":1129,"id_way":69947075,"height":6.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223997.63483163292,6757677.450954571],[224004.85646159315,6757690.522351527],[224014.57725918226,6757685.533513513],[224012.39623297725,6757681.390889604],[224013.11398669775,6757680.953243501],[224008.30179178415,6757671.447871507],[223997.63483163292,6757677.450954571]]]]},"properties":{"pk":1130,"id_way":69947101,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223581.7265357645,6757552.576890257],[223582.82769971146,6757558.898132054],[223585.77130714065,6757558.346895952],[223584.67014655552,6757552.0256535765],[223581.7265357645,6757552.576890257]]]]},"properties":{"pk":1131,"id_way":69947105,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223824.06692411582,6758606.814418124],[223822.0529652214,6758612.190927997],[223839.85425390472,6758618.828230277],[223841.95351413253,6758613.376201181],[223824.06692411582,6758606.814418124]]]]},"properties":{"pk":1132,"id_way":69947124,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223981.36170062269,6757902.687378523],[223983.52524007938,6757896.863835772],[223976.7009324431,6757894.344821095],[223971.89289829353,6757907.502771276],[223978.62710293956,6757910.006917683],[223981.36170062269,6757902.687378523]]]]},"properties":{"pk":1133,"id_way":69947127,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224043.50937596965,6757717.041650768],[224039.26265883664,6757708.829639417],[224030.6059255238,6757713.459831916],[224035.11420190224,6757721.628957569],[224043.50937596965,6757717.041650768]]]]},"properties":{"pk":1134,"id_way":69947129,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223656.70628122526,6758245.287536289],[223657.35083744462,6758243.501053966],[223649.87904770568,6758240.746088512],[223649.28955385103,6758242.537154751],[223656.70628122526,6758245.287536289]]]]},"properties":{"pk":1135,"id_way":69947149,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224071.26803055502,6758090.579954618],[224063.88573665783,6758087.947182767],[224061.5367512847,6758094.508612173],[224068.89644850141,6758097.142879904],[224071.26803055502,6758090.579954618]]]]},"properties":{"pk":1136,"id_way":69947150,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224209.30816232951,6757640.016954019],[224206.39519384192,6757640.377171161],[224206.9840528541,6757645.434940262],[224209.8970186682,6757645.074723428],[224209.30816232951,6757640.016954019]]]]},"properties":{"pk":1137,"id_way":69947154,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223977.46593872036,6758543.530296679],[223981.80755434063,6758534.913087798],[223973.99845409594,6758530.954889104],[223969.5710636949,6758539.5342814615],[223977.46593872036,6758543.530296679]]]]},"properties":{"pk":1138,"id_way":69947171,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224030.66658418693,6757758.500767172],[224020.91463341392,6757754.227813817],[224012.09958631857,6757758.343590904],[224015.52365279503,6757765.526928919],[224026.16056711026,6757769.767479445],[224030.66658418693,6757758.500767172]]]]},"properties":{"pk":1139,"id_way":69947197,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223504.6583321191,6757342.305078021],[223504.12795345183,6757332.2728496995],[223481.9393310067,6757333.21477398],[223482.44880242174,6757342.895181864],[223504.6583321191,6757342.305078021]]]]},"properties":{"pk":1140,"id_way":69947211,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223910.59232042808,6758032.021306781],[223907.1494243642,6758025.870108391],[223906.1720550035,6758026.402903389],[223906.67323159202,6758027.308449629],[223900.8922733804,6758030.5731607685],[223903.80048839172,6758035.862401538],[223910.59232042808,6758032.021306781]]]]},"properties":{"pk":1141,"id_way":69947219,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223686.05507214784,6758437.864977621],[223687.03744907692,6758434.5392890265],[223681.55357851,6758432.776061247],[223680.85327709027,6758436.217619207],[223686.05507214784,6758437.864977621]]]]},"properties":{"pk":1142,"id_way":69947220,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223729.5600453545,6758340.663965747],[223732.16201329854,6758331.576112696],[223723.04966964337,6758328.498964339],[223721.1461622807,6758333.983344836],[223714.78457599922,6758331.64308578],[223713.12599663011,6758336.264240211],[223721.25030893862,6758338.182800522],[223729.5600453545,6758340.663965747]]]]},"properties":{"pk":1143,"id_way":69947244,"height":12.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223756.424003067,6757897.4110665675],[223763.0439695037,6757907.177520027],[223769.48594638496,6757902.908117388],[223762.98510430398,6757893.075146972],[223756.424003067,6757897.4110665675]]]]},"properties":{"pk":1144,"id_way":69947247,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223954.7824144229,6757901.074449777],[223957.8657744496,6757892.937469227],[223945.82944114078,6757888.520454628],[223942.86524160972,6757896.581708253],[223954.7824144229,6757901.074449777]]]]},"properties":{"pk":1145,"id_way":69947315,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223885.86521436714,6757699.590673313],[223877.5961856482,6757684.682080502],[223866.7389372738,6757692.471703596],[223876.42429320284,6757706.142955785],[223885.86521436714,6757699.590673313]]]]},"properties":{"pk":1146,"id_way":69947318,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223820.3808876263,6758159.8069693735],[223821.12434778747,6758163.22394612],[223826.12748932114,6758160.6046202015],[223825.52537399068,6758157.6068310905],[223820.3808876263,6758159.8069693735]]]]},"properties":{"pk":1147,"id_way":69947351,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223997.80261880916,6758009.43520018],[223986.48024767794,6758005.68689855],[223986.87187649225,6758004.583564387],[223977.8298468915,6758001.194924679],[223975.2470808093,6758008.185797369],[223984.4692750483,6758011.384119995],[223984.55587897697,6758011.141765749],[223996.0066383697,6758015.309771258],[223997.80261880916,6758009.43520018]]]]},"properties":{"pk":1148,"id_way":69947354,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223960.01332094325,6758408.73468343],[223962.19267598895,6758417.511937499],[223970.77076018456,6758415.326225931],[223968.55750231553,6758406.584394936],[223960.01332094325,6758408.73468343]]]]},"properties":{"pk":1149,"id_way":69947400,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224067.64867442095,6757789.782525613],[224072.574175346,6757791.583188401],[224072.78354195858,6757791.035347595],[224073.54483062544,6757791.273924812],[224075.59662980423,6757785.458032343],[224074.9107436373,6757785.210267373],[224075.11735982238,6757784.704097557],[224070.22166506457,6757782.987402304],[224070.0762176967,6757783.422787286],[224069.47753604775,6757783.21320294],[224067.31481456445,6757789.031084285],[224067.88299017292,6757789.278988299],[224067.64867442095,6757789.782525613]]]]},"properties":{"pk":1150,"id_way":69947405,"height":7.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223627.69403825063,6757769.30461554],[223635.90357205246,6757781.075254618],[223647.00671400886,6757773.433918265],[223638.9162246152,6757761.576715172],[223627.69403825063,6757769.30461554]]]]},"properties":{"pk":1151,"id_way":69947432,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223880.72241988007,6758432.353973367],[223883.57653099284,6758424.613681619],[223876.74885975744,6758422.0618987065],[223873.83909651334,6758429.839185358],[223880.72241988007,6758432.353973367]]]]},"properties":{"pk":1152,"id_way":69947452,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223760.95613127592,6757919.11207355],[223759.138870688,6757915.854883724],[223753.23692545146,6757919.25461697],[223754.96897138364,6757922.291751788],[223760.95613127592,6757919.11207355]]]]},"properties":{"pk":1153,"id_way":69947454,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223981.2340722632,6757645.6180295],[223985.7957860318,6757653.990510946],[223991.22278464292,6757650.939421735],[223986.7141475738,6757642.8762033535],[223981.2340722632,6757645.6180295]]]]},"properties":{"pk":1154,"id_way":69947457,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223878.19058047005,6758192.723031215],[223888.60390161083,6758190.443823274],[223890.14169114773,6758184.469367177],[223888.85665096343,6758184.463093857],[223889.2216353022,6758181.480190121],[223886.36862214303,6758180.830619825],[223876.05737869683,6758183.271951741],[223878.19058047005,6758192.723031215]]]]},"properties":{"pk":1155,"id_way":69947483,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224069.76639514245,6758554.242727369],[224060.9806524824,6758549.806426784],[224056.93822327311,6758557.952953666],[224065.69384936933,6758562.380779593],[224069.76639514245,6758554.242727369]]]]},"properties":{"pk":1156,"id_way":69947484,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223918.30849809657,6757861.622109227],[223920.61244049764,6757860.599766069],[223918.85106002388,6757856.652930497],[223923.40776490924,6757854.523975176],[223922.25084260423,6757851.940426526],[223908.772699058,6757857.999592319],[223911.69814608095,6757864.607426083],[223918.30849809657,6757861.622109227]]]]},"properties":{"pk":1157,"id_way":69947486,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224013.70114337295,6757570.346281676],[224019.5760882537,6757567.055393553],[224014.77438566586,6757558.487467706],[224008.81663800523,6757561.859482756],[224013.70114337295,6757570.346281676]]]]},"properties":{"pk":1158,"id_way":69947488,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224073.04498639185,6757974.516711586],[224070.4927961508,6757981.639498631],[224073.14617413777,6757982.601322759],[224075.6405007066,6757975.482263959],[224073.04498639185,6757974.516711586]]]]},"properties":{"pk":1159,"id_way":69947521,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223971.7055279047,6757907.432811985],[223976.51278340782,6757894.276992694],[223968.27053491533,6757891.24816549],[223963.42777083506,6757904.329694906],[223971.7055279047,6757907.432811985]]]]},"properties":{"pk":1160,"id_way":69947545,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223890.55302548324,6757624.131595827],[223892.8562988175,6757622.477586702],[223889.39801532426,6757617.579155713],[223887.1018937077,6757619.23247624],[223890.55302548324,6757624.131595827]]]]},"properties":{"pk":1161,"id_way":69947547,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223927.2967432635,6758136.666673962],[223936.4882557819,6758140.010254434],[223939.09316505166,6758133.0163766695],[223929.81550211716,6758129.789092445],[223927.2967432635,6758136.666673962]]]]},"properties":{"pk":1162,"id_way":69947570,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223741.40563428088,6758005.773498224],[223748.738745716,6758018.854958557],[223755.23854845768,6758015.170295049],[223755.09452602363,6758014.890132895],[223763.8643752834,6758010.047905011],[223756.61048547653,6757997.095720315],[223741.40563428088,6758005.773498224]]]]},"properties":{"pk":1163,"id_way":69947571,"height":12.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223518.4270918079,6757471.618159171],[223515.1963574399,6757473.649309662],[223516.78886178113,6757481.393794431],[223523.24882579266,6757492.324020303],[223529.69190363007,6757488.250394285],[223525.09406773307,6757480.193430548],[223523.8218742872,6757480.909065317],[223518.4270918079,6757471.618159171]]]]},"properties":{"pk":1164,"id_way":69947573,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223947.18890847746,6757250.093095537],[223949.9822458853,6757248.07668877],[223947.73106991913,6757244.97427118],[223944.93773150802,6757246.990679049],[223947.18890847746,6757250.093095537]]]]},"properties":{"pk":1165,"id_way":69947575,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223643.17123545834,6758495.938571285],[223636.53394954753,6758495.349297138],[223635.7644667678,6758503.729826855],[223642.37168698653,6758504.310675113],[223643.17123545834,6758495.938571285]]]]},"properties":{"pk":1166,"id_way":69947595,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223600.99607363844,6757918.873873989],[223601.50079756803,6757919.693389253],[223613.9048734998,6757910.553717014],[223611.268639692,6757907.06799163],[223610.26634230118,6757905.322885755],[223607.9186990364,6757900.2970938375],[223605.2821403764,6757899.331963422],[223593.577702804,6757906.06646446],[223600.99607363844,6757918.873873989]]]]},"properties":{"pk":1167,"id_way":69947598,"height":13.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223571.30881168245,6757348.241413975],[223576.89444518063,6757356.189986576],[223584.46903892263,6757350.831687782],[223578.8260937983,6757342.811360777],[223571.30881168245,6757348.241413975]]]]},"properties":{"pk":1168,"id_way":69947623,"height":12.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223839.37671948152,6758578.9066837095],[223835.66095887258,6758588.826816587],[223849.68014099152,6758593.182380222],[223853.6821644707,6758582.6782957865],[223839.37671948152,6758578.9066837095]]]]},"properties":{"pk":1169,"id_way":69947645,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223724.57456350836,6757270.500989164],[223730.21026748323,6757278.365948602],[223736.7797345552,6757273.669018016],[223731.31254464056,6757265.888188579],[223724.57456350836,6757270.500989164]]]]},"properties":{"pk":1170,"id_way":69947651,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223846.66599208617,6758126.131081639],[223843.035662007,6758117.936284227],[223823.5635976055,6758127.8802903695],[223826.78206388862,6758134.783742859],[223846.66599208617,6758126.131081639]]]]},"properties":{"pk":1171,"id_way":69947671,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223619.82451401965,6758144.741475139],[223628.22197049428,6758160.176919772],[223633.49865016222,6758157.32355314],[223625.09807422728,6758141.845049372],[223619.82451401965,6758144.741475139]]]]},"properties":{"pk":1172,"id_way":69947672,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224125.9694514354,6757462.573091211],[224128.98638835628,6757466.916886796],[224131.24903104885,6757465.342057293],[224128.1815069134,6757460.99259671],[224125.9694514354,6757462.573091211]]]]},"properties":{"pk":1173,"id_way":69947676,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223851.75607922816,6757818.78472606],[223842.68830444218,6757805.178821258],[223830.75979944633,6757812.9903077455],[223839.83283732718,6757826.661754497],[223851.75607922816,6757818.78472606]]]]},"properties":{"pk":1174,"id_way":69947722,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223680.14283149107,6757309.784699904],[223687.36201815747,6757304.701039636],[223685.1462625276,6757301.58659702],[223678.03841812327,6757306.70594177],[223680.14283149107,6757309.784699904]]]]},"properties":{"pk":1175,"id_way":69947725,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223570.10281121306,6758362.825295389],[223568.1849976115,6758374.4003359405],[223589.65660477369,6758378.044923757],[223591.63067888428,6758366.431799536],[223570.10281121306,6758362.825295389]]]]},"properties":{"pk":1176,"id_way":69947781,"height":9.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223566.66979576484,6757883.797465686],[223571.5954771711,6757877.411260916],[223570.68025169647,6757874.032857091],[223568.20144439107,6757873.275764031],[223562.42370864173,6757880.715499032],[223566.66979576484,6757883.797465686]]]]},"properties":{"pk":1177,"id_way":69947785,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224000.93468213396,6758547.269293604],[223992.38917588769,6758543.002797077],[223988.49357719542,6758550.826028828],[223996.92950734845,6758555.101448649],[224000.93468213396,6758547.269293604]]]]},"properties":{"pk":1178,"id_way":69947809,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223751.6130238206,6758410.039080344],[223749.50511188028,6758415.856533068],[223758.9651438835,6758419.201391817],[223761.01541132582,6758413.389137594],[223751.6130238206,6758410.039080344]]]]},"properties":{"pk":1179,"id_way":69947836,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223669.75695804518,6757830.242262459],[223663.96837612975,6757822.175102816],[223661.42802383457,6757823.951039823],[223667.219209789,6757832.060356606],[223669.75695804518,6757830.242262459]]]]},"properties":{"pk":1180,"id_way":69947839,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223815.17992524727,6757686.857356507],[223820.65315295037,6757687.823814586],[223824.5917572126,6757685.07332],[223824.7825360153,6757683.968118543],[223799.8251231078,6757648.373992585],[223795.4721744835,6757651.445163379],[223794.99671536146,6757650.770095974],[223768.62093330018,6757669.361744957],[223770.5739690855,6757672.135605988],[223760.97922279921,6757678.90918125],[223759.03332195955,6757676.134320138],[223752.49340475796,6757680.707845842],[223754.44151757908,6757683.515263951],[223744.88150475902,6757690.252398238],[223742.93314753447,6757687.444661169],[223716.0153925861,6757706.397031434],[223739.40494636807,6757747.864381467],[223743.5585806148,6757744.9455876],[223748.0832690686,6757745.583427775],[223817.70570519622,6757696.783349563],[223814.3134715831,6757691.924924925],[223815.17992524727,6757686.857356507]]]]},"properties":{"pk":1181,"id_way":69947841,"height":18.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223696.88359413476,6758196.324579107],[223701.89857808524,6758207.412510527],[223730.5780562853,6758194.950124433],[223725.76447584,6758183.70262675],[223696.88359413476,6758196.324579107]]]]},"properties":{"pk":1182,"id_way":69947861,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223884.4942092113,6758117.171299785],[223877.1809886895,6758104.222399524],[223870.83486935898,6758107.815878515],[223878.17488185433,6758120.729910201],[223884.4942092113,6758117.171299785]]]]},"properties":{"pk":1183,"id_way":69947862,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224152.95547717312,6757423.275375424],[224142.3931354143,6757425.176367973],[224143.88303450533,6757432.216072829],[224161.93081566342,6757429.282330165],[224160.73391481655,6757421.888496382],[224152.95547717312,6757423.275375424]]]]},"properties":{"pk":1184,"id_way":69947866,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224074.16416349408,6757901.1152555635],[224076.77552912378,6757893.886016565],[224067.7908224679,6757890.572210468],[224065.29654067176,6757897.889684503],[224074.16416349408,6757901.1152555635]]]]},"properties":{"pk":1185,"id_way":69947886,"height":11.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223872.69381874107,6757777.324064686],[223886.02973718318,6757771.46422261],[223883.0154290805,6757764.684893428],[223869.6503529244,6757770.546977291],[223872.69381874107,6757777.324064686]]]]},"properties":{"pk":1186,"id_way":69947909,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223585.72188676306,6757602.88533183],[223579.00559190405,6757607.606719586],[223587.92257387433,6757620.146009673],[223594.7311224989,6757615.373056091],[223585.72188676306,6757602.88533183]]]]},"properties":{"pk":1187,"id_way":69947911,"height":10.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223799.6054974404,6758637.42482509],[223796.48214058197,6758659.194300042],[223820.53303747426,6758662.583784472],[223823.90980453923,6758660.4927579565],[223828.6538788358,6758648.104242736],[223799.6054974404,6758637.42482509]]]]},"properties":{"pk":1188,"id_way":69947930,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223928.7686958487,6757963.394277401],[223938.9916080638,6757958.834780424],[223924.12742552778,6757925.623070789],[223914.3696253294,6757931.185310041],[223928.7686958487,6757963.394277401]]]]},"properties":{"pk":1189,"id_way":69947933,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224048.6769255185,6757610.0691946745],[224049.64755910766,6757607.266576993],[224044.1242582983,6757605.3085741885],[224043.17658249312,6757608.0339382645],[224048.6769255185,6757610.0691946745]]]]},"properties":{"pk":1190,"id_way":69947935,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223827.38635190157,6758192.95416754],[223827.99039025445,6758195.751022463],[223832.90726539431,6758193.086123246],[223832.35928976373,6758190.371276215],[223827.38635190157,6758192.95416754]]]]},"properties":{"pk":1191,"id_way":69947955,"height":3.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224029.47911869906,6758024.817393053],[224031.40606188268,6758019.56179622],[224019.0524353411,6758015.454890835],[224017.26788446895,6758020.587635052],[224029.47911869906,6758024.817393053]]]]},"properties":{"pk":1192,"id_way":69947956,"height":13.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223781.09551173475,6758382.034085359],[223784.48219925203,6758372.991088662],[223775.90522529333,6758369.816163999],[223776.91646907016,6758367.042749229],[223775.14570131045,6758366.286369731],[223770.6632710432,6758378.212030187],[223781.09551173475,6758382.034085359]]]]},"properties":{"pk":1193,"id_way":69948000,"height":12.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223502.53351764884,6757390.035185255],[223497.64796507038,6757383.182815353],[223485.22207123967,6757384.054584411],[223486.8208078002,6757404.949764509],[223496.510244356,6757404.4290944245],[223495.50206906613,6757390.647337054],[223502.53351764884,6757390.035185255]]]]},"properties":{"pk":1194,"id_way":69948018,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223951.37963380033,6758033.357266005],[223951.9991803899,6758031.652216933],[223943.1315355269,6758028.307784481],[223942.34436623324,6758030.5750773195],[223943.36370999974,6758030.737815966],[223943.38998573308,6758030.889452333],[223947.8703373927,6758031.47300215],[223947.8955414821,6758031.313842626],[223948.86453201322,6758031.449339886],[223950.56198664175,6758032.340769826],[223951.37963380033,6758033.357266005]]]]},"properties":{"pk":1195,"id_way":69948026,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223713.40958403866,6758521.297917985],[223712.6079845698,6758530.968709531],[223722.53084952055,6758531.292819472],[223723.3955236923,6758522.130512122],[223713.40958403866,6758521.297917985]]]]},"properties":{"pk":1196,"id_way":69948027,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223510.23288449863,6757656.015468409],[223507.07027347691,6757651.587043917],[223499.9673101687,6757656.7493598275],[223511.98756733537,6757673.720438716],[223519.20751774855,6757668.635594088],[223510.23288449863,6757656.015468409]]]]},"properties":{"pk":1197,"id_way":69948030,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223810.17038294638,6758365.656225147],[223780.3813194449,6758354.758301993],[223778.63406005222,6758359.54336271],[223795.49925948385,6758365.660454358],[223792.70337820644,6758373.604329057],[223805.3240916969,6758378.957915374],[223810.17038294638,6758365.656225147]]]]},"properties":{"pk":1198,"id_way":69948056,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224044.22878923465,6758600.261417363],[224047.48851285968,6758592.710919463],[224044.03040029324,6758591.2439524615],[224040.78361825846,6758598.840443862],[224044.22878923465,6758600.261417363]]]]},"properties":{"pk":1199,"id_way":69948057,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223675.79425457655,6757866.937667701],[223667.25542759575,6757869.175392489],[223662.87603091018,6757872.222256479],[223664.64980019993,6757874.704627069],[223675.79425457655,6757866.937667701]]]]},"properties":{"pk":1200,"id_way":69948059,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223624.13773839537,6757497.966971037],[223642.62145277296,6757523.956631481],[223649.87638510455,6757518.824509181],[223631.56359730058,6757492.732202506],[223624.13773839537,6757497.966971037]]]]},"properties":{"pk":1201,"id_way":69948084,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223991.8902818331,6757992.778274547],[223982.2028301672,6757989.237644942],[223977.8988500856,6758001.007201065],[223987.0723500655,6758004.445106468],[223987.07164427693,6758004.609876582],[223992.14861063287,6758006.296359043],[223996.59902485984,6757994.490141792],[223991.8902818331,6757992.778274547]]]]},"properties":{"pk":1202,"id_way":69948106,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223928.82987829577,6758195.665637909],[223917.50611762292,6758204.273062448],[223917.46320146715,6758204.465675225],[223920.77559330955,6758209.015206563],[223922.92379904323,6758209.251246109],[223934.58672022252,6758203.184775894],[223928.82987829577,6758195.665637909]]]]},"properties":{"pk":1203,"id_way":69948134,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223587.0635347584,6758120.344965872],[223590.23857793902,6758125.980925244],[223592.81925627618,6758124.540342053],[223589.67299265615,6758118.901682291],[223587.0635347584,6758120.344965872]]]]},"properties":{"pk":1204,"id_way":69948136,"height":3.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224071.10097720817,6757522.466192195],[224076.77279307184,6757530.563489567],[224084.7423984224,6757524.934881802],[224079.06675900586,6757516.831830343],[224071.10097720817,6757522.466192195]]]]},"properties":{"pk":1205,"id_way":69948141,"height":10.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223951.99737977923,6758485.610543541],[223961.77175327187,6758489.466294585],[223963.91085395444,6758483.146475299],[223957.81108866053,6758480.717002351],[223959.13270822656,6758477.196903332],[223964.1479662077,6758478.437477425],[223963.1023438887,6758481.641007143],[223964.2769614673,6758482.055762781],[223967.930964845,6758471.275594814],[223959.2969972103,6758469.13584289],[223951.99737977923,6758485.610543541]]]]},"properties":{"pk":1206,"id_way":69948158,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224130.9324424838,6757941.58943668],[224133.87507960908,6757933.330550221],[224117.81653741322,6757927.442093422],[224114.73013635288,6757935.746189713],[224130.9324424838,6757941.58943668]]]]},"properties":{"pk":1207,"id_way":69948161,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223817.82907179263,6757841.201287269],[223830.2078489209,6757832.997487346],[223817.21156798516,6757813.466785697],[223804.77568097916,6757821.7086643465],[223817.82907179263,6757841.201287269]]]]},"properties":{"pk":1208,"id_way":69948184,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223770.19768132866,6757935.612539961],[223768.4371801154,6757932.503152392],[223762.50515630914,6757935.830239797],[223764.26146805994,6757938.972229572],[223770.19768132866,6757935.612539961]]]]},"properties":{"pk":1209,"id_way":69948207,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223625.48846749624,6758393.671205739],[223625.8936547367,6758391.768830174],[223622.20412337309,6758390.9001358235],[223621.66633977558,6758392.762318414],[223625.48846749624,6758393.671205739]]]]},"properties":{"pk":1210,"id_way":69948208,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224007.44597938683,6757617.981045816],[224011.13428985915,6757622.218642409],[224015.01910063456,6757625.5428987015],[224019.40353567371,6757628.89550493],[224023.46759920128,6757631.3710568035],[224027.49263058195,6757633.408521159],[224024.803430142,6757641.118022661],[224058.51239532972,6757653.583790702],[224061.51085338125,6757645.287935528],[224050.21259866946,6757641.191888818],[224031.64462982843,6757634.030721829],[224034.21718280212,6757626.775844137],[224030.5979184043,6757625.270244785],[224027.0144197446,6757623.358087796],[224023.63395431914,6757621.140261895],[224020.4969073201,6757618.599606821],[224017.58760546328,6757615.784836505],[224014.58266449452,6757612.344366789],[224007.44597938683,6757617.981045816]]]]},"properties":{"pk":1211,"id_way":69948210,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223667.70061922676,6758310.206498321],[223670.70212801968,6758297.647785948],[223656.53123812375,6758292.351799553],[223653.4451481781,6758300.644532701],[223663.78673963263,6758304.374742716],[223662.654930184,6758309.0257532075],[223667.70061922676,6758310.206498321]]]]},"properties":{"pk":1212,"id_way":69948232,"height":9.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224191.59594531075,6758559.2624748815],[224228.88766837327,6758572.136048373],[224233.94216255832,6758572.192834954],[224304.58843432338,6758539.219414678],[224309.88591890433,6758542.009352475],[224327.17050235154,6758544.99465142],[224341.26615024687,6758550.9215585645],[224343.84859085883,6758546.164132497],[224329.63306924677,6758539.633597025],[224301.2345999665,6758534.445174676],[224230.48642380894,6758566.785126841],[224219.79757415113,6758563.039079194],[224193.2318187473,6758554.320153782],[224191.59594531075,6758559.2624748815]]]]},"properties":{"pk":1213,"id_way":69948233,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223700.0937038164,6757807.54715131],[223695.12961181626,6757800.319851805],[223688.4694383239,6757804.969543475],[223693.46397475654,6757812.118171282],[223700.0937038164,6757807.54715131]]]]},"properties":{"pk":1214,"id_way":69948235,"height":8.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223933.8058449056,6757594.586047039],[223941.6421602778,6757611.116787584],[223950.98350583884,6757605.910392988],[223945.7681688726,6757596.495036687],[223946.06480857718,6757596.301564849],[223943.0504887218,6757590.143603544],[223933.8058449056,6757594.586047039]]]]},"properties":{"pk":1215,"id_way":69948237,"height":9.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224096.89629286068,6758015.378836569],[224101.80271479348,6758017.14084244],[224104.82695306392,6758008.997698582],[224103.49585842754,6758008.525552456],[224104.36040277063,6758006.192296272],[224100.7308620405,6758004.874507007],[224096.89629286068,6758015.378836569]]]]},"properties":{"pk":1216,"id_way":69948258,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223828.600734349,6758529.658921568],[223831.47843657294,6758521.63971946],[223808.76671422538,6758513.213819739],[223805.85803854157,6758521.114410782],[223828.600734349,6758529.658921568]]]]},"properties":{"pk":1217,"id_way":69948278,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223589.3664935794,6758453.734693256],[223582.22348751183,6758453.021460484],[223581.2757230579,6758462.620578817],[223588.29989909066,6758463.321571393],[223589.3664935794,6758453.734693256]]]]},"properties":{"pk":1218,"id_way":69948280,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223990.63993055176,6757766.956639817],[223981.70570885358,6757771.19254755],[223983.68798250993,6757774.53706059],[223987.88289143334,6757782.924711123],[223993.58508609704,6757773.108036838],[223990.63993055176,6757766.956639817]]]]},"properties":{"pk":1219,"id_way":69948281,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223958.83712988728,6758154.593662648],[223956.79858639557,6758160.579535505],[223966.08340004273,6758163.976567954],[223966.857773428,6758163.244120662],[223972.52993489327,6758169.141871966],[223978.0187354079,6758164.213899295],[223981.0700652852,6758155.735683843],[223960.69991282464,6758149.043482755],[223958.83712988728,6758154.593662648]]]]},"properties":{"pk":1220,"id_way":69948303,"height":13.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223789.6547769264,6758117.393412332],[223790.8118025585,6758120.052713956],[223795.60922187354,6758117.936359501],[223794.4802513388,6758115.275052882],[223789.6547769264,6758117.393412332]]]]},"properties":{"pk":1221,"id_way":69948304,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223522.1806784427,6757522.990246548],[223520.17046366856,6757513.074149899],[223510.35454529527,6757515.101978983],[223512.37191903542,6757525.060732895],[223522.1806784427,6757522.990246548]]]]},"properties":{"pk":1222,"id_way":69948306,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224038.70179523024,6757239.3902665125],[224040.29801448024,6757241.67715948],[224040.99352005345,6757241.198260189],[224039.3371643692,6757238.920098776],[224038.70179523024,6757239.3902665125]]]]},"properties":{"pk":1223,"id_way":69948308,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223656.78448794055,6758544.349326321],[223661.18400219834,6758517.61445288],[223650.4918468538,6758515.730898773],[223646.09141815102,6758542.499641534],[223656.78448794055,6758544.349326321]]]]},"properties":{"pk":1224,"id_way":69948326,"height":21.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223658.83684305634,6757928.892048867],[223663.0217944318,6757926.206994537],[223654.9952712307,6757914.027650694],[223656.5052093237,6757913.003387404],[223651.71859082056,6757905.93101964],[223647.8195742354,6757908.697351009],[223652.09984604325,6757915.420435402],[223650.53367014005,6757916.482213073],[223658.83684305634,6757928.892048867]]]]},"properties":{"pk":1225,"id_way":69948329,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223966.13142692234,6757742.0283312155],[223975.70282489012,6757735.473936606],[223972.62739662654,6757729.1215126915],[223961.25890966778,6757735.004554464],[223966.13142692234,6757742.0283312155]]]]},"properties":{"pk":1226,"id_way":69948352,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223592.54113303238,6757548.348499941],[223590.16181302557,6757549.820417904],[223593.0617743482,6757554.391895881],[223595.47038075194,6757552.927719902],[223592.54113303238,6757548.348499941]]]]},"properties":{"pk":1227,"id_way":69948354,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223856.5520150845,6758609.172475917],[223876.843474672,6758617.044004506],[223881.38585993822,6758605.109963379],[223861.09796084615,6758597.282391571],[223856.5520150845,6758609.172475917]]]]},"properties":{"pk":1228,"id_way":69948373,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223786.8655624546,6757964.953425613],[223777.82042962287,6757948.910658475],[223768.53971142674,6757954.046800988],[223777.64261071346,6757970.161767546],[223786.8655624546,6757964.953425613]]]]},"properties":{"pk":1229,"id_way":69948376,"height":12.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224082.07406199476,6757696.163082909],[224073.74048178174,6757693.1181046795],[224069.51942903403,6757705.014348128],[224077.32880998912,6757707.9949169345],[224075.59107849427,6757713.195159408],[224086.09023632717,6757717.124602282],[224089.45032388376,6757708.418256023],[224079.131708927,6757704.604129709],[224082.07406199476,6757696.163082909]]]]},"properties":{"pk":1230,"id_way":69948378,"height":9.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223649.66616074133,6758164.031230667],[223654.1371240988,6758168.596778014],[223655.9500517909,6758166.808042872],[223651.45023529785,6758162.361323233],[223649.66616074133,6758164.031230667]]]]},"properties":{"pk":1231,"id_way":69948398,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224033.7388782209,6758085.337345831],[224038.48939860958,6758072.659393743],[224025.72845349938,6758068.474786307],[224021.0328983529,6758081.343927129],[224033.7388782209,6758085.337345831]]]]},"properties":{"pk":1232,"id_way":69948399,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223614.37514371346,6757370.640605565],[223620.2336364791,6757366.469493383],[223611.548442443,6757354.368245195],[223605.78277151502,6757358.498719655],[223614.37514371346,6757370.640605565]]]]},"properties":{"pk":1233,"id_way":69948401,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224194.53903627093,6757619.945625539],[224188.10282497617,6757619.540438869],[224185.5361562281,6757627.194263145],[224186.06514504267,6757627.351274798],[224182.9026277312,6757637.635371215],[224197.27312893694,6757645.781789362],[224195.01283941846,6757628.038659237],[224195.4225400306,6757627.882981218],[224194.53903627093,6757619.945625539]]]]},"properties":{"pk":1234,"id_way":69948403,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223954.6446058269,6758495.987604149],[223947.45405153307,6758492.35710519],[223943.43793824778,6758500.457018914],[223950.62654295523,6758504.096897714],[223954.6446058269,6758495.987604149]]]]},"properties":{"pk":1235,"id_way":69948420,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224176.78952684734,6757969.8934948025],[224136.10797033456,6757979.288142062],[224138.49756290167,6757989.608982462],[224179.0332176851,6757980.325619969],[224176.78952684734,6757969.8934948025]]]]},"properties":{"pk":1236,"id_way":69948423,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224025.5091838423,6757793.533371217],[224012.4438904742,6757788.675859697],[224008.4334035514,6757799.420324224],[224009.63728391117,6757799.899099426],[224008.47568840533,6757804.126021971],[224019.94672305835,6757808.2787850145],[224025.5091838423,6757793.533371217]]]]},"properties":{"pk":1237,"id_way":69948446,"height":16.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223680.78938562708,6758529.579735401],[223681.91920351374,6758518.534818064],[223670.59828490042,6758517.466722842],[223669.65255886925,6758527.7735769125],[223680.78938562708,6758529.579735401]]]]},"properties":{"pk":1238,"id_way":69948468,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223894.13425109806,6758018.55585502],[223899.46489809302,6758028.0753792655],[223904.02158134698,6758025.481712565],[223904.28530079665,6758025.8711796375],[223906.43725032933,6758024.589616279],[223900.89695534384,6758014.717110451],[223894.13425109806,6758018.55585502]]]]},"properties":{"pk":1239,"id_way":69948469,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223681.34445507746,6758334.735153713],[223683.10373340314,6758327.932721385],[223679.55287227585,6758327.016870221],[223680.035902776,6758324.803210552],[223674.95581486347,6758323.430472907],[223672.76630410456,6758332.77588514],[223681.34445507746,6758334.735153713]]]]},"properties":{"pk":1240,"id_way":69948504,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223590.2042110872,6757885.03306787],[223594.64764581897,6757882.337643939],[223603.12974480816,6757875.078641757],[223595.59599451855,6757867.744275142],[223587.51755368008,6757876.627922744],[223588.98836679154,6757877.93304817],[223588.36404052583,6757878.674578477],[223590.25801459543,6757880.360697348],[223591.41936635415,6757879.998843337],[223592.70628666296,6757881.242364362],[223589.1841870502,6757883.312863687],[223590.2042110872,6757885.03306787]]]]},"properties":{"pk":1241,"id_way":69948508,"height":12.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223759.05261258394,6757857.469031681],[223776.5344240937,6757857.388575637],[223770.73177515928,6757847.066830031],[223757.41848415183,6757854.337047644],[223759.05261258394,6757857.469031681]]]]},"properties":{"pk":1242,"id_way":69948558,"height":12.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223858.67354686913,6757624.159506716],[223862.4374662944,6757624.782410683],[223864.09999895134,6757623.605879038],[223862.3246462265,6757621.1119695855],[223858.43949276724,6757623.823340515],[223858.67354686913,6757624.159506716]]]]},"properties":{"pk":1243,"id_way":69948560,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223782.92485963748,6758195.473272527],[223792.29029247785,6758216.752097632],[223792.89683816538,6758217.687378288],[223793.40921746584,6758218.144912558],[223794.68872612453,6758218.8493298115],[223830.42341350202,6758231.794402578],[223836.52182223188,6758214.97656648],[223816.59651448755,6758207.847739961],[223806.57279150817,6758185.046682656],[223782.92485963748,6758195.473272527]]]]},"properties":{"pk":1244,"id_way":69948584,"height":13.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224471.34273479375,6757436.382303893],[224486.21689877164,6757441.677333346],[224489.07137006184,6757433.615466411],[224474.22787572007,6757428.240895624],[224471.34273479375,6757436.382303893]]]]},"properties":{"pk":1245,"id_way":69948593,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223860.38602373874,6758372.732269033],[223857.6810304235,6758380.0804778095],[223866.69699076575,6758383.392882092],[223868.12436330057,6758379.566081914],[223877.50373430407,6758382.978019146],[223878.77451084447,6758379.5674507525],[223860.38602373874,6758372.732269033]]]]},"properties":{"pk":1246,"id_way":69948611,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224059.8521138407,6757786.883451232],[224064.85160325473,6757788.76125851],[224065.0582732421,6757788.220742648],[224065.55538715565,6757788.336252547],[224067.6430714544,6757782.696671345],[224067.22618695267,6757782.463255413],[224067.3381059968,6757782.155245394],[224062.26334082452,6757780.285326549],[224062.11968137985,6757780.661941111],[224061.70113294528,6757780.58434268],[224059.6230247104,6757786.21707349],[224059.99778860956,6757786.373062469],[224059.8521138407,6757786.883451232]]]]},"properties":{"pk":1247,"id_way":69948614,"height":7.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223715.1013822552,6757771.356502203],[223724.52363324445,6757764.773326157],[223715.72877148964,6757749.003782701],[223707.22377197258,6757753.710492113],[223711.58384144006,6757761.764370547],[223709.48780355885,6757763.2548302915],[223715.1013822552,6757771.356502203]]]]},"properties":{"pk":1248,"id_way":69948637,"height":10.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223681.98355368205,6757312.830815546],[223675.4326319265,6757317.237374118],[223671.3014258614,6757311.587727552],[223665.64974963779,6757315.641938394],[223674.30600882246,6757327.746159085],[223686.35644315797,6757319.2275689],[223681.98355368205,6757312.830815546]]]]},"properties":{"pk":1249,"id_way":69948639,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223731.79181065198,6757952.479453616],[223728.5211478925,6757946.605473985],[223719.03355663738,6757951.858345446],[223720.76997863798,6757954.852387821],[223721.2704511801,6757954.611056358],[223721.98988044198,6757955.890992014],[223720.04311128243,6757956.925751633],[223719.6156998977,6757956.349509866],[223718.86406128673,6757956.491027021],[223708.055447863,6757962.577128922],[223709.37803861147,6757965.050832377],[223731.79181065198,6757952.479453616]]]]},"properties":{"pk":1250,"id_way":69948660,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223956.04763564706,6757640.702968387],[223966.17817854477,6757635.940412363],[223973.58184715873,6757631.973920448],[223970.34778559968,6757625.9917653445],[223962.27630046246,6757630.965371075],[223964.0553093575,6757634.131642383],[223962.53685551276,6757634.851272169],[223961.35035023143,6757632.424437284],[223960.78326155053,6757632.58200328],[223958.79437877412,6757628.392687013],[223960.1740652931,6757627.682109763],[223959.09838404274,6757625.7707017],[223950.99720819815,6757630.432293006],[223955.95592813002,6757640.744187443],[223956.04763564706,6757640.702968387]]]]},"properties":{"pk":1251,"id_way":69948662,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223868.1956604367,6758148.371737372],[223869.791590224,6758155.455416957],[223879.35872986857,6758153.135679369],[223882.31235399452,6758145.154978337],[223868.1956604367,6758148.371737372]]]]},"properties":{"pk":1252,"id_way":69948683,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224060.80209245256,6758549.716326215],[224052.0243853627,6758545.290228501],[224047.97466286423,6758553.4373379275],[224056.7596725486,6758557.862834346],[224060.80209245256,6758549.716326215]]]]},"properties":{"pk":1253,"id_way":69948684,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223842.79738080935,6757840.338657503],[223837.0050384295,6757844.1648588395],[223848.14539586005,6757861.08093704],[223853.90643567985,6757857.333723891],[223842.79738080935,6757840.338657503]]]]},"properties":{"pk":1254,"id_way":69948686,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224026.90834298875,6757551.568178022],[224021.05400931463,6757554.853350575],[224025.9184527074,6757563.451890401],[224031.69691380145,6757560.160846074],[224026.90834298875,6757551.568178022]]]]},"properties":{"pk":1255,"id_way":69948688,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224060.655358301,6758013.090801106],[224058.6292438208,6758018.446098246],[224059.01228075963,6758018.726774161],[224053.6054792788,6758033.38580924],[224058.53636252278,6758035.178144783],[224065.88341740755,6758015.004364457],[224060.655358301,6758013.090801106]]]]},"properties":{"pk":1256,"id_way":69948708,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223956.76983570957,6757764.247379049],[223951.0939931585,6757768.150238968],[223957.23638628318,6757777.121882007],[223962.9170670848,6757773.18602216],[223956.76983570957,6757764.247379049]]]]},"properties":{"pk":1257,"id_way":69948731,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223883.55777494636,6757614.246833693],[223886.98635233133,6757619.069219216],[223889.28307395952,6757617.415466652],[223885.91171553885,6757612.587592469],[223883.55777494636,6757614.246833693]]]]},"properties":{"pk":1258,"id_way":69948733,"height":3.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223977.26437300327,6758111.11290121],[223974.96825506963,6758118.112036047],[223992.77806826867,6758124.010155961],[223997.3795230184,6758111.41145671],[223986.82946785376,6758108.765768789],[223984.94808415568,6758113.779305824],[223977.26437300327,6758111.11290121]]]]},"properties":{"pk":1259,"id_way":69948753,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223983.904675219,6758030.165198339],[223990.64121863252,6758032.21186469],[223993.79645448213,6758022.295302638],[223987.4745995911,6758019.979103174],[223986.5113924684,6758022.6018172],[223986.333820643,6758022.681161335],[223983.904675219,6758030.165198339]]]]},"properties":{"pk":1260,"id_way":69948754,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223559.1210744067,6757640.431386156],[223550.25756363987,6757627.82153644],[223542.97601615216,6757632.977358318],[223551.95953338334,6757645.51142777],[223559.1210744067,6757640.431386156]]]]},"properties":{"pk":1261,"id_way":69948756,"height":9.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223547.30211051484,6757918.728833327],[223535.9298392335,6757915.36447392],[223534.18859635302,6757921.241769899],[223538.1013678696,6757924.058867069],[223547.30211051484,6757918.728833327]]]]},"properties":{"pk":1262,"id_way":69948781,"height":13.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223556.17496677904,6757547.629554225],[223557.81124580835,6757547.308567923],[223557.2331066277,6757544.500786457],[223555.68051936195,6757544.814553146],[223556.17496677904,6757547.629554225]]]]},"properties":{"pk":1263,"id_way":69948806,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223892.23628675772,6758572.32330628],[223882.62545889328,6758569.752661285],[223876.35298874826,6758586.3417728385],[223887.4543586018,6758589.622797765],[223892.23628675772,6758572.32330628]]]]},"properties":{"pk":1264,"id_way":69948824,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223739.43375513382,6757259.407828818],[223738.50921011603,6757260.085712872],[223739.00636265604,6757260.724068963],[223739.95988077487,6757260.009284367],[223742.76928399116,6757263.964830629],[223750.0745550308,6757258.806649725],[223746.7635673651,6757254.142129018],[223739.43375513382,6757259.407828818]]]]},"properties":{"pk":1265,"id_way":69948829,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223639.70473761836,6758137.723582651],[223634.3402153749,6758140.81295232],[223635.51008648492,6758142.855826586],[223640.87777595982,6758139.798314621],[223639.70473761836,6758137.723582651]]]]},"properties":{"pk":1266,"id_way":69948849,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223835.1101249101,6758103.896772037],[223816.1886504828,6758114.77999558],[223819.96146877593,6758121.483624963],[223838.99207347693,6758110.757225756],[223835.1101249101,6758103.896772037]]]]},"properties":{"pk":1267,"id_way":69948850,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224035.53293164182,6757587.199753878],[224030.8713303716,6757589.440648661],[224031.18663601697,6757590.255253635],[224032.6369715513,6757592.772235021],[224037.68340250873,6757589.918792675],[224035.8001253405,6757586.613807396],[224035.35244312283,6757586.834513939],[224035.53293164182,6757587.199753878]]]]},"properties":{"pk":1268,"id_way":69948854,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224185.16325260545,6757981.961556157],[224180.38826298676,6757960.929592409],[224175.25181549473,6757961.408399576],[224179.87313323616,6757983.248350325],[224185.16325260545,6757981.961556157]]]]},"properties":{"pk":1269,"id_way":69948874,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223929.48441826715,6757807.009107164],[223926.9085606293,6757800.208295419],[223917.75536988012,6757803.743898723],[223920.3092980794,6757810.633771174],[223929.48441826715,6757807.009107164]]]]},"properties":{"pk":1270,"id_way":69948897,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223632.22109680495,6757291.683355711],[223625.9175895722,6757296.333777893],[223630.29024131756,6757302.574319644],[223636.65549103369,6757297.9624030925],[223632.22109680495,6757291.683355711]]]]},"properties":{"pk":1271,"id_way":69948899,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223622.80432686373,6758491.297023845],[223621.7609677264,6758502.431572317],[223635.56527742118,6758503.7118354095],[223636.60579274208,6758492.456565744],[223622.80432686373,6758491.297023845]]]]},"properties":{"pk":1272,"id_way":69948906,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223592.8055992071,6758359.521264572],[223594.80685599003,6758347.682673243],[223573.21536117373,6758344.036607861],[223571.24093494384,6758355.839877932],[223592.8055992071,6758359.521264572]]]]},"properties":{"pk":1273,"id_way":69948944,"height":22.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224234.4147843119,6758681.300403454],[224240.22687710557,6758678.547742695],[224258.89219957474,6758667.7255235575],[224268.17068618984,6758662.0528915785],[224281.56243740255,6758651.936451666],[224296.1261680577,6758639.841344035],[224309.7325224143,6758626.675262601],[224315.13020246048,6758621.125838717],[224320.65269972364,6758614.975387437],[224325.15839999664,6758609.73196148],[224330.52212497432,6758602.92328023],[224344.6699592642,6758570.500931213],[224339.54910280128,6758568.049737178],[224325.84842939972,6758599.13825364],[224312.03300401763,6758615.882068872],[224302.8029287485,6758625.459700349],[224291.82055123302,6758635.555228069],[224283.63854859088,6758642.804769252],[224276.1846341059,6758648.759341653],[224262.18596232217,6758659.043470874],[224248.15970949104,6758667.6795356395],[224231.82655735192,6758676.637227502],[224234.4147843119,6758681.300403454]]]]},"properties":{"pk":1274,"id_way":69948945,"height":3.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223562.91166763427,6757888.650563778],[223561.56136383486,6757888.192116482],[223558.1145708363,6757892.314852605],[223559.36964347,6757893.26931656],[223562.91166763427,6757888.650563778]]]]},"properties":{"pk":1275,"id_way":69948947,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223805.88530575542,6758574.851461914],[223808.7935847292,6758566.938768796],[223790.69598909706,6758561.594511394],[223787.52518836726,6758569.926030027],[223805.88530575542,6758574.851461914]]]]},"properties":{"pk":1276,"id_way":69948989,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223700.61792603135,6757835.1276885085],[223710.53093568317,6757828.616120631],[223702.8510095862,6757817.116508237],[223692.93459091088,6757823.584446248],[223700.61792603135,6757835.1276885085]]]]},"properties":{"pk":1277,"id_way":69948992,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223854.53545660368,6757304.829690332],[223783.65484833476,6757354.703029488],[223788.29253857123,6757361.344850173],[223859.17385594128,6757311.316843026],[223854.53545660368,6757304.829690332]]]]},"properties":{"pk":1278,"id_way":69948994,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223690.33963970566,6758164.828785383],[223696.27039913385,6758178.294782811],[223704.32617750345,6758174.832155327],[223698.44906954726,6758161.29625956],[223690.33963970566,6758164.828785383]]]]},"properties":{"pk":1279,"id_way":69949014,"height":10.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223871.50702364082,6758118.788244994],[223875.55092148815,6758116.554985244],[223870.66080090124,6758107.914367969],[223860.3812216306,6758113.731333148],[223866.59320759194,6758141.347786184],[223881.2984297441,6758138.136371092],[223880.22717979047,6758133.195265398],[223875.15949789548,6758134.37324667],[223871.50702364082,6758118.788244994]]]]},"properties":{"pk":1280,"id_way":69949015,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224104.42561387323,6757469.683769553],[224108.0603827022,6757474.81401751],[224122.30754117054,6757464.849174892],[224118.58362335723,6757459.626319198],[224104.42561387323,6757469.683769553]]]]},"properties":{"pk":1281,"id_way":69949019,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223833.5626143894,6757890.066469067],[223829.7061155336,6757883.247847212],[223811.67603825527,6757893.348091098],[223815.47413045474,6757900.171116265],[223833.5626143894,6757890.066469067]]]]},"properties":{"pk":1282,"id_way":69949039,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224019.41884130327,6757710.063475813],[224025.6099163589,6757706.615803168],[224023.966715189,6757703.464191187],[224017.7370037447,6757706.7204245385],[224019.41884130327,6757710.063475813]]]]},"properties":{"pk":1283,"id_way":69949066,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223614.0972516233,6757601.768422427],[223624.46750042867,6757594.456743949],[223615.4323273655,6757581.9266590895],[223605.1847494446,6757589.195319617],[223614.0972516233,6757601.768422427]]]]},"properties":{"pk":1284,"id_way":69949068,"height":10.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223847.624781753,6758632.665679447],[223855.5506692964,6758635.6850631535],[223858.80842414542,6758627.309092852],[223850.82700197765,6758624.239695957],[223847.624781753,6758632.665679447]]]]},"properties":{"pk":1285,"id_way":69949087,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223993.43574709317,6757920.952072996],[223995.13038293732,6757916.391936033],[223985.93015355786,6757912.97143928],[223984.0882398416,6757917.622877557],[223979.53545156613,6757915.962372897],[223975.0219425342,6757928.005801021],[223988.88685846937,6757933.177512984],[223993.43574709317,6757920.952072996]]]]},"properties":{"pk":1286,"id_way":69949090,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224037.16632068748,6757600.78268442],[224038.5018668712,6757603.1205893615],[224044.7688449829,6757602.528663895],[224042.23450406606,6757598.035862988],[224037.16632068748,6757600.78268442]]]]},"properties":{"pk":1287,"id_way":69949092,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223817.3456150211,6758309.813848326],[223829.25910006152,6758314.273486968],[223838.67977686206,6758289.194458823],[223826.53580204622,6758284.741711039],[223817.3456150211,6758309.813848326]]]]},"properties":{"pk":1288,"id_way":69949113,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224003.42886424292,6757976.988603158],[223992.33858229904,6758006.35940644],[223997.44733285598,6758008.053448857],[224008.47271835982,6757978.708615745],[224003.42886424292,6757976.988603158]]]]},"properties":{"pk":1289,"id_way":69949114,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224215.40151190443,6757639.170820744],[224215.9643354271,6757644.264158827],[224218.81563692619,6757643.898717395],[224218.19531493986,6757638.810097696],[224215.40151190443,6757639.170820744]]]]},"properties":{"pk":1290,"id_way":69949118,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224002.5461939427,6758556.6164948875],[224005.20859620543,6758557.807672812],[224004.11300554874,6758560.335956716],[224007.7963407194,6758561.91650319],[224012.15848422804,6758551.205997315],[224009.55598557857,6758549.935435729],[224009.73950200973,6758549.432906214],[224006.01336989243,6758547.766952004],[224002.5461939427,6758556.6164948875]]]]},"properties":{"pk":1291,"id_way":69949135,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224039.19465081848,6757842.729444787],[224036.75978077835,6757849.331135837],[224045.12066069175,6757852.352047503],[224047.55166532294,6757845.79425018],[224039.19465081848,6757842.729444787]]]]},"properties":{"pk":1292,"id_way":69949162,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223718.4559522109,6758474.929133304],[223706.6706339657,6758474.708172004],[223706.59006873122,6758483.632230612],[223718.3838572778,6758483.775776212],[223718.4559522109,6758474.929133304]]]]},"properties":{"pk":1293,"id_way":69949185,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223931.69053448958,6757997.299338861],[223937.07989293625,6758006.814311615],[223939.3649336405,6758005.515544099],[223939.76248390964,6758006.199994485],[223937.44332535134,6758007.503561452],[223941.21448961273,6758014.605368565],[223947.55848434774,6758011.001982182],[223938.00855462268,6757993.741618949],[223931.69053448958,6757997.299338861]]]]},"properties":{"pk":1294,"id_way":69949186,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223708.0796969318,6758355.655465677],[223723.62806432456,6758361.379441158],[223727.29524388124,6758348.593899651],[223719.05809954277,6758346.296132694],[223717.97787110825,6758349.903552424],[223711.10882264696,6758347.2793820845],[223708.0796969318,6758355.655465677]]]]},"properties":{"pk":1295,"id_way":69949217,"height":9.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224068.6573601997,6758578.1454834705],[224062.23533703233,6758590.988520112],[224066.70002856638,6758593.276317211],[224069.01708358296,6758588.743096591],[224078.56677672782,6758593.4984009],[224082.3839851587,6758584.994989817],[224068.6573601997,6758578.1454834705]]]]},"properties":{"pk":1296,"id_way":69949218,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223781.770423421,6757912.06404543],[223775.80855612864,6757915.393904178],[223777.6266502728,6757918.576475763],[223783.5590361047,6757915.249215245],[223781.770423421,6757912.06404543]]]]},"properties":{"pk":1297,"id_way":69949220,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223570.1896939527,6757462.29728245],[223574.86592897444,6757459.345881692],[223564.9730944717,6757444.647790849],[223558.18252286437,6757448.943035867],[223556.6140122821,6757446.452244661],[223549.84513979877,6757450.947962954],[223584.39190081577,6757505.549686635],[223612.54106071065,6757485.5790373115],[223606.77724514023,6757477.121808917],[223603.47073107478,6757479.408303219],[223604.15011429298,6757480.477680013],[223589.9938755487,6757490.67395526],[223587.30632266018,6757486.751324927],[223586.20328667696,6757487.466260335],[223570.1896939527,6757462.29728245]]]]},"properties":{"pk":1298,"id_way":69949254,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223978.93992936827,6757963.530035741],[223980.97993962458,6757957.9964935705],[223965.92857215987,6757952.385108863],[223963.85721020956,6757957.888519306],[223978.93992936827,6757963.530035741]]]]},"properties":{"pk":1299,"id_way":69949275,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223603.45370038314,6758111.172508754],[223606.60275640612,6758116.843762524],[223609.0950482242,6758115.412517493],[223605.97406180575,6758109.728095101],[223603.45370038314,6758111.172508754]]]]},"properties":{"pk":1300,"id_way":69949298,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223905.67872704545,6758195.584676172],[223917.29189329824,6758204.314891719],[223918.84946548217,6758198.092301634],[223915.50099201297,6758195.794235579],[223917.10384067887,6758191.271051632],[223908.41344234432,6758188.087938986],[223905.67872704545,6758195.584676172]]]]},"properties":{"pk":1301,"id_way":69949299,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223968.4740903194,6758442.684981323],[223970.36457807844,6758450.392458952],[223980.2972617459,6758447.851910011],[223978.4057985691,6758440.221400877],[223968.4740903194,6758442.684981323]]]]},"properties":{"pk":1302,"id_way":69949326,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223590.3051072381,6757885.205784237],[223594.07215400453,6757891.755436559],[223605.71080476415,6757885.014469311],[223607.12717569675,6757878.997614257],[223603.27332472213,6757875.218952944],[223596.9511964821,6757880.654967186],[223598.1434759167,6757882.057257326],[223595.34933240578,6757883.69340156],[223594.6718720147,6757882.556868929],[223590.3051072381,6757885.205784237]]]]},"properties":{"pk":1303,"id_way":69949329,"height":15.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223913.65662163045,6757708.750586647],[223920.2038937634,6757705.455176628],[223911.62174537446,6757688.934527281],[223904.69361255213,6757691.501201245],[223913.65662163045,6757708.750586647]]]]},"properties":{"pk":1304,"id_way":69949358,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223616.76970953503,6758421.696050946],[223618.91784652288,6758414.189939443],[223615.76755956077,6758413.478895932],[223613.67506800193,6758420.875835113],[223616.76970953503,6758421.696050946]]]]},"properties":{"pk":1305,"id_way":69949384,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223791.06844689112,6757928.637110474],[223785.19243271247,6757932.00210421],[223786.98221933548,6757935.187019595],[223792.85512197463,6757931.865257079],[223791.06844689112,6757928.637110474]]]]},"properties":{"pk":1306,"id_way":69949386,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223901.36458066825,6757663.5328491],[223896.25256318567,6757656.217020371],[223885.8426863359,6757663.565328891],[223893.7888477146,6757684.575967342],[223902.9388300836,6757680.887153611],[223902.8005477217,6757680.506301133],[223909.892603464,6757675.398762853],[223906.6481419782,6757670.9428683175],[223900.809728173,6757675.613202477],[223897.35077659597,6757666.275402378],[223901.36458066825,6757663.5328491]]]]},"properties":{"pk":1307,"id_way":69949388,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223584.12404077093,6758278.916241557],[223582.17687324647,6758290.493055616],[223591.83985852374,6758292.017294275],[223593.77944275932,6758280.528491139],[223584.12404077093,6758278.916241557]]]]},"properties":{"pk":1308,"id_way":69949414,"height":10.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224133.4803118802,6758442.116140626],[224129.95696022286,6758450.293447279],[224150.75848623348,6758459.149420534],[224149.4835864038,6758461.968613214],[224143.4816181804,6758459.477791241],[224134.34183218612,6758481.072081053],[224151.67296995455,6758488.453248882],[224160.87190177775,6758466.854540494],[224154.9518718271,6758464.310483785],[224155.77861077504,6758462.47728741],[224157.4280685957,6758463.112008979],[224157.81906852033,6758462.1635449035],[224165.04752850367,6758465.2182897385],[224163.52907033748,6758468.763728317],[224168.11764073072,6758470.756740137],[224166.83791127236,6758473.713448116],[224176.47957401356,6758477.884217439],[224172.20476454613,6758488.004328862],[224170.37421697853,6758487.215420953],[224167.5940733434,6758493.704499259],[224183.24209748235,6758500.331076118],[224183.33133178615,6758500.134537846],[224195.0162401522,6758505.0536974585],[224199.48854749385,6758494.459687613],[224187.8620326278,6758489.5458536735],[224193.05933336943,6758477.165972346],[224211.1736744633,6758484.894418541],[224210.75333144196,6758485.843771872],[224212.53125794895,6758486.636751205],[224211.8132163395,6758488.253483426],[224219.59078639248,6758491.545994088],[224220.74903152097,6758488.94447488],[224238.9996229397,6758496.689668897],[224242.5189798889,6758488.457641775],[224224.68575131547,6758480.957036473],[224227.3029552451,6758474.725813422],[224219.11285995244,6758471.188549118],[224217.5077303876,6758474.862188107],[224212.56662959076,6758472.76342978],[224212.8298006131,6758472.017271574],[224198.12253077427,6758465.699205534],[224202.96330232924,6758454.386078084],[224239.9112852284,6758470.064849953],[224242.4121227398,6758464.268866994],[224244.3621812517,6758465.058837917],[224254.07523310866,6758442.268708738],[224251.6134086713,6758441.196613145],[224252.88627961275,6758438.207346881],[224256.70464017772,6758439.883298609],[224262.06280741454,6758427.235089379],[224221.74664002968,6758410.092857219],[224219.36933408075,6758415.657116137],[224215.72683613256,6758414.111871452],[224194.46020059675,6758464.112891695],[224191.05316483745,6758462.772867069],[224192.36262781618,6758459.610916578],[224189.05301652758,6758458.220061774],[224187.77930602885,6758461.25467753],[224165.97133268538,6758452.012588422],[224165.6436200721,6758452.79773468],[224160.69982811838,6758450.660639827],[224162.27142411674,6758447.0336463265],[224154.02780091861,6758443.457781561],[224151.40739628897,6758449.732346662],[224133.4803118802,6758442.116140626]]]]},"properties":{"pk":1309,"id_way":69949415,"height":18.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223905.73205415555,6757883.582176435],[223896.6664661934,6757887.679596135],[223897.99040531716,6757890.707292048],[223893.90336673817,6757893.062177239],[223898.6478254214,6757901.637106617],[223910.664065535,6757894.796021671],[223905.73205415555,6757883.582176435]]]]},"properties":{"pk":1310,"id_way":69949417,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224009.73196005513,6757587.773394788],[224013.42847419757,6757596.527277727],[224020.75086400652,6757592.682826145],[224016.84781348874,6757583.739050503],[224009.73196005513,6757587.773394788]]]]},"properties":{"pk":1311,"id_way":69949419,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224086.53917746144,6757979.445756953],[224084.67027783726,6757984.708581736],[224086.88323533762,6757985.506307898],[224088.803308524,6757980.250567118],[224086.53917746144,6757979.445756953]]]]},"properties":{"pk":1312,"id_way":69949445,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223741.82201228128,6758495.508659945],[223739.79207478356,6758514.233362071],[223752.4755629017,6758515.437242643],[223756.71972772304,6758512.906588147],[223763.02981093846,6758495.438817243],[223741.82201228128,6758495.508659945]]]]},"properties":{"pk":1313,"id_way":69949465,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223987.7627946326,6757783.131700963],[223983.5124092694,6757774.633110462],[223980.52235822866,6757769.653132003],[223971.47705173286,6757773.903809991],[223973.73341995088,6757778.2031754125],[223975.616252397,6757783.852462676],[223979.4390985801,6757789.322764583],[223982.84986349524,6757791.632543236],[223987.7627946326,6757783.131700963]]]]},"properties":{"pk":1314,"id_way":69949468,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223691.49707163937,6758118.665794893],[223711.38271772538,6758103.457509622],[223706.42404724032,6758096.937914179],[223686.5406995044,6758112.25603235],[223691.49707163937,6758118.665794893]]]]},"properties":{"pk":1315,"id_way":69949490,"height":10.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223760.43938062058,6758106.793927638],[223770.075132164,6758101.289929785],[223773.52619902676,6758107.253617141],[223778.54293392357,6758104.402413148],[223769.85178968482,6758088.923077917],[223755.05359865818,6758097.323130473],[223760.43938062058,6758106.793927638]]]]},"properties":{"pk":1316,"id_way":69949491,"height":12.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223509.65028975013,6757512.578715111],[223509.21286871473,6757510.251523929],[223506.36833336292,6757510.949962025],[223506.93145036622,6757513.204795117],[223509.65028975013,6757512.578715111]]]]},"properties":{"pk":1317,"id_way":69949493,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223986.55497042314,6757469.368716692],[223990.12843760636,6757466.76612596],[223983.71839143784,6757457.634828061],[223980.090262262,6757460.188734349],[223986.55497042314,6757469.368716692]]]]},"properties":{"pk":1318,"id_way":69949495,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223972.5405161702,6757728.941279588],[223967.049084031,6757717.496910536],[223957.39801662465,6757722.095724882],[223949.3020309718,6757726.687268402],[223954.87187462408,6757738.092609604],[223972.5405161702,6757728.941279588]]]]},"properties":{"pk":1319,"id_way":69949540,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223807.08475369532,6758589.844112374],[223809.67232023834,6758590.766653388],[223811.13297292273,6758586.140373288],[223808.6820947542,6758585.218871215],[223807.08475369532,6758589.844112374]]]]},"properties":{"pk":1320,"id_way":69949561,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223799.5256354882,6757957.789441696],[223793.28137292745,6757946.727025537],[223788.95280186587,6757949.172321247],[223786.23643679937,6757944.307495421],[223777.9958506693,6757948.814567556],[223787.03966909947,6757964.855003425],[223799.5256354882,6757957.789441696]]]]},"properties":{"pk":1321,"id_way":69949564,"height":12.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224043.78867945672,6757623.929475137],[224044.67559877314,6757621.400390659],[224039.24706252158,6757619.479869776],[224038.4138685125,6757621.971677915],[224043.78867945672,6757623.929475137]]]]},"properties":{"pk":1322,"id_way":69949566,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223648.15644328596,6758165.1736201085],[223653.23527183227,6758160.359256791],[223651.5630971984,6758158.62691497],[223646.22923512317,6758161.8103371365],[223648.15644328596,6758165.1736201085]]]]},"properties":{"pk":1323,"id_way":69949586,"height":3.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224050.8027052485,6758072.803057498],[224059.52300181933,6758075.907325055],[224062.93238889394,6758066.66294688],[224054.18925456217,6758063.549567199],[224050.8027052485,6758072.803057498]]]]},"properties":{"pk":1324,"id_way":69949587,"height":7.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223590.69852484603,6757359.645934841],[223584.5842992918,6757350.995135434],[223577.0095917657,6757356.35351472],[223583.0337417835,6757364.891565445],[223590.69852484603,6757359.645934841]]]]},"properties":{"pk":1325,"id_way":69949589,"height":12.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224147.6051380521,6757368.805289227],[224146.4201397588,6757367.045260987],[224146.75207789495,6757366.850245922],[224146.3312382052,6757366.197473947],[224142.32348482273,6757368.916431047],[224142.79832662886,6757369.583721288],[224143.09211236864,6757369.426958954],[224144.29626620634,6757371.044108244],[224143.9690732892,6757371.3177731475],[224144.45032978783,6757372.026187689],[224148.43613792493,6757369.275621035],[224147.93374506885,6757368.565803457],[224147.6051380521,6757368.805289227]]]]},"properties":{"pk":1326,"id_way":69949591,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223933.91494021378,6758495.619491948],[223943.25956045138,6758500.366549832],[223947.27525974746,6758492.267471064],[223937.95387351373,6758487.62779535],[223933.91494021378,6758495.619491948]]]]},"properties":{"pk":1327,"id_way":69949608,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224065.5140447857,6757883.466925168],[224060.2293745948,6757881.396348445],[224059.28375114236,6757884.00823243],[224064.54658618858,6757885.963117879],[224065.5140447857,6757883.466925168]]]]},"properties":{"pk":1328,"id_way":69949611,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223864.2291207687,6757810.55756971],[223871.07453522878,6757806.015329809],[223865.7562794353,6757794.124865052],[223857.81170614032,6757797.773989759],[223859.84957689044,6757802.355352234],[223859.06222333378,6757802.746820433],[223864.2291207687,6757810.55756971]]]]},"properties":{"pk":1329,"id_way":69949634,"height":13.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224179.06442665283,6757211.024575705],[224187.74467441387,6757234.3973209765],[224227.26178809235,6757219.649921674],[224223.35234256022,6757209.357105385],[224194.2581357763,6757220.28676984],[224189.25057544312,6757207.236438864],[224179.06442665283,6757211.024575705]]]]},"properties":{"pk":1330,"id_way":69949661,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223628.21990647,6758548.545248953],[223637.43937956454,6758550.070454878],[223638.87437553558,6758541.353984113],[223629.6587017646,6758539.784815945],[223628.21990647,6758548.545248953]]]]},"properties":{"pk":1331,"id_way":69949681,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223577.95325091496,6757942.345871567],[223587.99901657802,6757945.120428008],[223589.88278012513,6757938.400910832],[223587.1456269857,6757937.6251234645],[223587.00461140543,6757937.269079862],[223580.1558467245,6757935.354577125],[223577.95325091496,6757942.345871567]]]]},"properties":{"pk":1332,"id_way":69949684,"height":9.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223883.13423056793,6758617.954713618],[223884.0072450448,6758618.064434269],[223885.18296354375,6758609.413920461],[223880.21355466585,6758608.717429613],[223877.0390444439,6758617.092325552],[223883.13423056793,6758617.954713618]]]]},"properties":{"pk":1333,"id_way":69949728,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223772.00145448998,6757784.216678647],[223769.52390448903,6757779.781058217],[223773.96640822955,6757777.182469827],[223760.05595911996,6757752.769370696],[223747.17501639054,6757761.954823139],[223762.63410853833,6757789.503648387],[223772.00145448998,6757784.216678647]]]]},"properties":{"pk":1334,"id_way":69949731,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223826.26653104703,6757709.802255394],[223824.1117094116,6757707.026804995],[223811.19668256122,6757716.217617929],[223818.55331688508,6757726.653823193],[223824.19811795955,6757722.689012221],[223832.26875030453,6757718.825387306],[223831.68589497436,6757717.502334161],[223826.26653104703,6757709.802255394]]]]},"properties":{"pk":1335,"id_way":69949733,"height":9.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223796.1150552492,6758161.268054933],[223785.3190880804,6758136.702970231],[223761.76293554003,6758147.155194839],[223772.52936773494,6758171.722699078],[223796.1150552492,6758161.268054933]]]]},"properties":{"pk":1336,"id_way":69949753,"height":9.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223954.37605219908,6758007.215052837],[223957.26676627726,6758008.326958474],[223959.1006693683,6758003.299626],[223955.79704142336,6758001.982486997],[223954.00135112205,6758006.585039535],[223954.37605219908,6758007.215052837]]]]},"properties":{"pk":1337,"id_way":69949754,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224449.68108363645,6757420.896771196],[224411.23878823576,6757407.150121101],[224408.54350703186,6757416.976628986],[224446.26710937964,6757430.6966408],[224449.68108363645,6757420.896771196]]]]},"properties":{"pk":1338,"id_way":69949758,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223857.34980141837,6758408.769327036],[223862.4294392851,6758394.8258644035],[223853.5021693761,6758391.557618956],[223848.45512925257,6758405.3826128375],[223857.34980141837,6758408.769327036]]]]},"properties":{"pk":1339,"id_way":69949775,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224159.01171879488,6757762.5884793075],[224175.56954754092,6757768.791894897],[224178.71186780863,6757760.138882193],[224162.0404926584,6757754.088150324],[224159.01171879488,6757762.5884793075]]]]},"properties":{"pk":1340,"id_way":69949778,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223900.98065827697,6757784.960478135],[223893.18514387592,6757774.738621393],[223890.19452182748,6757776.768360016],[223892.9392143966,6757780.961740231],[223889.38586164184,6757783.32189045],[223894.10742918908,6757790.536062006],[223900.98065827697,6757784.960478135]]]]},"properties":{"pk":1341,"id_way":69949802,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223650.86055161897,6757344.644982577],[223645.2233698374,6757336.700065855],[223638.44732724814,6757341.424900884],[223644.14727164188,6757349.409616863],[223650.86055161897,6757344.644982577]]]]},"properties":{"pk":1342,"id_way":69949804,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223685.96816066533,6758002.922390516],[223694.3620372362,6757997.830631747],[223689.92080768224,6757990.3336384],[223681.49285876023,6757995.548217295],[223685.96816066533,6758002.922390516]]]]},"properties":{"pk":1343,"id_way":69949824,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223893.0188009206,6757622.360987355],[223895.37921880375,6757620.668692438],[223891.91999766103,6757615.759438254],[223889.5602674367,6757617.46220227],[223893.0188009206,6757622.360987355]]]]},"properties":{"pk":1344,"id_way":69949827,"height":3.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223855.26972502228,6758150.930933855],[223852.44409626804,6758141.207787807],[223843.09786760533,6758144.16918041],[223845.65953921276,6758153.269074851],[223855.26972502228,6758150.930933855]]]]},"properties":{"pk":1345,"id_way":69949851,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224020.02509853977,6758442.730810986],[224020.5683907336,6758441.534880006],[224019.0506943545,6758440.8420324875],[224018.5224982651,6758442.066250563],[224020.02509853977,6758442.730810986]]]]},"properties":{"pk":1346,"id_way":69949852,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223944.53949588825,6757846.655505129],[223939.30953620456,6757832.858604711],[223930.102647441,6757836.354528706],[223935.45490267838,6757850.010169048],[223944.53949588825,6757846.655505129]]]]},"properties":{"pk":1347,"id_way":69949854,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224114.815135552,6757511.556139205],[224109.29061467422,6757503.614347181],[224103.43749247087,6757507.751456459],[224109.04797924176,6757515.664300374],[224114.815135552,6757511.556139205]]]]},"properties":{"pk":1348,"id_way":69949856,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224040.11558694832,6758028.4995738305],[224048.5068959897,6758031.529173232],[224054.68782752962,6758014.703975756],[224046.2937343299,6758011.641820021],[224040.11558694832,6758028.4995738305]]]]},"properties":{"pk":1349,"id_way":69949876,"height":10.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223814.85424522922,6757764.227149284],[223806.39656970688,6757749.653173132],[223798.7453616503,6757754.042246824],[223807.14391468113,6757768.621333361],[223814.85424522922,6757764.227149284]]]]},"properties":{"pk":1350,"id_way":69949899,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223999.76109659576,6758104.810911336],[223990.30833950592,6758101.388014261],[223987.64220035344,6758108.811601709],[223997.4481989186,6758111.222385083],[223999.76109659576,6758104.810911336]]]]},"properties":{"pk":1351,"id_way":69949927,"height":10.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223961.30495319035,6758642.686356864],[223970.97618310293,6758643.760124299],[223977.32882002817,6758646.849964842],[223982.34544700352,6758627.683224731],[223966.37951055687,6758623.4762667585],[223961.30495319035,6758642.686356864]]]]},"properties":{"pk":1352,"id_way":69949960,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223695.3935079839,6757871.217228337],[223708.59415021035,6757861.763537027],[223700.1823484829,6757851.192409709],[223688.0479997971,6757859.200161007],[223687.799203973,6757860.006309381],[223688.3399188864,6757861.290658568],[223695.3935079839,6757871.217228337]]]]},"properties":{"pk":1353,"id_way":69949962,"height":15.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223562.47975138063,6757527.725239845],[223552.89834019673,6757529.72299579],[223554.61961886394,6757539.091618278],[223564.43567008007,6757536.900121823],[223562.47975138063,6757527.725239845]]]]},"properties":{"pk":1354,"id_way":69949987,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223565.55000538597,6758390.073771721],[223575.15322998544,6758391.679294518],[223575.66056883623,6758388.840386065],[223581.34453117655,6758389.796544351],[223581.96546936946,6758386.083808591],[223566.6522080416,6758383.480249141],[223565.55000538597,6758390.073771721]]]]},"properties":{"pk":1355,"id_way":69950008,"height":6.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223886.4753492019,6757272.584815075],[223904.33958155953,6757259.818123649],[223895.27028798408,6757246.811421346],[223877.14369174364,6757259.456135065],[223886.4753492019,6757272.584815075]]]]},"properties":{"pk":1356,"id_way":69950011,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223637.1086499807,6758133.139557191],[223631.71130623642,6758136.188593038],[223632.88417298676,6758138.263014277],[223638.24945880307,6758135.173204668],[223637.1086499807,6758133.139557191]]]]},"properties":{"pk":1357,"id_way":69950031,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223938.6025358425,6758216.22702461],[223942.94223790875,6758224.988521229],[223944.95491241547,6758224.034694636],[223947.54811535348,6758229.252572713],[223951.61284192192,6758227.259261007],[223944.5881744984,6758213.243544616],[223938.6025358425,6758216.22702461]]]]},"properties":{"pk":1358,"id_way":69950032,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224030.04420921128,6757576.233397906],[224031.24930003285,6757578.6697230665],[224036.46417869953,6757575.737880132],[224035.12185343038,6757573.3427099],[224030.04420921128,6757576.233397906]]]]},"properties":{"pk":1359,"id_way":69950036,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224003.40199503498,6757976.768131299],[224008.84776482295,6757978.637131959],[224010.82430872758,6757973.379771131],[223998.31510357157,6757969.051665045],[223999.20741451194,6757966.376968007],[224002.16978871383,6757967.376168959],[224002.47199579142,6757966.548150467],[224006.31517256706,6757967.897963828],[224006.7346507165,6757966.671837279],[224012.59169727252,6757968.697189282],[224015.7397115212,6757960.319332528],[223995.48198026768,6757953.042099103],[223988.7015179233,6757971.564632123],[224003.40199503498,6757976.768131299]]]]},"properties":{"pk":1360,"id_way":69950056,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223926.83776711035,6757800.021238919],[223922.2051715912,6757787.770875608],[223912.60037647095,6757794.156804204],[223916.06821340355,6757799.893977347],[223917.68038660826,6757803.558460599],[223926.83776711035,6757800.021238919]]]]},"properties":{"pk":1361,"id_way":69950079,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223702.69783591988,6757287.117108924],[223714.62468249278,6757278.723132179],[223710.9307466786,6757273.432370042],[223699.28935370722,6757281.739905549],[223702.69783591988,6757287.117108924]]]]},"properties":{"pk":1362,"id_way":69950081,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223622.39335310194,6758493.693167156],[223615.1708518826,6758493.039575642],[223615.35042981955,6758490.795310922],[223610.78362489326,6758490.362932972],[223609.77377855495,6758501.348619351],[223621.56179897845,6758502.41334091],[223622.39335310194,6758493.693167156]]]]},"properties":{"pk":1363,"id_way":69950088,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223557.84794842175,6757557.168450057],[223557.66641816442,6757557.220324292],[223558.7471773316,6757563.550933988],[223561.5179855193,6757563.004466325],[223560.40857207213,6757556.672413412],[223557.84794842175,6757557.168450057]]]]},"properties":{"pk":1364,"id_way":69950104,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223631.991435084,6758349.1539150085],[223635.3444957044,6758339.869184885],[223622.79890758605,6758335.1022328],[223620.9805527141,6758344.972715099],[223631.991435084,6758349.1539150085]]]]},"properties":{"pk":1365,"id_way":69950126,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223561.17331858858,6757910.751669169],[223557.61159279343,6757904.753611818],[223551.8208159335,6757908.135666701],[223549.7794646009,6757905.908546559],[223548.7444907137,6757909.090899077],[223552.65440642595,6757915.656763242],[223561.17331858858,6757910.751669169]]]]},"properties":{"pk":1366,"id_way":69950129,"height":6.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223815.68848161024,6758552.042388012],[223813.88803043411,6758558.9981643],[223826.68945669298,6758562.367820929],[223828.48638250658,6758555.454781295],[223815.68848161024,6758552.042388012]]]]},"properties":{"pk":1367,"id_way":69950172,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223595.69551986453,6758402.65385737],[223617.56150515078,6758406.50210929],[223620.61146362094,6758395.666405745],[223598.03040202742,6758389.127426458],[223595.69551986453,6758402.65385737]]]]},"properties":{"pk":1368,"id_way":69950174,"height":10.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224008.17755953927,6757799.533808207],[224012.25656072047,6757788.605805587],[224002.30373715478,6757784.862137282],[223996.04360974164,6757795.706432537],[224004.55382591754,6757800.937650457],[224003.7239833311,6757802.398758977],[224007.78516823924,6757804.950503348],[224008.26206513567,6757804.148614541],[224009.39699375862,6757800.018746613],[224008.17755953927,6757799.533808207]]]]},"properties":{"pk":1369,"id_way":69950175,"height":16.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223499.02565383777,6757299.407518133],[223498.8687594701,6757305.486862743],[223500.9119340001,6757305.656142693],[223500.74505884564,6757313.814254926],[223506.08176137644,6757322.086936059],[223511.07200502665,6757319.042198738],[223506.9173098379,6757312.262412199],[223507.26691570488,6757299.927953327],[223499.02565383777,6757299.407518133]]]]},"properties":{"pk":1370,"id_way":69950190,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224049.7726346895,6758194.552217953],[224054.58578375785,6758175.917759835],[224029.95350908503,6758169.67732643],[224025.172056911,6758188.111249449],[224049.7726346895,6758194.552217953]]]]},"properties":{"pk":1371,"id_way":69950197,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223795.6915975599,6758131.263210278],[223796.82651964686,6758133.845957839],[223801.59390149263,6758131.732484294],[223800.48986038633,6758129.179620397],[223795.6915975599,6758131.263210278]]]]},"properties":{"pk":1372,"id_way":69950198,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224082.88039788234,6757278.333778964],[224082.75804168906,6757278.143832086],[224081.06724423778,6757279.373056645],[224079.95009549637,6757277.610156015],[224081.5423897458,6757276.536522222],[224066.4342308557,6757272.229807685],[224064.66088641327,6757273.447337437],[224066.22633057655,6757275.706082776],[224064.85964570273,6757276.652052759],[224071.5409428748,6757286.1726253545],[224082.88039788234,6757278.333778964]]]]},"properties":{"pk":1373,"id_way":69950202,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223752.31897956447,6757884.43096499],[223747.14529298167,6757876.686275107],[223740.99623698805,6757880.75323797],[223746.169929475,6757888.497922431],[223752.31897956447,6757884.43096499]]]]},"properties":{"pk":1374,"id_way":69950223,"height":7.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224020.51033096487,6757696.926086264],[224018.8622219036,6757693.855251127],[224012.84302387014,6757697.038410856],[224014.37566370965,6757700.095847207],[224020.51033096487,6757696.926086264]]]]},"properties":{"pk":1375,"id_way":69950246,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223569.57914646948,6757554.917151641],[223570.74634721217,6757561.243667279],[223573.65569149086,6757560.653750956],[223572.4040257576,6757554.365721456],[223569.57914646948,6757554.917151641]]]]},"properties":{"pk":1376,"id_way":69950248,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223834.4192533539,6757917.432697369],[223844.32053175787,6757911.726090272],[223843.51412661443,6757907.6649976075],[223841.68247677392,6757904.396324203],[223823.51205443434,6757914.6188969305],[223827.3384942405,6757921.516511505],[223834.4192533539,6757917.432697369]]]]},"properties":{"pk":1377,"id_way":69950270,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224037.85168377194,6757740.521729541],[224041.11280449876,6757732.377879368],[224029.61590183733,6757727.509045112],[224026.0490081917,6757729.215790822],[224028.81509819682,6757734.747106626],[224028.25030859237,6757735.204230691],[224028.24669873976,6757736.212712082],[224028.57049555003,6757736.645481739],[224037.85168377194,6757740.521729541]]]]},"properties":{"pk":1378,"id_way":69950272,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223800.52689832624,6758171.334262971],[223776.97407916185,6758181.830614584],[223782.84459727554,6758195.290083639],[223806.49220306426,6758184.8636375405],[223800.52689832624,6758171.334262971]]]]},"properties":{"pk":1379,"id_way":69950292,"height":12.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224017.56657385934,6758123.5975481905],[224014.86097430662,6758131.968545246],[224024.254925141,6758135.056484976],[224027.0262817266,6758126.680127308],[224017.56657385934,6758123.5975481905]]]]},"properties":{"pk":1380,"id_way":69950293,"height":9.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224215.203283849,6757639.197872829],[224212.38497006393,6757639.602217077],[224212.99550575897,6757644.659247485],[224215.76598188584,6757644.290075312],[224215.203283849,6757639.197872829]]]]},"properties":{"pk":1381,"id_way":69950297,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223983.34901836122,6758510.464300648],[223979.17607211747,6758518.540134375],[223986.3349968499,6758522.182163077],[223990.9055312398,6758513.3563976],[223983.72035264806,6758509.759643983],[223983.34901836122,6758510.464300648]]]]},"properties":{"pk":1382,"id_way":69950314,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224033.35329057722,6757884.393759251],[224024.99547482573,6757881.40550252],[224021.10435900613,6757891.948592926],[224029.46305709792,6757894.947681908],[224033.35329057722,6757884.393759251]]]]},"properties":{"pk":1383,"id_way":69950347,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223914.071407003,6758058.133517571],[223918.95888621762,6758066.741646867],[223927.38197267655,6758061.955100653],[223922.55393910763,6758053.353081173],[223914.071407003,6758058.133517571]]]]},"properties":{"pk":1384,"id_way":69950376,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223697.19568585147,6758426.170515315],[223705.28862012824,6758428.543985732],[223707.1992807381,6758421.9010936525],[223699.07345109244,6758419.573867418],[223697.19568585147,6758426.170515315]]]]},"properties":{"pk":1385,"id_way":69950377,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224115.85911383695,6757469.587294638],[224118.9013555822,6757474.0494267875],[224121.23339861396,6757472.392729939],[224118.15756720628,6757467.9653015],[224115.85911383695,6757469.587294638]]]]},"properties":{"pk":1386,"id_way":69950383,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223729.50505562781,6758340.856271624],[223721.29306325509,6758338.404304456],[223719.11400597548,6758346.104092242],[223727.35027638762,6758348.401615416],[223729.50505562781,6758340.856271624]]]]},"properties":{"pk":1387,"id_way":69950420,"height":10.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223730.5106304295,6757923.500916284],[223744.64414884622,6757914.401692394],[223749.226535022,6757922.240960238],[223753.38043160335,6757919.894333657],[223750.97895192687,6757915.11921218],[223744.36781935501,6757905.40121355],[223726.85807265577,6757916.988483968],[223730.5106304295,6757923.500916284]]]]},"properties":{"pk":1388,"id_way":69950426,"height":10.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223988.81707939957,6757933.364945365],[223974.95186802716,6757928.193123202],[223971.8074013714,6757936.614286589],[223985.66781627655,6757941.8194553945],[223988.81707939957,6757933.364945365]]]]},"properties":{"pk":1389,"id_way":69950489,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223888.10973516185,6757706.726961387],[223889.2260448572,6757705.6735491725],[223885.96254530488,6757699.766533908],[223876.53992042717,6757706.306154536],[223886.48943685504,6757720.387392365],[223893.76920527715,6757715.066103068],[223888.10973516185,6757706.726961387]]]]},"properties":{"pk":1390,"id_way":69950491,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223823.04310461614,6758172.404593255],[223823.61972050322,6758175.127518002],[223828.6214525045,6758172.508926854],[223828.04483896756,6758169.786001651],[223823.04310461614,6758172.404593255]]]]},"properties":{"pk":1391,"id_way":69950511,"height":3.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223990.8387067717,6758067.56588586],[223991.4328733371,6758065.587126202],[223984.16752358834,6758063.567875227],[223983.60077350223,6758065.543816458],[223990.8387067717,6758067.56588586]]]]},"properties":{"pk":1392,"id_way":69950512,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223517.22787498301,6757434.973232285],[223516.7037424203,6757432.382094933],[223518.09406971178,6757431.979561317],[223517.3123190332,6757427.658899371],[223515.89485385251,6757427.862506753],[223515.39674781452,6757425.411434511],[223505.4000691148,6757427.44342267],[223507.35244757385,6757436.929600328],[223517.22787498301,6757434.973232285]]]]},"properties":{"pk":1393,"id_way":69950514,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223894.7137639178,6757266.953446513],[223896.9372016919,6757270.277752288],[223899.32300309342,6757268.613630663],[223897.15869438028,6757265.221175978],[223894.7137639178,6757266.953446513]]]]},"properties":{"pk":1394,"id_way":69950516,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223971.5429584325,6758423.360501582],[223964.1210083842,6758425.256557963],[223965.988307799,6758432.688439546],[223976.12870854742,6758430.108923304],[223975.17842633484,6758426.313315847],[223974.1746672174,6758426.5504006045],[223973.28743646148,6758422.912183938],[223971.5429584325,6758423.360501582]]]]},"properties":{"pk":1395,"id_way":69950533,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224066.91235326225,6757840.861874914],[224073.08786287752,6757824.159462892],[224058.72541506155,6757818.801847554],[224056.88711648,6757819.631223151],[224055.00425536485,6757818.808026267],[224054.35708445346,6757817.4337010775],[224055.9969935041,6757812.667213104],[224054.72724949886,6757812.233814764],[224057.63966716282,6757804.617065821],[224050.90662025858,6757802.102838288],[224040.38039564647,6757831.049342902],[224066.91235326225,6757840.861874914]]]]},"properties":{"pk":1396,"id_way":69950536,"height":7.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223701.86085466374,6757780.65309015],[223696.24318813218,6757772.585471116],[223695.38924588793,6757773.178199505],[223693.0867929559,6757769.897255006],[223685.09783632122,6757775.413675177],[223693.04324711737,6757786.803978842],[223701.86085466374,6757780.65309015]]]]},"properties":{"pk":1397,"id_way":69950559,"height":10.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223595.72251755878,6758454.394695648],[223594.62400826716,6758465.64490265],[223617.86907472985,6758468.043979819],[223619.02825694467,6758456.789135217],[223595.72251755878,6758454.394695648]]]]},"properties":{"pk":1398,"id_way":69950569,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223880.67150944783,6758405.090157822],[223889.5342009954,6758408.356940967],[223892.53375786857,6758400.181862674],[223883.6665538856,6758396.874531006],[223880.67150944783,6758405.090157822]]]]},"properties":{"pk":1399,"id_way":69950580,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223785.46036732575,6757918.667201273],[223779.55414508964,6757922.035218543],[223781.31501434214,6757925.145265978],[223787.2492279996,6757921.850717333],[223785.46036732575,6757918.667201273]]]]},"properties":{"pk":1400,"id_way":69950582,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223716.3356094871,6758434.3477467215],[223713.77038657988,6758443.190415901],[223722.84353707495,6758445.79818811],[223725.25817036376,6758437.458453807],[223716.3356094871,6758434.3477467215]]]]},"properties":{"pk":1401,"id_way":69950583,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223896.41597687296,6757656.101708547],[223903.11983464466,6757665.709017774],[223911.25204483944,6757659.9849646315],[223904.46155025618,6757650.426464187],[223896.41597687296,6757656.101708547]]]]},"properties":{"pk":1402,"id_way":69950585,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223908.33326772365,6758150.05567953],[223893.45903668774,6758144.574678374],[223890.75624239014,6758151.955881375],[223905.6619675206,6758157.368252681],[223908.33326772365,6758150.05567953]]]]},"properties":{"pk":1403,"id_way":69950606,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224097.42425428095,6758522.417463801],[224081.24165064262,6758514.3729578415],[224078.6348340496,6758519.406677098],[224094.98806637945,6758527.4904103],[224097.42425428095,6758522.417463801]]]]},"properties":{"pk":1404,"id_way":69950607,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223851.5029330742,6757873.694504747],[223855.03544157598,6757871.5494687185],[223854.0744380658,6757869.86754441],[223850.53365499046,6757871.9289567415],[223851.5029330742,6757873.694504747]]]]},"properties":{"pk":1405,"id_way":69950609,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223995.26515298343,6757569.452062352],[224000.15620387983,6757578.015519409],[224006.50341063546,6757574.410682441],[224001.73496045795,6757565.815277809],[223995.26515298343,6757569.452062352]]]]},"properties":{"pk":1406,"id_way":69950611,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224078.58184426112,6758008.74226432],[224087.60123507804,6758012.0107378345],[224090.59817948076,6758003.79155886],[224085.0877222333,6758001.771640525],[224085.98076402265,6757999.514496584],[224082.44322676148,6757998.202581294],[224078.58184426112,6758008.74226432]]]]},"properties":{"pk":1407,"id_way":69950632,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223969.5337081315,6757755.470738118],[223973.43364598037,6757761.234639891],[223984.3691455038,6757753.7014855435],[223981.33327229283,6757747.325896493],[223969.5337081315,6757755.470738118]]]]},"properties":{"pk":1408,"id_way":69950655,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223712.71246829114,6758092.058321478],[223706.58227378005,6758096.815574959],[223711.54147905105,6758103.335873532],[223721.03378972277,6758096.05034522],[223719.69844187514,6758093.709344509],[223721.95261828438,6758092.289571066],[223712.6946700821,6758075.6921391785],[223705.69626083644,6758079.574073548],[223712.71246829114,6758092.058321478]]]]},"properties":{"pk":1409,"id_way":69950677,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223758.48894152942,6758060.659831669],[223772.8042061217,6758052.690097275],[223772.62435619926,6758052.414590668],[223783.89754957502,6758046.150878938],[223776.3511779827,6758032.564596903],[223750.7962647976,6758047.116309762],[223758.48894152942,6758060.659831669]]]]},"properties":{"pk":1410,"id_way":69950678,"height":13.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223533.0743620662,6757498.053528561],[223527.9271133598,6757489.609771824],[223523.35270539686,6757492.494959206],[223528.35347645046,6757500.940611201],[223533.0743620662,6757498.053528561]]]]},"properties":{"pk":1411,"id_way":69950680,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223972.1422462437,6757441.369736513],[223973.58451664748,6757440.36882525],[223972.19365291,6757437.275733821],[223969.60966758837,6757439.13897902],[223972.1422462437,6757441.369736513]]]]},"properties":{"pk":1412,"id_way":69950682,"height":6.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223601.96885642025,6757922.558978556],[223602.27402999921,6757922.64884926],[223607.82041592847,6757918.334885832],[223610.53255217525,6757921.0471324045],[223609.50846786785,6757921.810162886],[223610.01956487514,6757922.59015251],[223618.2438053368,6757917.228218469],[223614.01958871205,6757910.717619935],[223601.58021293723,6757919.883302091],[223601.96885642025,6757922.558978556]]]]},"properties":{"pk":1413,"id_way":69950705,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223801.63937783887,6758587.853316816],[223803.97386517946,6758588.684860705],[223805.626219069,6758584.0746153835],[223803.2383911238,6758583.151527822],[223801.63937783887,6758587.853316816]]]]},"properties":{"pk":1414,"id_way":69950749,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223794.72569528845,6757935.1975356545],[223788.91009991828,6757938.567719121],[223790.6456768637,6757941.636336367],[223796.51128307031,6757938.42412317],[223794.72569528845,6757935.1975356545]]]]},"properties":{"pk":1415,"id_way":69950751,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223806.3864023802,6757323.224390174],[223784.21035372443,6757291.736603985],[223777.60918008865,6757296.3919307105],[223799.87582527194,6757327.795046358],[223806.3864023802,6757323.224390174]]]]},"properties":{"pk":1416,"id_way":69950754,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223844.69797838278,6758074.051411708],[223836.0740981975,6758078.954467582],[223840.40009534443,6758086.648977785],[223849.02861400013,6758081.712794627],[223844.69797838278,6758074.051411708]]]]},"properties":{"pk":1417,"id_way":69950774,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223657.94989509307,6758157.355892207],[223660.7079143306,6758154.712525327],[223664.40283106652,6758158.582428054],[223670.00988107893,6758153.129693844],[223665.71808213022,6758148.604918721],[223657.29109616962,6758156.703007092],[223657.94989509307,6758157.355892207]]]]},"properties":{"pk":1418,"id_way":69950775,"height":3.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224130.92046436266,6757459.064509812],[224133.99520918916,6757463.413425713],[224136.26435249473,6757461.794699626],[224133.24736430024,6757457.450821177],[224130.92046436266,6757459.064509812]]]]},"properties":{"pk":1419,"id_way":69950779,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223889.91905972018,6758521.752764445],[223900.14597390525,6758525.798860999],[223904.7698122057,6758513.786040661],[223907.31244714424,6758514.867149153],[223908.15325711376,6758514.841636689],[223908.9855115175,6758514.424233569],[223909.53765849874,6758513.650538062],[223911.07429972762,6758509.625083992],[223932.2668321659,6758520.437517618],[223936.5437090832,6758511.9483713545],[223903.46102014507,6758495.108055649],[223902.0297246702,6758496.968527181],[223899.76873407158,6758496.048116489],[223889.91905972018,6758521.752764445]]]]},"properties":{"pk":1420,"id_way":69950796,"height":16.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224098.15047617978,6757871.742030818],[224097.195087665,6757872.623642056],[224093.42146308458,6757883.09568748],[224094.19178919293,6757883.4125682665],[224092.25869729157,6757888.693104098],[224100.30268476618,6757891.682602116],[224101.78860628992,6757887.739636722],[224140.48957271694,6757901.994635356],[224143.51071823022,6757894.006499596],[224101.79612903058,6757878.402826363],[224102.77352114342,6757875.059316538],[224102.64232327807,6757873.847890563],[224101.9207166475,6757872.712090251],[224102.92644789856,6757871.948198565],[224102.04706043395,6757871.444058205],[224100.60741617667,6757871.1362687135],[224099.49980344024,6757871.214705857],[224098.15047617978,6757871.742030818]]]]},"properties":{"pk":1421,"id_way":69950799,"height":7.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223642.01791462532,6758550.8308001105],[223655.31706848994,6758553.073677581],[223656.7516609424,6758544.54661806],[223645.85299760202,6758542.661362489],[223645.886534289,6758542.503501151],[223643.48126459296,6758542.101081467],[223642.01791462532,6758550.8308001105]]]]},"properties":{"pk":1422,"id_way":69950821,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223852.23154269427,6757798.764305382],[223857.64865983732,6757797.628791816],[223865.6745503644,6757793.942316239],[223859.76835069776,6757780.763530346],[223851.71148483045,6757784.411524867],[223851.80282943117,6757784.614554172],[223846.79010528186,6757786.9700986],[223849.36437685706,6757792.761034963],[223854.4560690176,6757790.477866515],[223855.84132653612,6757793.462689133],[223850.68453034823,6757795.830703952],[223851.96608761817,6757798.822006292],[223852.23154269427,6757798.764305382]]]]},"properties":{"pk":1423,"id_way":69950822,"height":13.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223568.22861909572,6758530.220919453],[223566.88967374244,6758538.318048831],[223590.90851224278,6758542.325907872],[223592.4002836031,6758533.598044213],[223580.5737781163,6758532.133192762],[223568.22861909572,6758530.220919453]]]]},"properties":{"pk":1424,"id_way":69950869,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223574.64029577022,6757916.9560210835],[223565.2958533779,6757922.36276112],[223570.0863192664,6757930.797833427],[223575.1612693996,6757930.161131934],[223575.034895894,6757929.0988453],[223574.10378460705,6757927.486011514],[223579.11515884352,6757924.573501157],[223574.64029577022,6757916.9560210835]]]]},"properties":{"pk":1425,"id_way":69950872,"height":9.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224001.29359669206,6758559.183942042],[224006.01279987668,6758547.210064438],[224002.15589337586,6758545.268913711],[223997.0779231513,6758555.250493037],[223997.4987878898,6758557.416360789],[224001.29359669206,6758559.183942042]]]]},"properties":{"pk":1426,"id_way":69950892,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223755.59523719273,6758372.692323763],[223758.30982212262,6758373.694806265],[223759.75207078992,6758369.181593594],[223759.0285090432,6758368.022504633],[223756.97827454755,6758367.435154188],[223755.59523719273,6758372.692323763]]]]},"properties":{"pk":1427,"id_way":69950915,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223735.14020772718,6757783.908459664],[223730.37277451018,6757775.463620103],[223715.9273390328,6757785.541309981],[223720.98068996903,6757792.695426061],[223727.19195109242,6757788.260156141],[223729.65742579877,6757787.279615141],[223735.14020772718,6757783.908459664]]]]},"properties":{"pk":1428,"id_way":69950918,"height":9.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223803.0892825127,6757573.51651777],[223809.81526420108,6757580.086158719],[223831.03637268074,6757559.110405011],[223832.3769099078,6757560.979306319],[223842.59180235487,6757553.7689549355],[223840.12166424055,6757550.25977765],[223845.1092428454,6757545.175507629],[223829.58161491243,6757523.1225075675],[223823.1550585325,6757526.305174967],[223817.81810624915,6757518.768472145],[223807.68670646517,6757526.092602444],[223811.77693647117,6757531.9324894305],[223785.19926023137,6757544.564175093],[223788.43564395807,6757552.176346072],[223793.65014038514,6757561.499834431],[223797.6897143096,6757567.462023105],[223803.0892825127,6757573.51651777]]]]},"properties":{"pk":1429,"id_way":69950920,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223741.40137294392,6758221.430401687],[223719.59829302522,6758213.309815066],[223716.43044763664,6758221.499715088],[223738.45963372235,6758229.6890320815],[223741.40137294392,6758221.430401687]]]]},"properties":{"pk":1430,"id_way":69950942,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223884.53735018757,6758046.743079284],[223881.74406072273,6758041.744895155],[223879.43111178087,6758043.061693268],[223882.22440295538,6758048.05987625],[223884.53735018757,6758046.743079284]]]]},"properties":{"pk":1431,"id_way":69950943,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223524.71129981815,6757312.88374321],[223539.1998077926,6757313.770457175],[223541.05887078293,6757302.000556637],[223525.63963856676,6757301.03546366],[223524.71129981815,6757312.88374321]]]]},"properties":{"pk":1432,"id_way":69950945,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224153.2923565244,6757472.654392255],[224146.16374783742,6757477.664154834],[224151.77311473584,6757485.644131752],[224158.8759081552,6757480.68010114],[224153.2923565244,6757472.654392255]]]]},"properties":{"pk":1433,"id_way":69950947,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224148.318723093,6757756.411081504],[224153.6119650299,6757741.999708006],[224145.75551316031,6757739.171864873],[224140.49266422313,6757753.504599436],[224148.318723093,6757756.411081504]]]]},"properties":{"pk":1434,"id_way":69950967,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223882.23745981543,6757798.494531363],[223893.94654462326,6757790.655457684],[223889.21949391853,6757783.432908309],[223886.53769977958,6757785.230689042],[223878.1113291362,6757789.322426429],[223882.23745981543,6757798.494531363]]]]},"properties":{"pk":1435,"id_way":69950990,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223645.6599110002,6757310.777691409],[223636.7706748978,6757298.125926186],[223620.5658174104,6757309.830783997],[223629.51242144982,6757322.367571044],[223645.6599110002,6757310.777691409]]]]},"properties":{"pk":1436,"id_way":69950992,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223681.38923315832,6757995.377146258],[223700.87585412912,6757983.349432208],[223694.74933695575,6757972.994196392],[223675.17617951208,6757985.101282487],[223681.38923315832,6757995.377146258]]]]},"properties":{"pk":1437,"id_way":69951048,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223838.19188981428,6758174.673422583],[223843.7747090934,6758173.457850493],[223841.32380842709,6758161.961179439],[223835.5958548886,6758163.210358539],[223838.19188981428,6758174.673422583]]]]},"properties":{"pk":1438,"id_way":69951081,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224023.65717891543,6758463.041667788],[224013.4699965091,6758466.704130716],[224013.18547047436,6758477.207820151],[224022.69804647422,6758477.805180614],[224023.65717891543,6758463.041667788]]]]},"properties":{"pk":1439,"id_way":69951082,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224089.679417018,6757495.364575336],[224064.39942618873,6757513.008595123],[224067.82811961538,6757517.831401529],[224092.98664230361,6757500.063746888],[224089.679417018,6757495.364575336]]]]},"properties":{"pk":1440,"id_way":69951086,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224061.4260379938,6757936.284848432],[224068.79903416664,6757915.863710206],[224059.84309095907,6757912.480573576],[224052.19853955,6757932.8568023145],[224061.4260379938,6757936.284848432]]]]},"properties":{"pk":1441,"id_way":69951106,"height":9.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223786.92398101615,6757849.364754382],[223791.89622085445,6757858.283662454],[223805.03479335227,6757849.62073779],[223799.8556787746,6757841.7513518585],[223798.30324907278,6757842.759408167],[223799.72545327325,6757847.342840432],[223796.4984454058,6757849.494261851],[223793.75179352582,6757845.373951283],[223786.92398101615,6757849.364754382]]]]},"properties":{"pk":1442,"id_way":69951137,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223999.82931120115,6758104.622903932],[224007.64926989,6758083.193700898],[223995.1818739258,6758079.941790344],[223987.94915136744,6758100.292994909],[223999.82931120115,6758104.622903932]]]]},"properties":{"pk":1443,"id_way":69951159,"height":12.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223954.97600330558,6758023.755572763],[223949.7771965868,6758021.91578211],[223948.86547371172,6758024.250492005],[223954.08791946896,6758026.130776457],[223954.97600330558,6758023.755572763]]]]},"properties":{"pk":1444,"id_way":69951160,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223966.43065356778,6758623.282916226],[223982.3960377509,6758627.489728681],[223986.12762365062,6758613.202186724],[223986.45103587367,6758613.276948822],[223988.30226757197,6758606.682887899],[223989.27589129168,6758606.927424774],[223991.54963043996,6758598.593613097],[223974.13879905763,6758593.980065013],[223966.43065356778,6758623.282916226]]]]},"properties":{"pk":1445,"id_way":69951196,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223696.2471327607,6757894.994385536],[223692.02172032805,6757889.064508086],[223683.97207399024,6757894.773145087],[223686.3049145818,6757898.062165488],[223678.1485711095,6757903.895760917],[223679.93055942972,6757906.727929543],[223696.2471327607,6757894.994385536]]]]},"properties":{"pk":1446,"id_way":69951201,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223609.08502503074,6757508.570599439],[223601.63158713764,6757513.8409785],[223607.1837539493,6757521.747799114],[223614.66814137239,6757516.583832208],[223609.08502503074,6757508.570599439]]]]},"properties":{"pk":1447,"id_way":69951232,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223524.6403383125,6757288.259581639],[223524.91123022165,6757282.150397777],[223512.6089713874,6757281.407149314],[223512.43642133224,6757279.642654671],[223509.75833085272,6757279.632773489],[223512.08497533452,6757287.459391551],[223524.6403383125,6757288.259581639]]]]},"properties":{"pk":1448,"id_way":69951244,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223842.59843710266,6758471.958401616],[223838.8591341398,6758481.831349492],[223844.44444434877,6758483.82786033],[223848.09146295663,6758473.994272752],[223842.59843710266,6758471.958401616]]]]},"properties":{"pk":1449,"id_way":69951250,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223895.1510780391,6757246.650725693],[223888.68426050097,6757237.9464077875],[223883.89724416702,6757241.340575241],[223888.7137224319,6757248.107548715],[223879.31144066865,6757254.840392062],[223880.6978782925,6757256.732244873],[223895.1510780391,6757246.650725693]]]]},"properties":{"pk":1450,"id_way":69951255,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223938.4234957223,6758216.316158216],[223927.52332888913,6758221.736223001],[223932.32418249338,6758231.395873444],[223943.20862490742,6758226.01978785],[223938.4234957223,6758216.316158216]]]]},"properties":{"pk":1451,"id_way":69951290,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223581.4029259099,6758123.549221984],[223578.87992467542,6758124.941003159],[223582.05562034246,6758130.587305933],[223584.52039996287,6758129.19054964],[223581.4029259099,6758123.549221984]]]]},"properties":{"pk":1452,"id_way":69951292,"height":3.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224037.88353719347,6757546.54960202],[224033.62161954056,6757548.945452981],[224038.0107825769,6757556.602385293],[224048.0332303652,6757550.950955634],[224043.64405996999,6757543.29398446],[224037.88353719347,6757546.54960202]]]]},"properties":{"pk":1453,"id_way":69951300,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224020.6400469322,6758486.564216386],[224021.2937588967,6758477.916357639],[224013.1750376784,6758477.407558695],[224012.5190147341,6758485.935930069],[224020.6400469322,6758486.564216386]]]]},"properties":{"pk":1454,"id_way":69951335,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224036.10370325606,6757950.547127806],[224039.25202985705,6757942.11317941],[224024.41114367574,6757936.585255241],[224021.11470557796,6757945.406061572],[224021.34854279223,6757945.519866421],[224017.1847227983,6757957.039799527],[224031.61848141748,6757962.532898605],[224036.10370325606,6757950.547127806]]]]},"properties":{"pk":1455,"id_way":69951341,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223830.37473546926,6757832.88726531],[223839.6658700098,6757826.77185564],[223830.59248860844,6757813.099891264],[223821.32739872133,6757819.16928329],[223830.37473546926,6757832.88726531]]]]},"properties":{"pk":1456,"id_way":69951388,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223669.93433662818,6757275.475887675],[223673.68394651084,6757272.8336067125],[223669.43374231257,6757266.795267701],[223665.6212440714,6757269.475317249],[223669.93433662818,6757275.475887675]]]]},"properties":{"pk":1457,"id_way":69951392,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223542.32157427026,6757950.828657653],[223542.05849468094,6757950.827648511],[223541.3316573499,6757953.218976139],[223546.13897980153,6757954.598085995],[223547.12424718175,6757951.082593181],[223542.61993808535,6757949.8500897465],[223542.32157427026,6757950.828657653]]]]},"properties":{"pk":1458,"id_way":69951419,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223637.97196729254,6758386.986127034],[223636.31465585832,6758394.096532242],[223640.30736438168,6758395.0446136305],[223639.83440479072,6758397.10077941],[223646.38727511585,6758398.682663036],[223648.55108298513,6758389.5690928865],[223637.97196729254,6758386.986127034]]]]},"properties":{"pk":1459,"id_way":69951420,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223551.4057869704,6757558.392518689],[223548.664868934,6757558.946843476],[223549.77357985693,6757565.269021977],[223552.53940253492,6757564.754230661],[223551.4057869704,6757558.392518689]]]]},"properties":{"pk":1460,"id_way":69951422,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223649.59204729594,6758307.046369975],[223651.01826833715,6758307.224648436],[223651.09224115795,6758306.441888337],[223649.7430701439,6758305.50400789],[223649.59204729594,6758307.046369975]]]]},"properties":{"pk":1461,"id_way":69951444,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223713.34702891594,6757809.975421236],[223711.2473792058,6757806.940456294],[223707.234053194,6757809.544720837],[223709.27699924368,6757812.669333024],[223713.34702891594,6757809.975421236]]]]},"properties":{"pk":1462,"id_way":69951447,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223990.74396403384,6757614.179206348],[223984.60131130385,6757601.999861102],[223973.57284294275,6757608.245690281],[223976.4631016971,6757614.216589087],[223976.2882243377,6757614.298742527],[223978.7028419262,6757619.469770138],[223977.72418235373,6757620.0171278035],[223978.25989831527,6757621.178504716],[223990.74396403384,6757614.179206348]]]]},"properties":{"pk":1463,"id_way":69951449,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224109.54855528465,6757987.837695943],[224107.30816156216,6757986.989568168],[224105.38128367573,6757992.244743857],[224107.65447495686,6757993.059709407],[224109.54855528465,6757987.837695943]]]]},"properties":{"pk":1464,"id_way":69951470,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223896.77155871864,6758545.824969176],[223903.9634565021,6758527.521624358],[223889.84740239542,6758521.93949819],[223882.7139865801,6758540.502391391],[223896.77155871864,6758545.824969176]]]]},"properties":{"pk":1465,"id_way":69951490,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223592.78964752937,6758419.590738793],[223591.08731976108,6758429.614535076],[223600.7923047433,6758430.54609992],[223599.64095437626,6758442.354968352],[223607.08545094135,6758443.132684458],[223609.08607257187,6758423.100476965],[223601.5632159869,6758421.052330679],[223592.78964752937,6758419.590738793]]]]},"properties":{"pk":1466,"id_way":69951492,"height":9.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223990.48277162263,6757805.214796424],[224003.3522752993,6757812.567665461],[224007.6836957874,6757805.1229483215],[224003.45556048185,6757802.466286874],[224004.2845175671,6757801.006878059],[223995.94250596545,6757795.879048274],[223990.48277162263,6757805.214796424]]]]},"properties":{"pk":1467,"id_way":69951493,"height":15.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224049.72366721692,6758194.746138648],[224025.11860458288,6758188.303995911],[224024.45891348115,6758190.755365498],[224023.0367472447,6758190.357619142],[224022.3115801643,6758193.124889527],[224023.7339541144,6758193.522626239],[224022.87043249875,6758196.87858947],[224047.56923151098,6758203.202177343],[224049.72366721692,6758194.746138648]]]]},"properties":{"pk":1468,"id_way":69951515,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223798.06967586375,6758110.4588150345],[223793.48099897566,6758112.45887899],[223794.58473830682,6758115.011031815],[223799.20044012595,6758112.998366407],[223798.06967586375,6758110.4588150345]]]]},"properties":{"pk":1469,"id_way":69951516,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223535.08035167638,6757533.483495277],[223528.90282800831,6757534.771244501],[223531.06900184517,6757546.034692623],[223537.27120104266,6757544.788228337],[223535.08035167638,6757533.483495277]]]]},"properties":{"pk":1470,"id_way":69951518,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224052.538161965,6757485.923366122],[224048.2841601439,6757489.003427686],[224052.8328253615,6757495.243948642],[224057.02387839375,6757492.287333764],[224052.538161965,6757485.923366122]]]]},"properties":{"pk":1471,"id_way":69951520,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223798.51289232337,6757869.64754206],[223802.37648370664,6757876.594038268],[223814.11179249917,6757869.970052723],[223809.41111912482,6757862.430638512],[223798.51289232337,6757869.64754206]]]]},"properties":{"pk":1472,"id_way":69951541,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223988.15352804746,6757708.209221727],[223992.10774403176,6757716.453598279],[224008.08179521988,6757708.981140471],[224004.09551865526,6757700.618192252],[223988.15352804746,6757708.209221727]]]]},"properties":{"pk":1473,"id_way":69951564,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223581.53010491046,6757552.614668841],[223578.75811497448,6757553.161358962],[223579.80771251646,6757559.475976623],[223582.63116999625,6757558.935343125],[223581.53010491046,6757552.614668841]]]]},"properties":{"pk":1474,"id_way":69951566,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223783.5443785109,6758611.485637907],[223773.99565227603,6758607.982689135],[223767.78582426993,6758625.478632403],[223777.20821233408,6758628.980272691],[223783.5443785109,6758611.485637907]]]]},"properties":{"pk":1475,"id_way":69951585,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223743.0692823425,6757972.775078735],[223729.19199728614,6757980.753800345],[223736.59271024494,6757993.585618146],[223750.32376613232,6757985.8167837085],[223743.0692823425,6757972.775078735]]]]},"properties":{"pk":1476,"id_way":69951588,"height":13.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224104.99302602248,6757724.0718374355],[224108.30936246313,6757715.269119111],[224099.0778966123,6757711.983117412],[224095.75338438226,6757720.775581649],[224104.99302602248,6757724.0718374355]]]]},"properties":{"pk":1477,"id_way":69951590,"height":10.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224035.60810706706,6758100.156511687],[224036.97038485407,6758096.128560004],[224030.8420024389,6758094.2596171545],[224031.4107495713,6758092.641687372],[224027.03198032657,6758091.289735381],[224027.84244681295,6758088.968678018],[224032.04509973753,6758090.200681118],[224032.72955997716,6758088.148893884],[224038.88011134692,6758090.048404006],[224039.71140019782,6758087.402741907],[224020.96439313245,6758081.532041829],[224016.29681811665,6758094.376226312],[224035.60810706706,6758100.156511687]]]]},"properties":{"pk":1478,"id_way":69951611,"height":12.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224203.4950917778,6757640.766095281],[224204.11269874408,6757645.821523162],[224206.78568739598,6757645.46058298],[224206.19682519865,6757640.402786521],[224203.4950917778,6757640.766095281]]]]},"properties":{"pk":1479,"id_way":69951615,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223960.93097056012,6758534.547688264],[223969.6269788746,6758538.969090653],[223973.8201144605,6758530.864349995],[223965.03202845517,6758526.395835039],[223960.93097056012,6758534.547688264]]]]},"properties":{"pk":1480,"id_way":69951632,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224026.507184658,6757831.861721309],[224032.57149789436,6757815.545957111],[224023.61484265956,6757812.120610869],[224023.23102272672,6757813.233201856],[224018.28581764587,6757811.323820468],[224014.5456060395,6757821.396561724],[224019.45839389696,6757823.218020097],[224017.4942821433,6757828.592560776],[224026.507184658,6757831.861721309]]]]},"properties":{"pk":1481,"id_way":69951676,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223701.14408951276,6758442.786657941],[223695.56819234107,6758441.059971431],[223694.75098533763,6758443.87473311],[223694.06678934445,6758444.310088168],[223689.42571862426,6758443.750629273],[223688.56995010414,6758451.769541016],[223697.1126714601,6758452.682290472],[223698.50083679866,6758451.887836282],[223701.14408951276,6758442.786657941]]]]},"properties":{"pk":1482,"id_way":69951714,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223901.07095517888,6758014.618496201],[223908.23411339583,6758027.379413144],[223914.9008060483,6758023.642284559],[223915.95868552124,6758025.493796938],[223916.82049163408,6758024.977712994],[223918.74139112368,6758028.458794837],[223921.55711664283,6758026.867259275],[223911.3286881913,6758008.814087929],[223901.07095517888,6758014.618496201]]]]},"properties":{"pk":1483,"id_way":69951715,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223763.49780098393,6758331.9022095855],[223760.6623811034,6758340.906643614],[223765.10317728776,6758342.533119043],[223764.80502194434,6758343.4049710315],[223767.16773800907,6758344.2882367475],[223767.46606879277,6758343.416577802],[223775.4963814076,6758346.467147145],[223774.4492988195,6758349.225747941],[223775.22214036793,6758349.508051336],[223771.86340059282,6758358.870641941],[223778.43831755142,6758359.496330407],[223785.5543839811,6758340.088661549],[223763.49780098393,6758331.9022095855]]]]},"properties":{"pk":1484,"id_way":69951739,"height":15.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223936.45536479692,6757825.342856671],[223922.71326971904,6757830.697199014],[223925.4418046691,6757837.898448985],[223939.2385878408,6757832.671611843],[223936.45536479692,6757825.342856671]]]]},"properties":{"pk":1485,"id_way":69951742,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223775.49265148852,6757828.827670455],[223783.14253158687,6757824.526294542],[223779.6697376267,6757818.28971907],[223771.99534798478,6757822.560369112],[223775.49265148852,6757828.827670455]]]]},"properties":{"pk":1486,"id_way":69951788,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223878.72832976296,6757623.673809122],[223875.85846335712,6757619.640255069],[223872.79082510725,6757621.771131079],[223875.6924749881,6757625.844419215],[223878.72832976296,6757623.673809122]]]]},"properties":{"pk":1487,"id_way":69951790,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223972.20025817893,6758016.473622775],[223968.87683974855,6758025.55028268],[223983.71337993463,6758030.106769086],[223985.3535931865,6758024.994442177],[223979.10889039675,6758022.732716934],[223980.29953225818,6758019.415123158],[223972.20025817893,6758016.473622775]]]]},"properties":{"pk":1488,"id_way":69951810,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223806.63395219424,6758155.894796772],[223807.75819454307,6758158.444383309],[223812.67478024962,6758156.242179693],[223811.55131255835,6758153.778115978],[223806.63395219424,6758155.894796772]]]]},"properties":{"pk":1489,"id_way":69951811,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223624.52443604576,6757306.7550147865],[223621.122898787,6757301.851054977],[223616.90743148967,6757304.732937175],[223620.44942176348,6757309.668143091],[223624.52443604576,6757306.7550147865]]]]},"properties":{"pk":1490,"id_way":69951813,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224481.34810175275,6757497.817760618],[224493.73915357137,6757502.165532836],[224503.23161774618,6757474.876351803],[224490.9905477958,6757470.538911591],[224481.34810175275,6757497.817760618]]]]},"properties":{"pk":1491,"id_way":69951815,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223953.37136155242,6758382.139928403],[223955.63901798945,6758391.26660652],[223963.296233279,6758389.322368084],[223962.65368223868,6758386.863469739],[223966.44309482785,6758386.011110295],[223964.81938502405,6758379.286796358],[223953.37136155242,6758382.139928403]]]]},"properties":{"pk":1492,"id_way":69951844,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224144.5620107001,6757790.796965474],[224179.28504110282,6757803.870653297],[224181.57938428933,6757797.16238188],[224156.33613834035,6757788.60410003],[224146.78696796956,6757784.8701517405],[224144.5620107001,6757790.796965474]]]]},"properties":{"pk":1493,"id_way":69951850,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223709.32450480637,6757763.370317141],[223702.9372133894,6757767.863412879],[223708.6328669037,6757775.892111428],[223714.93752960282,6757771.471189649],[223709.32450480637,6757763.370317141]]]]},"properties":{"pk":1494,"id_way":69951875,"height":12.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223805.2640647046,6757934.047572482],[223797.02439630302,6757938.89321412],[223798.48548587158,6757941.525924661],[223817.58421839421,6757930.805036789],[223810.18196376233,6757917.685734973],[223791.2423919659,6757928.538381308],[223792.7647145898,6757931.28674452],[223801.06127793703,6757926.604360688],[223805.2640647046,6757934.047572482]]]]},"properties":{"pk":1495,"id_way":69951898,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223914.69401677587,6757665.18260735],[223906.8075990619,6757670.82208869],[223910.05507874678,6757675.282128374],[223919.16050378932,6757668.767088596],[223916.68398785897,6757663.515664466],[223924.1427850201,6757658.263349124],[223935.73296178895,6757652.479532213],[223928.31937714314,6757636.99397459],[223927.95354173405,6757636.497567869],[223927.0032130608,6757635.772275652],[223926.27123025537,6757635.576514301],[223925.42762667467,6757635.655198381],[223904.62501620923,6757650.31122786],[223911.54382430235,6757660.0503416555],[223911.33271687967,6757660.169042663],[223914.69401677587,6757665.18260735]]]]},"properties":{"pk":1496,"id_way":69951900,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223905.5931775912,6758157.5560511425],[223890.68724136014,6758152.143603185],[223888.0178525424,6758159.378090533],[223902.91978835926,6758164.83482207],[223905.5931775912,6758157.5560511425]]]]},"properties":{"pk":1497,"id_way":69951931,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224059.7721052477,6758519.551686155],[224057.38853367817,6758524.420335399],[224110.6657947291,6758551.293808761],[224113.0421360498,6758546.425875047],[224059.7721052477,6758519.551686155]]]]},"properties":{"pk":1498,"id_way":69951933,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223944.3452625057,6757858.471649463],[223947.1808593789,6757853.583086494],[223944.61057195,6757846.84245928],[223934.7504989905,6757850.473143174],[223935.79537844713,6757853.422272601],[223944.3452625057,6757858.471649463]]]]},"properties":{"pk":1499,"id_way":69951938,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224067.21430867777,6757972.411310556],[224064.78455688944,6757979.091146442],[224067.26021011462,6757980.000979595],[224067.17245758968,6757980.395022336],[224067.3492261148,6757980.452874026],[224069.89933390502,6757973.3822762035],[224067.21430867777,6757972.411310556]]]]},"properties":{"pk":1500,"id_way":69951960,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223976.8769987798,6757801.973927398],[223982.74955460732,6757791.8061591005],[223979.29635282265,6757789.467643969],[223975.43563214818,6757783.943145559],[223973.54882733108,6757778.281855159],[223971.3359390989,6757774.065309951],[223967.26092080184,6757781.118708744],[223971.48692353393,6757783.65306655],[223968.9195403312,6757788.1731029805],[223964.63564088248,6757785.586877344],[223960.66104368726,6757792.485045094],[223976.8769987798,6757801.973927398]]]]},"properties":{"pk":1501,"id_way":69951983,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223915.3814697713,6758130.838876237],[223900.47922345708,6758125.470226745],[223896.44299785633,6758136.448764956],[223911.34867848438,6758141.861123172],[223915.3814697713,6758130.838876237]]]]},"properties":{"pk":1502,"id_way":69952005,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223727.2942296438,6758013.768695937],[223734.6592156284,6758026.880586955],[223743.46945629595,6758021.861814768],[223740.900377808,6758017.231499802],[223746.00230866074,6758014.322965961],[223741.23177556845,6758005.872359416],[223727.2942296438,6758013.768695937]]]]},"properties":{"pk":1503,"id_way":69952006,"height":12.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223555.36651577379,6757484.393485753],[223549.8679907966,6757475.664448151],[223540.9908414809,6757481.303554085],[223541.77003722358,6757482.524001001],[223542.9520166416,6757481.773680147],[223544.25599865182,6757483.555794889],[223546.8692391651,6757482.06052156],[223547.94810795062,6757483.731879739],[223541.10156133477,6757487.785794965],[223543.50160605932,6757491.648398501],[223555.36651577379,6757484.393485753]]]]},"properties":{"pk":1504,"id_way":69952008,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223556.2468434117,6757329.2933032205],[223558.5221485697,6757332.416192736],[223567.16220583124,6757326.269378897],[223564.91969588283,6757323.111792918],[223556.2468434117,6757329.2933032205]]]]},"properties":{"pk":1505,"id_way":69952064,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223815.48019654115,6758572.533471689],[223813.0069645588,6758571.864744423],[223811.43174736953,6758576.847262908],[223813.8759675482,6758577.590631829],[223815.48019654115,6758572.533471689]]]]},"properties":{"pk":1506,"id_way":69952082,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223886.3106640507,6757272.698336436],[223876.97792059902,6757259.568128546],[223870.47227612045,6757264.105437825],[223879.74866312984,6757277.273230425],[223886.3106640507,6757272.698336436]]]]},"properties":{"pk":1507,"id_way":69952087,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223642.30684611903,6758142.306037432],[223636.90297851554,6758145.366472724],[223638.10179135072,6758147.483585801],[223643.47463782888,6758144.393005413],[223642.30684611903,6758142.306037432]]]]},"properties":{"pk":1508,"id_way":69952107,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223824.32651414702,6758058.033376029],[223831.544283854,6758070.911071759],[223840.11930974378,6758065.968956409],[223837.60820758404,6758061.590286321],[223839.56338534507,6758060.466055936],[223840.1244150202,6758061.447754529],[223848.69273133017,6758056.7031000685],[223843.36276861347,6758047.273089723],[223824.32651414702,6758058.033376029]]]]},"properties":{"pk":1509,"id_way":69952108,"height":13.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224138.50416940683,6757494.975583705],[224132.83219486594,6757486.956175844],[224126.44316801568,6757491.449599732],[224132.08591050835,6757499.471425428],[224138.50416940683,6757494.975583705]]]]},"properties":{"pk":1510,"id_way":69952112,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224045.5256507392,6757980.528436045],[224049.0604157528,6757970.772430285],[224040.78417559553,6757967.778065264],[224037.19082644943,6757977.538731008],[224045.5256507392,6757980.528436045]]]]},"properties":{"pk":1511,"id_way":69952132,"height":10.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223940.6292784161,6757807.834993754],[223950.72631768326,6757803.890590798],[223945.90103002766,6757791.116753552],[223935.77651876016,6757794.899914764],[223940.6292784161,6757807.834993754]]]]},"properties":{"pk":1512,"id_way":69952155,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223636.34482941436,6758358.254495269],[223629.60738623058,6758356.273705466],[223627.91865241807,6758360.9405583115],[223634.68301617418,6758362.800030687],[223636.34482941436,6758358.254495269]]]]},"properties":{"pk":1513,"id_way":69952202,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223564.39720711825,6757858.129162049],[223563.1663534791,6757857.754536663],[223562.4755402368,6757860.128850742],[223563.8172765257,6757860.506505915],[223564.39720711825,6757858.129162049]]]]},"properties":{"pk":1514,"id_way":69952205,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223739.91734761625,6758462.9163335925],[223751.88263270163,6758463.05721467],[223751.99652327358,6758449.237385995],[223740.17218708285,6758449.095346569],[223739.91734761625,6758462.9163335925]]]]},"properties":{"pk":1515,"id_way":69952249,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223682.11243095316,6757847.213595505],[223700.45055295035,6757835.237178785],[223695.54566679976,6757827.850008998],[223690.94905718236,6757830.838858526],[223689.8597209274,6757829.335790086],[223676.1786484505,6757838.944494203],[223682.11243095316,6757847.213595505]]]]},"properties":{"pk":1516,"id_way":69952254,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223708.75518177493,6758167.408788117],[223704.82456420324,6758158.507422447],[223698.63236611945,6758161.216244767],[223702.53711369867,6758170.163126206],[223708.75518177493,6758167.408788117]]]]},"properties":{"pk":1517,"id_way":69952278,"height":9.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223876.2767405064,6758079.587879404],[223881.13449310558,6758088.109511361],[223887.01416660636,6758084.787461072],[223882.18564473407,6758076.263365341],[223876.2767405064,6758079.587879404]]]]},"properties":{"pk":1518,"id_way":69952279,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224147.25327778555,6757457.21864413],[224146.4069607583,6757452.113007507],[224143.6730772893,6757452.551856769],[224144.54337835533,6757457.686687662],[224147.25327778555,6757457.21864413]]]]},"properties":{"pk":1519,"id_way":69952283,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224063.46904603136,6757888.725601059],[224064.47409001182,6757886.149541004],[224059.215664358,6757884.196293428],[224058.26951460334,6757886.809634261],[224063.46904603136,6757888.725601059]]]]},"properties":{"pk":1520,"id_way":69952303,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224030.4292323702,6757713.553593745],[224027.40177483205,6757715.146938278],[224030.0277118566,6757720.233745656],[224033.19357660043,6757718.554072172],[224030.4292323702,6757713.553593745]]]]},"properties":{"pk":1521,"id_way":69952326,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223587.75898735327,6757620.261077131],[223578.84220162965,6757607.722062907],[223567.15165931475,6757616.009822286],[223576.07970167455,6757628.503915886],[223587.75898735327,6757620.261077131]]]]},"properties":{"pk":1522,"id_way":69952328,"height":9.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223921.29708462514,6757919.251903051],[223908.17315271095,6757926.588473698],[223911.5244872447,6757932.545166746],[223924.04555766928,6757925.439526351],[223921.29708462514,6757919.251903051]]]]},"properties":{"pk":1523,"id_way":69952354,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224036.60911958388,6757608.819313579],[224042.04148765747,6757610.772375047],[224042.9236453008,6757608.155274745],[224037.49415696762,6757606.244821144],[224036.60911958388,6757608.819313579]]]]},"properties":{"pk":1524,"id_way":69952356,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223825.5356236185,6758184.098412368],[223826.11193377088,6758186.898024841],[223831.08559637767,6758184.314758613],[223830.5095461996,6758181.60086588],[223825.5356236185,6758184.098412368]]]]},"properties":{"pk":1525,"id_way":69952376,"height":3.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224004.89983072213,6758030.353615976],[224003.14197938956,6758036.047117588],[224008.54674694818,6758037.699543303],[224010.27342467057,6758032.15929456],[224004.89983072213,6758030.353615976]]]]},"properties":{"pk":1526,"id_way":69952377,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224224.03540500093,6757638.0279403115],[224221.44434455372,6757638.392366877],[224222.06560254906,6757643.492292649],[224224.73572529064,6757643.121331391],[224224.03540500093,6757638.0279403115]]]]},"properties":{"pk":1527,"id_way":69952381,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224010.6964421668,6758512.077012602],[224020.1781414039,6758512.797318537],[224020.7391677272,6758504.467235079],[224011.23083645198,6758503.78269123],[224010.6964421668,6758512.077012602]]]]},"properties":{"pk":1528,"id_way":69952398,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223726.47794297748,6758513.0429125],[223727.39784414234,6758503.369539074],[223723.7504062957,6758503.030096636],[223723.35243790984,6758507.687450347],[223717.52864031185,6758507.18822215],[223717.95313217133,6758502.481828448],[223714.18871228935,6758502.097808593],[223713.353565564,6758511.820209251],[223726.47794297748,6758513.0429125]]]]},"properties":{"pk":1529,"id_way":69952447,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223943.19781221278,6758028.119024734],[223946.68135077276,6758029.436450015],[223949.52520679176,6758022.0112501085],[223944.34685107213,6758024.884586763],[223943.19781221278,6758028.119024734]]]]},"properties":{"pk":1530,"id_way":69952448,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223748.47891951687,6758358.275148187],[223739.17328682865,6758355.6632713],[223736.4232643722,6758365.657912403],[223745.4382850184,6758368.969748096],[223746.52312649728,6758365.029318289],[223747.12133362296,6758364.775407149],[223747.549421939,6758364.087938645],[223747.58336492412,6758363.372475556],[223747.177951373,6758362.86105148],[223748.47891951687,6758358.275148187]]]]},"properties":{"pk":1531,"id_way":69952472,"height":10.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223953.03225948452,6758630.405250276],[223963.61352511353,6758633.097724909],[223973.94538578522,6758593.929160135],[223963.36504894914,6758591.159956603],[223953.03225948452,6758630.405250276]]]]},"properties":{"pk":1532,"id_way":69952473,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223571.1296269025,6757509.312413812],[223560.81541013237,6757492.982930118],[223553.9041699448,6757497.371372357],[223556.2943882981,6757501.170364578],[223553.98266403048,6757502.581953514],[223558.49673461873,6757509.325237647],[223561.13635266796,6757508.852596481],[223562.3359502194,6757514.493369241],[223569.44876593194,6757513.001457952],[223571.1296269025,6757509.312413812]]]]},"properties":{"pk":1533,"id_way":69952501,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224000.29295015865,6757984.739678875],[223994.63825740074,6757982.676740537],[223996.4356769036,6757977.903275416],[224002.11694584126,6757979.930361244],[224003.23990394242,6757976.922915925],[223988.63263018514,6757971.7524077585],[223984.59594500583,6757982.731293544],[223999.08390568377,6757987.988309523],[224000.29295015865,6757984.739678875]]]]},"properties":{"pk":1534,"id_way":69952522,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223595.09809055348,6758115.849343232],[223598.32879846537,6758121.448954153],[223600.97426738546,6758119.980599558],[223597.73566083805,6758114.371196851],[223595.09809055348,6758115.849343232]]]]},"properties":{"pk":1535,"id_way":69952544,"height":3.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223911.96795797918,6758178.466866902],[223931.48403941153,6758185.579641785],[223936.21049722313,6758172.629484988],[223916.689816707,6758165.5496195415],[223911.96795797918,6758178.466866902]]]]},"properties":{"pk":1536,"id_way":69952545,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224103.27399458239,6757507.866646739],[224095.13473146287,6757513.582394399],[224100.7490447893,6757521.451242295],[224108.88449405675,6757515.779508569],[224103.27399458239,6757507.866646739]]]]},"properties":{"pk":1537,"id_way":69952549,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223914.01795455033,6758457.945195533],[223910.0714636195,6758468.391851961],[223920.14705359784,6758472.163801645],[223924.5686571719,6758460.562567459],[223914.01795455033,6758457.945195533]]]]},"properties":{"pk":1538,"id_way":69952566,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224011.82261523016,6757938.952845103],[224013.57925625384,6757939.56375781],[224013.9534948129,6757939.261472166],[224014.03147436434,6757938.912555827],[224022.2358132524,6757941.856715706],[224024.2237387444,6757936.515402528],[224004.29011449698,6757929.080270618],[224000.52221467125,6757939.351217223],[224010.4528843253,6757942.367262662],[224011.82261523016,6757938.952845103]]]]},"properties":{"pk":1539,"id_way":69952569,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223820.75383382806,6757760.84151306],[223812.38671378128,6757746.193912136],[223806.56990681725,6757749.553400097],[223815.02786182493,6757764.127856659],[223820.75383382806,6757760.84151306]]]]},"properties":{"pk":1540,"id_way":69952592,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223625.90258107753,6758445.0153119285],[223635.13089680026,6758445.963470935],[223637.1443325045,6758437.51026361],[223626.728035698,6758436.407412479],[223625.90258107753,6758445.0153119285]]]]},"properties":{"pk":1541,"id_way":69952615,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224041.0847401571,6757613.536941558],[224041.97681800788,6757610.961657811],[224036.54342052134,6757609.008226246],[224035.62551001398,6757611.618114547],[224041.0847401571,6757613.536941558]]]]},"properties":{"pk":1542,"id_way":69952618,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223630.50113836507,6758304.997539903],[223632.73547908003,6758308.75972963],[223640.86557543045,6758306.123599662],[223642.00555217362,6758304.456357642],[223642.71210654304,6758304.455185947],[223644.49547581997,6758301.854993612],[223635.8496794357,6758295.83570353],[223630.30575741886,6758303.745706175],[223630.19771434832,6758304.477297597],[223630.50113836507,6758304.997539903]]]]},"properties":{"pk":1543,"id_way":69952640,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224287.9560961118,6758560.531271644],[224285.8209214092,6758555.620984887],[224236.27574228667,6758578.463503271],[224238.60850825685,6758583.304716533],[224287.9560961118,6758560.531271644]]]]},"properties":{"pk":1544,"id_way":69952641,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223654.11039540416,6757785.613776673],[223652.5974636625,6757786.537268004],[223660.24803664326,6757797.44952832],[223661.7957422192,6757796.491227729],[223654.11039540416,6757785.613776673]]]]},"properties":{"pk":1545,"id_way":69952643,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224007.32012402866,6757617.8255908415],[224014.45774579907,6757612.188172022],[224011.40487257522,6757607.863763561],[224010.2391731309,6757605.8546037525],[224005.34094318305,6757596.299036748],[224001.1403197457,6757598.505653453],[223997.87219080108,6757593.786286342],[223994.7110576318,6757595.418149626],[224001.38579825504,6757608.182041167],[224005.75342826496,6757615.670202659],[224007.32012402866,6757617.8255908415]]]]},"properties":{"pk":1546,"id_way":69952645,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224091.6278335801,6757981.309606716],[224089.7304779851,6757986.5736687975],[224092.11895248003,6757987.414250218],[224094.04179977937,6757982.190090533],[224091.6278335801,6757981.309606716]]]]},"properties":{"pk":1547,"id_way":69952666,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223836.69826129026,6758531.7761403965],[223839.4173560554,6758521.775843968],[223832.41548860475,6758519.604103444],[223828.79169380554,6758529.718913328],[223836.69826129026,6758531.7761403965]]]]},"properties":{"pk":1548,"id_way":69952687,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223573.38810986365,6758439.81877548],[223579.10844067467,6758440.477119131],[223582.61307386594,6758419.783916076],[223576.77373893443,6758418.778676726],[223573.38810986365,6758439.81877548]]]]},"properties":{"pk":1549,"id_way":69952689,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223980.6361259988,6757895.59903007],[223982.59459408242,6757890.26159898],[223979.9996635756,6757889.296324871],[223978.04119741474,6757894.633756857],[223980.6361259988,6757895.59903007]]]]},"properties":{"pk":1550,"id_way":69952691,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223554.30535669485,6758136.512947926],[223552.41974632238,6758133.077401825],[223559.38583423442,6758129.059708002],[223559.11442065204,6758128.580135718],[223561.7227854902,6758127.067578112],[223567.9779026737,6758138.412841311],[223579.06915110172,6758132.261036048],[223564.50111652075,6758106.289286332],[223534.26489555,6758123.472381757],[223544.63775587446,6758141.892942976],[223554.30535669485,6758136.512947926]]]]},"properties":{"pk":1551,"id_way":69952717,"height":12.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223780.89377989146,6758126.583099108],[223775.418751351,6758129.05321338],[223779.25866740185,6758137.761467614],[223784.73699412952,6758135.334295583],[223780.89377989146,6758126.583099108]]]]},"properties":{"pk":1552,"id_way":69952718,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223507.95557931278,6757525.964496704],[223512.1758619782,6757525.101502838],[223511.94239355833,6757523.606651232],[223507.72473563452,6757524.575792886],[223507.95557931278,6757525.964496704]]]]},"properties":{"pk":1553,"id_way":69952720,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223816.90274695723,6757857.480635159],[223822.1261124832,6757865.378903813],[223828.2482036008,6757871.77088602],[223834.50170730587,6757869.446865475],[223823.0548740921,6757853.411768046],[223816.90274695723,6757857.480635159]]]]},"properties":{"pk":1554,"id_way":69952743,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223984.6180054875,6757700.794091967],[223991.434330781,6757697.496526026],[223989.34046555535,6757693.233857171],[223992.5694665835,6757691.458843301],[223987.94237271397,6757682.865568535],[223978.47717511372,6757688.195218085],[223984.6180054875,6757700.794091967]]]]},"properties":{"pk":1555,"id_way":69952766,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223956.70324260197,6758589.3686406575],[223954.19325609095,6758598.891033485],[223957.25686213752,6758599.74602372],[223957.7664209307,6758598.056539284],[223961.10381900918,6758598.934109064],[223963.1717622668,6758591.1085723005],[223956.70324260197,6758589.3686406575]]]]},"properties":{"pk":1556,"id_way":69952788,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223758.4315327437,6757973.266102703],[223761.75698952092,6757979.18006113],[223777.4685724217,6757970.260310502],[223768.36453430945,6757954.143327868],[223765.83839196636,6757955.504247769],[223771.56435813755,6757965.8187914025],[223758.4315327437,6757973.266102703]]]]},"properties":{"pk":1557,"id_way":69952791,"height":13.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224139.9924622965,6757659.346851071],[224138.1985884754,6757666.312917624],[224138.5880728192,6757666.383900491],[224137.18148585077,6757670.5698838895],[224136.7726997651,6757670.457838574],[224136.68361858866,6757670.712000489],[224146.8826514354,6757674.375191682],[224149.8826741994,6757664.3718777895],[224151.18486613483,6757657.570716155],[224140.66388586548,6757655.837836197],[224139.9924622965,6757659.346851071]]]]},"properties":{"pk":1558,"id_way":69952793,"height":16.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223651.51748377245,6758171.141647683],[223653.99419667275,6758168.736677096],[223649.52019793337,6758164.168030153],[223648.25820062315,6758165.352403776],[223651.51748377245,6758171.141647683]]]]},"properties":{"pk":1559,"id_way":69952814,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224074.5801070534,6758081.312886158],[224077.9348920241,6758072.0288919555],[224070.55361899585,6758069.396482466],[224067.2281036359,6758078.678176499],[224074.5801070534,6758081.312886158]]]]},"properties":{"pk":1560,"id_way":69952815,"height":7.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223596.80894368334,6757345.841894579],[223629.35002554112,6757322.484310268],[223620.4034910806,6757309.9476207215],[223604.2527485808,6757321.6510357205],[223604.42509311248,6757321.92638387],[223602.3076585904,6757323.483102386],[223588.1876790617,6757333.624567089],[223596.80894368334,6757345.841894579]]]]},"properties":{"pk":1561,"id_way":69952817,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224188.27120708424,6757682.733785038],[224193.95040000416,6757684.717228855],[224193.26444485618,6757686.65719486],[224199.46963799174,6757688.892721534],[224200.0913032006,6757686.990595735],[224202.91656482648,6757688.064432568],[224202.47197504636,6757689.360907292],[224203.90952003168,6757689.926287826],[224207.38602349706,6757680.162172723],[224191.47583883908,6757673.34731854],[224188.27120708424,6757682.733785038]]]]},"properties":{"pk":1562,"id_way":69952819,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223954.358849987,6758521.003843651],[223950.1339116168,6758529.388682274],[223960.63590486362,6758534.689596107],[223964.8536317134,6758526.305419566],[223954.358849987,6758521.003843651]]]]},"properties":{"pk":1563,"id_way":69952836,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223594.43650368677,6758672.968720877],[223579.21702820386,6758670.652864995],[223578.55293361298,6758674.668808417],[223593.60837529466,6758676.8404214475],[223610.5893326603,6758678.914866148],[223611.23818563533,6758673.604289362],[223659.75919095156,6758633.834539217],[223655.05206794862,6758632.061990366],[223614.6715539292,6758664.916093936],[223613.25104233404,6758661.692647428],[223600.53237449107,6758659.766848532],[223594.099177058,6758658.36969592],[223587.5837705858,6758657.490063365],[223586.796866923,6758661.284035076],[223604.92129277476,6758663.686711629],[223603.36737834453,6758673.39635488],[223594.43650368677,6758672.968720877]]]]},"properties":{"pk":1564,"id_way":69952863,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224017.56931822456,6757855.927443059],[224003.6427495026,6757850.82640204],[224000.73819384465,6757858.693401948],[224014.60737224127,6757863.909109384],[224017.56931822456,6757855.927443059]]]]},"properties":{"pk":1565,"id_way":69952864,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223662.04471456126,6757944.177251271],[223655.03448283547,6757933.548556113],[223646.81697019655,6757938.712948994],[223653.55864360175,6757949.692229363],[223662.04471456126,6757944.177251271]]]]},"properties":{"pk":1566,"id_way":69952886,"height":13.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223709.61045380187,6758312.085966266],[223705.3050222706,6758323.621664729],[223707.19248360666,6758324.328528006],[223709.92331628583,6758323.784632845],[223711.77566663278,6758324.517529801],[223713.75119667826,6758326.841915978],[223716.03114798007,6758327.643229402],[223720.22198489791,6758316.05976202],[223709.61045380187,6758312.085966266]]]]},"properties":{"pk":1567,"id_way":69952911,"height":18.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223590.84792450746,6757935.7395536965],[223588.19173350107,6757945.173911289],[223593.1445319408,6757946.554985818],[223595.8036138781,6757937.152928246],[223590.84792450746,6757935.7395536965]]]]},"properties":{"pk":1568,"id_way":69952914,"height":9.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223776.47801670412,6757812.160070622],[223783.98158453446,6757807.817619242],[223779.40972737514,6757799.607663576],[223764.11308501379,6757808.370576551],[223768.53374029996,6757816.291956088],[223776.32850074154,6757811.883122212],[223776.47801670412,6757812.160070622]]]]},"properties":{"pk":1569,"id_way":69952960,"height":12.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223857.22372969732,6757687.82501475],[223837.10676451985,6757702.198587044],[223845.2854966782,6757713.70573934],[223865.51515816813,6757699.3453328675],[223857.22372969732,6757687.82501475]]]]},"properties":{"pk":1570,"id_way":69952962,"height":10.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223804.06726090383,6758137.418604148],[223802.84869895334,6758134.641459153],[223798.1115228884,6758136.763020561],[223799.30196410295,6758139.542198864],[223804.06726090383,6758137.418604148]]]]},"properties":{"pk":1571,"id_way":69952982,"height":3.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223962.17619811188,6758004.533648238],[223959.2861515133,6758003.374763926],[223957.4537003735,6758008.398116122],[223960.3145127458,6758009.475393638],[223962.17619811188,6758004.533648238]]]]},"properties":{"pk":1572,"id_way":69952983,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223572.29836080817,6757295.593936138],[223577.2287095261,6757292.36248847],[223579.02629250416,6757294.891465549],[223583.18914906535,6757292.089542124],[223578.549261472,6757285.494378946],[223569.46590073165,6757291.952560007],[223572.29836080817,6757295.593936138]]]]},"properties":{"pk":1573,"id_way":69952985,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223860.4548135885,6758372.5444689635],[223879.03108914685,6758379.449459147],[223878.14354065803,6758381.861429564],[223896.7687778589,6758388.656389848],[223900.89867117433,6758377.44751414],[223894.015032584,6758374.936671209],[223893.83930038998,6758375.437506722],[223875.9239227811,6758368.862217944],[223876.81397537945,6758366.57203336],[223864.31254889868,6758361.959517054],[223860.4548135885,6758372.5444689635]]]]},"properties":{"pk":1574,"id_way":69953004,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224063.09283015187,6757778.047463373],[224068.18136317303,6757779.8753621755],[224068.3890388982,6757779.236078143],[224068.90127703588,6757779.475828271],[224071.0285593075,6757773.750301094],[224070.43463625046,6757773.506935286],[224070.64011018246,6757773.00421829],[224065.49448344635,6757771.170731765],[224065.40485396018,6757771.696829643],[224065.0842547064,6757771.531033769],[224062.86183182153,6757777.306154893],[224063.34548828212,6757777.586032002],[224063.09283015187,6757778.047463373]]]]},"properties":{"pk":1575,"id_way":69953007,"height":6.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223712.62616822607,6757743.453880032],[223707.14999175924,6757733.624660484],[223700.49933922247,6757737.464064297],[223705.92160191524,6757747.1674358295],[223712.62616822607,6757743.453880032]]]]},"properties":{"pk":1576,"id_way":69953030,"height":7.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223681.85047898145,6757312.284307489],[223686.51985463058,6757319.112218464],[223693.94478739926,6757313.878393342],[223689.1322516272,6757307.158672037],[223681.85047898145,6757312.284307489]]]]},"properties":{"pk":1577,"id_way":69953032,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223703.1409031625,6757976.535466683],[223705.8361964188,6757975.0628209375],[223704.34467323602,6757972.46783464],[223701.7272225322,6757973.9446901865],[223703.1409031625,6757976.535466683]]]]},"properties":{"pk":1578,"id_way":69953052,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223889.3292982726,6757644.830286676],[223902.9549517313,6757635.17164529],[223897.93453511776,6757628.058470389],[223884.2823685611,6757637.752073717],[223889.3292982726,6757644.830286676]]]]},"properties":{"pk":1579,"id_way":69953055,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224864.20084007067,6758381.836180178],[224866.43291951815,6758368.731825569],[224858.73774050229,6758367.460811906],[224856.5167962973,6758380.520811043],[224864.20084007067,6758381.836180178]]]]},"properties":{"pk":1580,"id_way":71057605,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225020.29609108533,6758357.37814447],[225031.05676034978,6758295.143417663],[225019.31954770247,6758292.967468956],[225022.84937718068,6758273.612443225],[224934.4564914962,6758258.210980631],[224906.70743519004,6758419.205107619],[224905.58538686915,6758419.036996472],[224898.72230549357,6758423.911251754],[224899.27081809222,6758424.737787417],[224897.34089196223,6758426.062343292],[224896.77178289075,6758425.2399803605],[224878.13254167544,6758438.420905886],[224888.54842557167,6758453.2252065595],[224887.32608294833,6758460.685591868],[224885.58668098223,6758460.368714502],[224885.24628121077,6758462.439086613],[224887.01201632532,6758462.709203893],[224885.65584046178,6758470.9298311975],[224873.72630913148,6758468.79192331],[224865.0581185538,6758518.033374795],[224860.3086334986,6758517.201202502],[224856.92827470272,6758536.913626696],[224847.93699824341,6758535.301706196],[224848.4600723259,6758532.372959353],[224841.20766319823,6758531.101560799],[224840.68075969347,6758533.987194644],[224834.05883165318,6758532.77088231],[224820.10656260035,6758611.692947234],[224931.9977603995,6758631.174017646],[224934.35400664265,6758617.597641752],[224941.83589851204,6758618.86092056],[224940.32298597624,6758627.699737522],[224963.7698425155,6758631.735624566],[224999.78669881297,6758418.336086258],[224985.5688987804,6758415.880657669],[224996.95980229788,6758353.027029006],[225020.29609108533,6758357.37814447]]]]},"properties":{"pk":1581,"id_way":71057982,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224826.24778615026,6758176.11830263],[224829.14728128634,6758159.298599145],[224830.25269956328,6758159.4883558005],[224831.06127301828,6758154.847054982],[224829.94099342765,6758154.658833696],[224830.36260953953,6758152.238958288],[224812.19678270226,6758149.115521033],[224808.125391167,6758172.9803357385],[224826.24778615026,6758176.11830263]]]]},"properties":{"pk":1582,"id_way":71058074,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224916.36379198023,6758110.3351983875],[224918.79017618828,6758111.593524787],[224921.43312780577,6758105.180875878],[224918.90562685241,6758104.148623207],[224916.36379198023,6758110.3351983875]]]]},"properties":{"pk":1583,"id_way":71058087,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225074.83697295602,6758544.922820181],[225083.2580015255,6758545.43178095],[225083.83640535516,6758536.834057571],[225075.2191791233,6758536.351782573],[225074.83697295602,6758544.922820181]]]]},"properties":{"pk":1584,"id_way":71058366,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224729.75351240535,6758514.563846525],[224753.72523639904,6758518.756810247],[224757.48609357196,6758497.213158089],[224733.50953625437,6758493.05372951],[224729.75351240535,6758514.563846525]]]]},"properties":{"pk":1585,"id_way":71058835,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224799.27795058629,6758326.11159179],[224801.57321996638,6758312.657967658],[224804.9629269619,6758313.209708849],[224819.3739107461,6758229.778182075],[224805.76336667733,6758227.249169562],[224805.87498694545,6758226.862116271],[224780.8188615627,6758222.318270984],[224781.98289088678,6758215.621912999],[224803.08833877483,6758219.227052846],[224804.643078142,6758210.3531756075],[224806.9109374154,6758210.705302743],[224807.27965490145,6758208.516946402],[224796.678808373,6758206.729268743],[224806.0822655817,6758152.612186576],[224786.7848463367,6758149.226521059],[224786.27282308828,6758156.218128565],[224783.1303008648,6758164.0778308045],[224774.41892270205,6758214.308293853],[224775.82114674023,6758214.551820346],[224774.7069697416,6758221.200195776],[224773.30450289577,6758220.967515333],[224749.60191309405,6758357.411684268],[224751.10295097745,6758357.4885401055],[224761.14996364363,6758359.064293446],[224761.29146070953,6758358.203974496],[224770.96091620947,6758359.899646523],[224771.1057404391,6758359.0853953585],[224781.24575988433,6758360.865195897],[224781.40310016496,6758359.927962443],[224793.14262735232,6758361.8584284205],[224793.98948480948,6758356.9745115405],[224798.92696114938,6758357.802683499],[224804.20903602804,6758326.951508248],[224799.27795058629,6758326.11159179]]]]},"properties":{"pk":1586,"id_way":71058848,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224798.0692561624,6758362.730878733],[224798.89293202444,6758357.999769608],[224794.15254202698,6758357.204623118],[224793.33978207738,6758361.892048711],[224798.0692561624,6758362.730878733]]]]},"properties":{"pk":1587,"id_way":71059238,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224809.8183784951,6758147.529288631],[224813.83381512217,6758148.193724833],[224814.1857012198,6758146.075183045],[224810.17785331953,6758145.420666153],[224809.8183784951,6758147.529288631]]]]},"properties":{"pk":1588,"id_way":71059757,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224922.88880224415,6758077.1720834365],[224803.84992080968,6758030.5357146915],[224803.53516815644,6758034.423413209],[224893.92737131033,6758070.757944874],[224893.1822035266,6758072.6126393275],[224901.66785213925,6758076.03073991],[224902.42130851728,6758074.186721897],[224920.64572676524,6758081.494831071],[224922.88880224415,6758077.1720834365]]]]},"properties":{"pk":1589,"id_way":71059781,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224716.7472670494,6758588.210460245],[224740.8086566726,6758592.495753512],[224744.5772411221,6758570.862308634],[224720.5867933497,6758566.626538049],[224716.7472670494,6758588.210460245]]]]},"properties":{"pk":1590,"id_way":71060166,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224814.74312257368,6758222.7362312265],[224816.59571904695,6758211.433900043],[224815.34512580524,6758211.226516823],[224813.45600161838,6758222.530766414],[224814.74312257368,6758222.7362312265]]]]},"properties":{"pk":1591,"id_way":71060179,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224804.26356696044,6758422.451892613],[224810.09065018815,6758423.481071386],[224810.4839803115,6758421.247032939],[224804.6568949987,6758420.217853776],[224804.26356696044,6758422.451892613]]]]},"properties":{"pk":1592,"id_way":71060534,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224878.04026441753,6758346.0240218425],[224880.63386133523,6758330.973327205],[224874.92371886162,6758330.162183892],[224872.34211205132,6758345.179626893],[224878.04026441753,6758346.0240218425]]]]},"properties":{"pk":1593,"id_way":71060920,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224870.52609860752,6758258.600970162],[224871.0689949879,6758255.743254564],[224868.96480040113,6758255.382942712],[224868.4463080807,6758258.198033511],[224870.52609860752,6758258.600970162]]]]},"properties":{"pk":1594,"id_way":71061404,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225074.76912843276,6758506.279091556],[225075.90268090655,6758497.837366051],[225073.8418946889,6758497.545587204],[225072.66518482467,6758505.918731685],[225074.76912843276,6758506.279091556]]]]},"properties":{"pk":1595,"id_way":71061696,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224720.8845604235,6758565.215580181],[224744.86444024296,6758569.418905521],[224748.62783221222,6758547.908310011],[224724.65527247213,6758543.704371591],[224720.8845604235,6758565.215580181]]]]},"properties":{"pk":1596,"id_way":71061814,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224986.71935509107,6758212.042953713],[224993.97930968972,6758207.08754199],[224992.4376895957,6758204.822300101],[224985.1565611713,6758209.7789766295],[224986.71935509107,6758212.042953713]]]]},"properties":{"pk":1597,"id_way":71061827,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225041.83027659764,6758548.659130195],[225059.49013309486,6758550.94062559],[225065.21546498316,6758505.8781157],[225053.43090904228,6758504.393637331],[225050.8471912159,6758524.575480646],[225046.04501801947,6758524.015014836],[225044.83562333047,6758534.306814073],[225043.56154832654,6758534.075057819],[225041.83027659764,6758548.659130195]]]]},"properties":{"pk":1598,"id_way":71062128,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224807.71459662757,6758617.033136001],[224846.85287460923,6758394.1283979295],[224822.20544935158,6758389.855407468],[224815.90837165312,6758425.79848767],[224801.9548379019,6758423.344796664],[224795.49056284633,6758460.221266708],[224809.41412406063,6758462.6773490915],[224798.94357243978,6758522.446778477],[224784.79189670816,6758519.953444643],[224778.38319475032,6758557.148125671],[224792.47658284844,6758559.568194089],[224783.28129080404,6758612.798781276],[224807.71459662757,6758617.033136001]]]]},"properties":{"pk":1599,"id_way":71062221,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224804.24275843028,6758326.754371697],[224806.52016436335,6758313.429241797],[224805.03704758454,6758313.424405871],[224801.73698505567,6758312.887240083],[224799.50873651335,6758325.9480244145],[224804.24275843028,6758326.754371697]]]]},"properties":{"pk":1600,"id_way":71062634,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225084.45589428535,6758508.050223432],[225083.33421990715,6758514.472824845],[225082.18607948467,6758514.276122976],[225081.54569163735,6758518.646421582],[225082.73573909551,6758518.849753825],[225082.68860001932,6758519.477526152],[225089.8436850273,6758520.671276746],[225091.64698127523,6758509.20728073],[225084.45589428535,6758508.050223432]]]]},"properties":{"pk":1601,"id_way":71063013,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224801.4571641691,6758225.862923785],[224805.2729285981,6758226.551899502],[224805.59080567514,6758224.792176322],[224801.76901151682,6758224.11434473],[224801.4571641691,6758225.862923785]]]]},"properties":{"pk":1602,"id_way":71063122,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224865.4117706875,6758514.871926988],[224866.3818275127,6758509.348620847],[224864.87770640917,6758509.075575734],[224863.92100554876,6758514.588204054],[224865.4117706875,6758514.871926988]]]]},"properties":{"pk":1603,"id_way":71063495,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224800.3175521302,6758194.205262242],[224809.92389303708,6758195.604521534],[224810.6737690556,6758190.444685411],[224801.0937114079,6758189.010460998],[224800.3175521302,6758194.205262242]]]]},"properties":{"pk":1604,"id_way":71063508,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225002.22402981934,6758510.672401827],[225000.72261430792,6758519.316921753],[225003.11147136654,6758519.752576478],[225004.5725825381,6758511.069489953],[225002.22402981934,6758510.672401827]]]]},"properties":{"pk":1605,"id_way":71063777,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224859.02070300712,6758365.973227074],[224866.77934470368,6758367.283030489],[224867.77456068076,6758361.500668866],[224860.015911829,6758360.190864151],[224859.02070300712,6758365.973227074]]]]},"properties":{"pk":1606,"id_way":71063884,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224783.29603136817,6758163.124608247],[224786.07562100442,6758156.172630045],[224786.5868789281,6758149.191452636],[224785.74480356253,6758149.040531636],[224783.29603136817,6758163.124608247]]]]},"properties":{"pk":1607,"id_way":71064396,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224827.0299986584,6758119.736592661],[224808.8636871079,6758116.613099859],[224807.40948658233,6758125.095961205],[224811.60029662497,6758125.794925745],[224810.07261947085,6758134.695763825],[224805.87997521777,6758133.974653246],[224804.42323123195,6758142.424698908],[224822.58755518115,6758145.526241306],[224824.03793335825,6758137.0873979265],[224822.11653731903,6758136.751735493],[224823.6508009664,6758127.839865973],[224825.58699093005,6758128.174353877],[224827.0299986584,6758119.736592661]]]]},"properties":{"pk":1608,"id_way":71064408,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224803.8770696674,6758218.209311677],[224806.48335939794,6758218.641716547],[224806.86787692312,6758216.374833425],[224804.26765735762,6758215.931567178],[224803.8770696674,6758218.209311677]]]]},"properties":{"pk":1609,"id_way":71064818,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225069.31003730933,6758544.549851464],[225070.03612123747,6758539.139780204],[225068.0213173607,6758538.855418265],[225067.25270403753,6758544.431170407],[225069.31003730933,6758544.549851464]]]]},"properties":{"pk":1610,"id_way":71065090,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224811.83609298422,6758423.9920713],[224815.56465500084,6758424.623503818],[224815.93780154508,6758422.5135433115],[224812.1879588112,6758421.873450215],[224811.83609298422,6758423.9920713]]]]},"properties":{"pk":1611,"id_way":71065178,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224858.89397289138,6758274.075069492],[224860.63274947222,6758264.024795919],[224869.20738488372,6758265.563680821],[224870.48882629524,6758258.797467966],[224868.21374082402,6758258.356693761],[224868.76788406272,6758255.34793564],[224862.329060259,6758254.161591289],[224875.8889394126,6758175.31144153],[224846.16021499014,6758170.121441903],[224829.1000960123,6758269.001101305],[224858.89397289138,6758274.075069492]]]]},"properties":{"pk":1612,"id_way":71065190,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224713.103462839,6758355.558948569],[224718.88749848545,6758356.44006185],[224719.27529389254,6758353.895469202],[224713.4912558529,6758353.014355541],[224713.103462839,6758355.558948569]]]]},"properties":{"pk":1613,"id_way":71065561,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225093.0881769791,6758499.823464337],[225094.58823177713,6758490.458012281],[225093.97428283616,6758490.4961755015],[225094.5596407705,6758486.959408441],[225087.94110882052,6758485.987825149],[225087.32250851198,6758489.519205147],[225086.6675215207,6758489.394373291],[225085.20414591578,6758498.6181459315],[225093.0881769791,6758499.823464337]]]]},"properties":{"pk":1614,"id_way":71065654,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225091.67768845422,6758509.009649174],[225093.05719291614,6758500.021050036],[225085.82618391127,6758498.900019007],[225084.48788212062,6758507.852797936],[225091.67768845422,6758509.009649174]]]]},"properties":{"pk":1615,"id_way":71065935,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224873.82091475592,6758146.786067982],[224875.73695181013,6758145.3245462505],[224868.9086165175,6758135.713849177],[224866.9709644545,6758137.177737699],[224873.82091475592,6758146.786067982]]]]},"properties":{"pk":1616,"id_way":71066024,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224790.25487745908,6758079.794743346],[224790.26023185256,6758077.173734256],[224788.17484772467,6758077.168883438],[224788.17726381132,6758079.799447323],[224790.25487745908,6758079.794743346]]]]},"properties":{"pk":1617,"id_way":71066037,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224779.9135156459,6758558.289613408],[224779.52229420558,6758560.556392146],[224790.58368897162,6758562.457741761],[224790.97772779295,6758560.234366712],[224779.9135156459,6758558.289613408]]]]},"properties":{"pk":1618,"id_way":71066402,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224817.28022103195,6758208.563025168],[224814.84794891765,6758223.279772705],[224819.7624061262,6758224.190912892],[224822.2354188919,6758209.407304182],[224817.28022103195,6758208.563025168]]]]},"properties":{"pk":1619,"id_way":71066414,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225046.56522228,6758521.780422773],[225048.86930881115,6758522.036087561],[225049.81056492266,6758513.474137087],[225047.50647494575,6758513.218471915],[225046.56522228,6758521.780422773]]]]},"properties":{"pk":1620,"id_way":71066684,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224847.78753549836,6758403.629605749],[224850.03890306782,6758404.0324804075],[224852.1550328857,6758391.828962136],[224849.8973282059,6758391.436774734],[224847.78753549836,6758403.629605749]]]]},"properties":{"pk":1621,"id_way":71066774,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224872.14436046837,6758345.149482085],[224875.03555439063,6758328.37787159],[224870.7337616252,6758327.616069551],[224867.83499474148,6758344.473523241],[224872.14436046837,6758345.149482085]]]]},"properties":{"pk":1622,"id_way":71067148,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224865.6661770487,6758247.117424514],[224867.9473403245,6758247.518491025],[224869.2103761094,6758240.2097352855],[224866.9292100238,6758239.80866826],[224865.6661770487,6758247.117424514]]]]},"properties":{"pk":1623,"id_way":71067746,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224723.8442800292,6758542.249148418],[224748.8398601946,6758546.649162428],[224753.48842807254,6758520.173841149],[224728.50015746526,6758515.773211288],[224723.8442800292,6758542.249148418]]]]},"properties":{"pk":1624,"id_way":71068176,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224980.11403313215,6758202.338593312],[224985.04365565136,6758209.613893223],[224992.32506142976,6758204.657027883],[224987.38345775884,6758197.415382929],[224980.11403313215,6758202.338593312]]]]},"properties":{"pk":1625,"id_way":71068189,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225038.83642957907,6758548.340744886],[225041.26810077266,6758548.598236508],[225042.7810880453,6758536.158327893],[225040.35611592713,6758535.972564961],[225038.83642957907,6758548.340744886]]]]},"properties":{"pk":1626,"id_way":71068473,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223910.01568022952,6757765.766162991],[223903.4370008298,6757768.874809789],[223910.09634099348,6757776.501450395],[223915.75493392118,6757773.176694894],[223910.01568022952,6757765.766162991]]]]},"properties":{"pk":1627,"id_way":177273392,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224820.85954147947,6757987.327928205],[224803.89091625455,6758030.336974621],[224936.4550288684,6758082.268649441],[224940.07025559273,6758073.11585054],[224953.9805913207,6758078.571812468],[224963.30775565008,6758054.916220167],[224947.71409752558,6758048.8155218335],[224951.74770336447,6758038.603574558],[224820.85954147947,6757987.327928205]]]]},"properties":{"pk":1628,"id_way":257733702,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224593.55241275494,6757362.201071735],[224607.87391774746,6757322.171775711],[224540.0763588109,6757298.914545037],[224526.27741943588,6757339.390503097],[224593.55241275494,6757362.201071735]]]]},"properties":{"pk":1629,"id_way":283609410,"height":14.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224273.348548534,6757376.448919731],[224282.98068224688,6757374.841901792],[224276.85961928655,6757338.26113532],[224267.23399117985,6757339.85670044],[224273.348548534,6757376.448919731]]]]},"properties":{"pk":1630,"id_way":290453904,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224327.5253273217,6757439.358042159],[224344.83239777412,6757435.934077178],[224342.3392513013,6757423.731084442],[224324.91653057595,6757427.82555829],[224327.5253273217,6757439.358042159]]]]},"properties":{"pk":1631,"id_way":290453905,"height":5.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224377.06347914189,6757324.502614041],[224345.35919128402,6757347.260977201],[224295.89171062165,6757356.548447816],[224297.52717121586,6757368.030259563],[224349.98630421705,6757357.550202888],[224382.94436894794,6757332.7751862435],[224377.06347914189,6757324.502614041]]]]},"properties":{"pk":1632,"id_way":290453906,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224389.65129882153,6757313.48500082],[224397.2336481942,6757322.11898438],[224406.695600865,6757313.900684245],[224460.9788730655,6757333.851424013],[224464.89993427822,6757323.59483367],[224404.4718221601,6757301.058263927],[224389.65129882153,6757313.48500082]]]]},"properties":{"pk":1633,"id_way":290453907,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224333.7634503371,6758470.712263359],[224349.84263933828,6758477.49326422],[224353.45593398326,6758468.91953386],[224337.37672821293,6758462.138523276],[224333.7634503371,6758470.712263359]]]]},"properties":{"pk":1634,"id_way":320476814,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224363.5566587389,6758481.94191575],[224373.98890671975,6758486.369077095],[224377.45463799444,6758478.208290125],[224367.02237963735,6758473.781122695],[224363.5566587389,6758481.94191575]]]]},"properties":{"pk":1635,"id_way":320476815,"height":5.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223953.1750100432,6758331.804327536],[223965.70293346012,6758292.85662186],[223955.38339643672,6758289.552534459],[223951.6772682179,6758301.080515303],[223952.5108584507,6758301.347489887],[223951.54186472803,6758304.352561184],[223950.17703283316,6758303.927746077],[223947.44949627377,6758312.40110782],[223948.12072480656,6758312.614462865],[223947.1761207954,6758315.5515607875],[223946.2578434615,6758315.257814491],[223942.07710228403,6758328.261961254],[223953.1750100432,6758331.804327536]]]]},"properties":{"pk":1636,"id_way":361811324,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223517.908089774,6758053.056060605],[223514.38464126483,6758064.935723402],[223570.72286507115,6758081.513402116],[223580.1248304153,6758049.808114569],[223563.67557528152,6758044.966730936],[223558.49429708012,6758062.4397474],[223549.25433585033,6758059.730715322],[223548.47419982095,6758062.357760536],[223546.12592352013,6758061.661427988],[223546.9229993592,6758058.96666713],[223524.50639908217,6758052.378032756],[223523.79142877844,6758054.787790114],[223517.908089774,6758053.056060605]]]]},"properties":{"pk":1637,"id_way":361811332,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223909.15373257457,6758360.8708195705],[223919.3625113631,6758333.053090363],[223906.36044927643,6758328.312097968],[223902.13951649197,6758339.81069425],[223901.21014541792,6758339.473162038],[223900.00902620645,6758342.732088929],[223902.29331052344,6758343.561931996],[223901.69492385283,6758345.197050668],[223880.18574716727,6758337.364202667],[223880.7459916606,6758335.82112386],[223884.7738856546,6758337.290703058],[223890.1886848615,6758322.533887031],[223876.27314319668,6758317.465366674],[223866.10216957133,6758345.190909487],[223909.15373257457,6758360.8708195705]]]]},"properties":{"pk":1638,"id_way":361811337,"height":16.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224060.56670649664,6758355.2455747835],[224077.1445123906,6758316.343246325],[224078.5378379991,6758316.93315309],[224079.9329826592,6758313.676170189],[224078.39182373267,6758313.020377517],[224085.5211955125,6758296.293619291],[224070.92565817345,6758290.118287338],[224061.06501219881,6758313.240886144],[224054.30978955276,6758310.386337559],[224044.9178639702,6758332.423462009],[224041.4465430793,6758330.953567498],[224036.22732024852,6758343.17998633],[224039.8468697531,6758344.715996777],[224039.20792571438,6758346.205412252],[224060.56670649664,6758355.2455747835]]]]},"properties":{"pk":1639,"id_way":361811338,"height":16.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223553.31010648573,6758019.3163644755],[223555.70415945532,6758011.42878197],[223532.37117567597,6758004.391591813],[223529.5201131462,6758013.787541905],[223533.1284747012,6758014.882841838],[223533.59297154876,6758013.374348831],[223536.42603306464,6758014.22108503],[223535.96998167195,6758015.740637093],[223539.11450241806,6758016.684383349],[223539.5650096466,6758015.187456472],[223542.13041937188,6758015.968025591],[223541.69072267567,6758017.407601391],[223544.84251895564,6758018.3508529905],[223545.28823817088,6758016.887828371],[223547.92231875513,6758017.684680949],[223547.4774937384,6758019.158346149],[223550.4376334627,6758020.0499970345],[223550.883178249,6758018.587253463],[223553.31010648573,6758019.3163644755]]]]},"properties":{"pk":1640,"id_way":361811347,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223570.50826834858,6757986.602352936],[223540.36862918342,6757977.66181092],[223537.58038288428,6757987.007423425],[223541.21593616056,6757988.079548962],[223541.64755413987,6757986.628983003],[223544.50428106915,6757987.47367297],[223544.078230707,6757988.901466069],[223547.1056161593,6757989.799380442],[223547.5184782658,6757988.394696058],[223550.19898199048,6757989.198724779],[223549.76671090443,6757990.637905384],[223552.7639403672,6757991.527316537],[223553.2209810741,6757990.0191191835],[223555.8689298998,6757990.802352237],[223555.42022954221,6757992.321112037],[223558.4250355229,6757993.21012405],[223558.86320608668,6757991.747900164],[223561.59842814208,6757992.558555352],[223561.33425137188,6757993.38265184],[223567.9040398828,6757995.34226058],[223570.50826834858,6757986.602352936]]]]},"properties":{"pk":1641,"id_way":361811354,"height":5.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223552.48337065548,6758051.051116938],[223555.31571504884,6758041.701269329],[223551.855758399,6758040.654331359],[223552.52047387286,6758038.460431867],[223549.39835310588,6758037.515355335],[223548.72814000247,6758039.731698708],[223545.57067765453,6758038.788230269],[223546.27033929207,6758036.46881286],[223543.1492356838,6758035.534227034],[223542.44953142296,6758037.853426067],[223539.34602550362,6758036.927968949],[223540.0165279402,6758034.711098138],[223536.87967544224,6758033.766968829],[223536.21019440345,6758035.994686837],[223533.1291039643,6758035.066862703],[223533.83525299342,6758032.73608604],[223530.7066700774,6758031.801944516],[223529.78043495538,6758034.852782802],[223527.1540585185,6758034.072983257],[223525.07593312883,6758040.943434678],[223527.7119609598,6758041.744957823],[223527.18897956025,6758043.4588448],[223552.48337065548,6758051.051116938]]]]},"properties":{"pk":1642,"id_way":361811355,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223890.9211409955,6758276.6449404275],[223877.11385814004,6758314.361655312],[223891.1449189721,6758319.465489166],[223894.86862812203,6758309.270559814],[223891.00413919662,6758307.865972567],[223892.04523872488,6758305.013729558],[223895.93226038394,6758306.416572712],[223899.51625616543,6758296.634020498],[223895.61343612723,6758295.221358507],[223896.1752315732,6758293.689466175],[223916.4133402513,6758301.045290635],[223915.3537168928,6758303.956850932],[223915.15988153822,6758303.882687204],[223912.08807493426,6758312.273646606],[223912.2892767542,6758312.346819254],[223911.24171077157,6758315.209977658],[223911.06357153665,6758315.146572493],[223907.35027461412,6758325.285510593],[223920.328045508,6758330.006291644],[223924.0526394793,6758319.822341398],[223918.66970922306,6758317.860301742],[223919.70654108154,6758315.041974277],[223925.05747599804,6758316.984178394],[223928.12979137903,6758308.5918751415],[223922.79441794122,6758306.659451451],[223923.86127051554,6758303.749328924],[223929.16573729334,6758305.672995526],[223932.23075711707,6758297.281297097],[223926.94949090085,6758295.366833319],[223928.76560816666,6758290.393665708],[223890.9211409955,6758276.6449404275]]]]},"properties":{"pk":1643,"id_way":361811358,"height":4.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223569.27798085008,6757966.7321529],[223563.95654638752,6757984.453181241],[223570.56551322766,6757986.41071985],[223575.8722137339,6757968.690800509],[223569.27798085008,6757966.7321529]]]]},"properties":{"pk":1644,"id_way":361811362,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223966.6115222527,6758289.941189369],[223974.2616840831,6758264.897960322],[223965.10544391634,6758262.754562243],[223956.76509675215,6758286.428390171],[223966.6115222527,6758289.941189369]]]]},"properties":{"pk":1645,"id_way":361811364,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224044.28944195755,6758323.542516881],[224046.18270363196,6758319.097813227],[224043.15278192773,6758317.818686278],[224041.25859612282,6758322.252915485],[224044.28944195755,6758323.542516881]]]]},"properties":{"pk":1646,"id_way":361811376,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224052.09946222787,6758289.278064568],[224051.44405285703,6758291.794099344],[224055.16455455488,6758292.743990262],[224055.81378946098,6758290.239073713],[224052.09946222787,6758289.278064568]]]]},"properties":{"pk":1647,"id_way":361811379,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224013.3632455168,6758289.415268979],[224017.71097297917,6758275.801722009],[224009.21396399537,6758273.676345545],[224005.17571371997,6758286.829586884],[224013.3632455168,6758289.415268979]]]]},"properties":{"pk":1648,"id_way":361811392,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223976.19865866736,6758265.495139725],[223972.5635654586,6758276.910552025],[223987.22594111259,6758281.444785262],[223985.9035469642,6758285.806284425],[223984.5700733123,6758285.401103903],[223968.7588214867,6758336.974432965],[224015.45362458087,6758351.189381702],[224024.29086707727,6758322.361068056],[224020.41469375615,6758321.180318029],[224020.88818477638,6758319.617923878],[224023.73202675034,6758320.480894142],[224025.03512888387,6758316.229071984],[224026.28343900727,6758316.607716779],[224032.18693848627,6758297.346118117],[224028.2576168367,6758296.158542535],[224028.7367321576,6758294.573049775],[224031.5732158509,6758295.436638174],[224032.8584591643,6758291.241894036],[224034.0377520481,6758291.603691981],[224037.35215723258,6758280.777474823],[224023.24776421188,6758276.483030558],[224021.04569249728,6758283.661125582],[224019.55028448146,6758283.202164194],[224017.27576123146,6758290.611732368],[224018.63217160595,6758291.026235986],[224005.67136679453,6758333.2927055],[224009.4633188399,6758334.447044676],[224008.97445552322,6758336.02142097],[223982.7207968976,6758328.035008602],[223983.12377223704,6758326.712292478],[223987.14667344108,6758327.9370455835],[223991.9140627568,6758312.389702318],[223988.0917257181,6758311.226815112],[223988.58461016414,6758309.618588523],[223991.25841373575,6758310.428185506],[223992.62664575988,6758305.959516806],[223993.79760552084,6758306.3109917315],[223999.6490536467,6758287.242634794],[223995.96541762727,6758286.124290554],[223996.4293911496,6758284.618536688],[223999.12639502506,6758285.43747931],[224000.42958606474,6758281.1854416905],[224001.60844509272,6758281.547134341],[224004.3240053006,6758272.535540555],[223976.19865866736,6758265.495139725]]]]},"properties":{"pk":1649,"id_way":361811396,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224127.3889257759,6758222.713503331],[224123.13246137524,6758212.304966476],[224117.43360345683,6758209.872489032],[224119.70556264537,6758204.584000448],[224089.61257112277,6758191.745565808],[224084.22432134298,6758204.297781941],[224127.3889257759,6758222.713503331]]]]},"properties":{"pk":1650,"id_way":361811403,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223545.7770531549,6757959.681728557],[223575.92923942243,6757968.499102628],[223580.3060809929,6757953.686339684],[223550.13174670277,6757944.870483086],[223545.7770531549,6757959.681728557]]]]},"properties":{"pk":1651,"id_way":361811409,"height":15.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223561.27492841336,6757993.57366454],[223550.7542398231,6758028.546360164],[223557.33354763736,6758030.506055428],[223567.84669459108,6757995.533863169],[223561.27492841336,6757993.57366454]]]]},"properties":{"pk":1652,"id_way":361811413,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224347.5380152172,6758610.156195076],[224381.20549348244,6758614.678661803],[224380.97347067393,6758616.647337213],[224383.99686789463,6758617.031440557],[224386.011368167,6758602.1831856975],[224373.9813406522,6758600.532777622],[224374.2133441085,6758599.319948307],[224358.9233947034,6758592.860265352],[224358.47674133966,6758596.37756096],[224353.91376698375,6758595.731116072],[224353.4479147709,6758599.178514744],[224352.42814640875,6758599.043920924],[224347.5380152172,6758610.156195076]]]]},"properties":{"pk":1653,"id_way":364526497,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223715.7638493863,6757785.656510623],[223710.53474484314,6757789.378041954],[223709.52101146447,6757790.595873644],[223708.99676759957,6757792.066658769],[223709.0823430211,6757793.126322549],[223709.36727891586,6757794.106008163],[223709.89212967898,6757794.976703892],[223730.28745769148,6757814.767141296],[223731.34294567347,6757814.802339402],[223731.7938708266,6757814.649686464],[223735.84208052282,6757812.050802039],[223727.5672673901,6757797.213031219],[223724.91943980515,6757798.571146761],[223715.7638493863,6757785.656510623]]]]},"properties":{"pk":1654,"id_way":394999597,"height":13.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223900.33197748067,6758525.872385933],[223924.65665710994,6758535.539282062],[223932.17756783857,6758520.616501485],[223911.18176492813,6758509.904447444],[223909.71529308855,6758513.745910438],[223909.11963805967,6758514.580571564],[223908.20368488133,6758515.039952388],[223907.27412622527,6758515.068157729],[223904.88209975485,6758514.051084025],[223900.33197748067,6758525.872385933]]]]},"properties":{"pk":1655,"id_way":395946365,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223899.8413801523,6758495.861752793],[223901.96413092234,6758496.725865559],[223903.27866975928,6758495.017084596],[223900.68302650668,6758493.73992591],[223899.8413801523,6758495.861752793]]]]},"properties":{"pk":1656,"id_way":395946368,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223947.17549059345,6758474.722586066],[223955.6680392498,6758476.864709285],[223959.09992469603,6758469.087044573],[223949.15742490024,6758466.626621479],[223947.17549059345,6758474.722586066]]]]},"properties":{"pk":1657,"id_way":395947155,"height":5.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223991.08463680063,6758513.4454590315],[223986.5134381353,6758522.2725072345],[223996.05905941612,6758527.082564471],[224000.16326280124,6758519.21792181],[224000.2305431508,6758517.962002704],[223991.08463680063,6758513.4454590315]]]]},"properties":{"pk":1658,"id_way":395947156,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224020.3656626669,6758461.603193818],[224043.71788315984,6758454.875987397],[224039.94843571985,6758441.855900555],[224034.35211050732,6758443.47146074],[224036.18585498128,6758449.799728825],[224018.4308105711,6758454.922335748],[224020.3656626669,6758461.603193818]]]]},"properties":{"pk":1659,"id_way":395947157,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223635.96429033845,6758295.671799786],[223643.86900367728,6758301.18097676],[223645.92222094975,6758298.2007578425],[223653.13864080558,6758300.970581624],[223656.34388263858,6758292.281813965],[223644.5401522736,6758287.874709171],[223640.57618320454,6758289.061163574],[223635.96429033845,6758295.671799786]]]]},"properties":{"pk":1660,"id_way":395947158,"height":10.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224178.05136139938,6757814.386903372],[224169.1143231501,6757811.123093653],[224167.4802585203,6757815.556650347],[224166.71401834994,6757815.284238892],[224164.3171802555,6757821.805101886],[224165.08352179654,6757822.077452266],[224161.0128721366,6757833.144723754],[224160.18414977644,6757832.843736997],[224157.81082041492,6757839.285466335],[224158.64774882558,6757839.596917501],[224155.9540759624,6757846.925246128],[224164.89096453594,6757850.1889969325],[224168.24544295523,6757841.079461382],[224169.28298896275,6757841.452817684],[224170.38000698472,6757838.480194483],[224169.34176511035,6757838.09592536],[224174.7108236529,6757823.469660355],[224175.9424041624,6757823.916677641],[224177.0210052789,6757821.002032181],[224175.78996123435,6757820.555243038],[224178.05136139938,6757814.386903372]]]]},"properties":{"pk":1661,"id_way":412948347,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224195.26387439982,6757918.460918433],[224204.71108775266,6757917.46950533],[224204.01341977992,6757910.871539848],[224205.63071754714,6757910.696495759],[224205.2915320169,6757907.457841874],[224203.6744707816,6757907.632871492],[224202.02041273649,6757892.038309868],[224203.7198443229,6757891.856615261],[224203.38695356718,6757888.69482605],[224201.68679494207,6757888.865508975],[224200.44440396543,6757877.162299277],[224202.00939151924,6757876.991425235],[224201.55015683215,6757872.635933271],[224199.984381497,6757872.7957750745],[224198.3477183681,6757857.322855762],[224199.68197131014,6757857.181746109],[224199.32569988834,6757853.821454129],[224197.73747685502,6757853.983044316],[224197.04965102943,6757847.506955365],[224187.85620006482,6757848.477770249],[224188.33636674692,6757853.031598817],[224187.46429894527,6757853.1240394935],[224188.19785891875,6757860.04272056],[224189.06999037514,6757859.95017326],[224190.32759750972,6757871.842476933],[224189.47038453643,6757871.933767876],[224190.1885758715,6757878.753388198],[224191.05322567403,6757878.661554274],[224192.03977521887,6757888.034005279],[224191.167690368,6757888.126737355],[224191.92017105283,6757895.277990657],[224192.79970945502,6757895.18475138],[224194.03555822666,6757906.901061293],[224193.38665083545,6757906.964758884],[224194.1037614703,6757913.771622631],[224194.75916860552,6757913.696478381],[224195.26387439982,6757918.460918433]]]]},"properties":{"pk":1662,"id_way":412948353,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224131.26171513434,6757778.772519311],[224142.91760312032,6757783.1863995725],[224144.77555068213,6757778.327374286],[224132.8931388046,6757774.2945911335],[224131.26171513434,6757778.772519311]]]]},"properties":{"pk":1663,"id_way":412948364,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224431.30810674434,6757344.841534162],[224417.3555257469,6757339.7964504985],[224413.377508806,6757350.695294848],[224411.28658062173,6757349.9387724],[224406.70011081707,6757362.510148169],[224420.28445015883,6757367.4341101],[224419.82171815095,6757368.686247648],[224422.28898685492,6757369.574593581],[224431.30810674434,6757344.841534162]]]]},"properties":{"pk":1664,"id_way":412948423,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223585.61739192714,6757464.126655341],[223587.7826258842,6757467.168039605],[223609.87656610116,6757451.496927638],[223601.5736493986,6757439.855537366],[223598.90697935753,6757441.751602471],[223600.94964743254,6757444.607423773],[223596.55511270685,6757447.72685843],[223600.65047965417,6757453.471070942],[223585.61739192714,6757464.126655341]]]]},"properties":{"pk":1665,"id_way":412948425,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223845.79247508934,6757719.354273026],[223861.5135306885,6757741.321029289],[223882.99913083526,6757726.034618791],[223880.8447164049,6757723.0254160445],[223862.33179150807,6757736.201696066],[223848.76507165705,6757717.243934521],[223845.79247508934,6757719.354273026]]]]},"properties":{"pk":1666,"id_way":466744310,"height":5.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224107.8529718114,6757420.579081894],[224112.5213736062,6757417.087897157],[224109.79644239735,6757413.47568257],[224105.13612181012,6757416.976996034],[224107.8529718114,6757420.579081894]]]]},"properties":{"pk":1667,"id_way":466917805,"height":3.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223534.31563759173,6758622.374054062],[223551.08754606047,6758624.620598657],[223564.78041701915,6758627.484430395],[223575.9683637864,6758630.549986653],[223680.1659137296,6758660.445600706],[223681.3244191245,6758657.445933174],[223614.87720242632,6758638.250412896],[223590.23918772396,6758630.28634895],[223577.26580453786,6758626.263647177],[223561.9752715049,6758622.172961161],[223548.30075937204,6758619.767852518],[223535.07417801302,6758617.661245509],[223534.31563759173,6758622.374054062]]]]},"properties":{"pk":1668,"id_way":512330595,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223765.9051226624,6758608.635506307],[223768.2929674099,6758601.793731207],[223737.98220273003,6758590.592428098],[223735.51283005622,6758597.220605543],[223765.9051226624,6758608.635506307]]]]},"properties":{"pk":1669,"id_way":512330607,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223746.94196145888,6758660.105927695],[223749.41112394293,6758653.4782505995],[223718.67655847245,6758642.122654238],[223716.2074224292,6758648.75034399],[223746.94196145888,6758660.105927695]]]]},"properties":{"pk":1670,"id_way":512330608,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224990.40044916613,6757346.925860753],[225010.45708393198,6757349.89127297],[225040.85821718414,6757145.953934964],[225020.7934709739,6757142.98900822],[224990.40044916613,6757346.925860753]]]]},"properties":{"pk":1671,"id_way":518247417,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223585.8398817754,6757375.732463921],[223597.08014207653,6757367.463536926],[223592.38615078514,6757361.422183919],[223581.415914464,6757369.582931944],[223585.8398817754,6757375.732463921]]]]},"properties":{"pk":1672,"id_way":522708633,"height":10.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224237.60515424822,6758548.101376298],[224233.0997102258,6758546.302422761],[224230.35765019365,6758553.132459057],[224234.85583595288,6758554.9319563545],[224237.60515424822,6758548.101376298]]]]},"properties":{"pk":1673,"id_way":554626180,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224416.44378050702,6758441.45440537],[224420.85332640243,6758441.386689033],[224420.77482398498,6758436.28742143],[224416.37246069236,6758436.354561042],[224416.44378050702,6758441.45440537]]]]},"properties":{"pk":1674,"id_way":554626181,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224341.98151697146,6758289.6193993995],[224343.40816164736,6758293.524411421],[224348.93757853284,6758291.504534354],[224347.50380268795,6758287.600071299],[224341.98151697146,6758289.6193993995]]]]},"properties":{"pk":1675,"id_way":554626182,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224228.89734947772,6758241.285358996],[224226.86239402293,6758235.712631767],[224222.69750174397,6758237.2217885],[224224.74050429033,6758242.804518261],[224228.89734947772,6758241.285358996]]]]},"properties":{"pk":1676,"id_way":554626183,"height":5.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224274.7698128528,6757398.321328623],[224273.32917339235,6757389.753603854],[224205.8674068519,6757401.063448085],[224207.513735519,6757410.87413445],[224209.81318645726,6757410.488096595],[224211.2834940153,6757419.208692922],[224251.2537822533,6757412.5016961545],[224249.57799751725,6757402.537979762],[224274.7698128528,6757398.321328623]]]]},"properties":{"pk":1677,"id_way":554994266,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224207.00264769394,6757437.86248318],[224204.2961903727,6757421.439676857],[224203.7329964124,6757421.540857006],[224202.8202584791,6757416.006239294],[224190.19171601924,6757418.08391473],[224190.02820393103,6757417.08268406],[224184.5868580148,6757417.973360283],[224184.74412431696,6757418.896898513],[224169.72599806523,6757421.368070988],[224173.35900487212,6757443.4023568295],[224207.00264769394,6757437.86248318]]]]},"properties":{"pk":1678,"id_way":554994267,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224211.91420816004,6757469.522913048],[224209.10659564735,6757455.126443192],[224176.79857159086,6757460.879660296],[224178.7977223711,6757474.543152791],[224211.91420816004,6757469.522913048]]]]},"properties":{"pk":1679,"id_way":554994270,"height":5.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224843.39320412028,6758304.703175784],[224843.35790265893,6758306.825915615],[224844.19333185774,6758308.780194002],[224845.75450523282,6758310.228124658],[224847.77072226236,6758310.918196409],[224849.89336720842,6758310.7362442035],[224851.75562307087,6758309.700985652],[224853.04120586521,6758308.001729785],[224853.52278589684,6758305.930520413],[224853.1114847139,6758303.843809269],[224851.8881027847,6758302.106356708],[224850.060240972,6758301.007744564],[224847.93914850728,6758300.752411488],[224845.90350661206,6758301.375457262],[224844.2915218534,6758302.773068717],[224843.39320412028,6758304.703175784]]]]},"properties":{"pk":1680,"id_way":555250735,"height":5.7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224822.86433948524,6758389.764431201],[224846.23856606692,6758393.816712191],[224858.72677110494,6758319.91679893],[224835.45832970162,6758315.878184167],[224822.86433948524,6758389.764431201]]]]},"properties":{"pk":1681,"id_way":555250738,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224477.11894019807,6758294.632621082],[224424.9829491366,6758291.918885543],[224423.92546793408,6758311.657282839],[224476.10424109228,6758314.256474358],[224477.11894019807,6758294.632621082]]]]},"properties":{"pk":1682,"id_way":555250741,"height":5.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224479.55590357358,6758248.601183865],[224423.3249426767,6758245.737992941],[224421.003240089,6758281.652062283],[224477.5823962243,6758284.387073689],[224479.55590357358,6758248.601183865]]]]},"properties":{"pk":1683,"id_way":555250743,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224483.0767259628,6758210.027163995],[224423.0468374417,6758212.32366437],[224423.60828472604,6758227.103603784],[224483.6380230975,6758224.807109288],[224483.0767259628,6758210.027163995]]]]},"properties":{"pk":1684,"id_way":555250745,"height":5.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224495.30822600628,6758111.368812723],[224494.8134996183,6758120.559965037],[224497.3917331824,6758120.652990193],[224490.40344630138,6758254.980671119],[224489.75031684904,6758254.989012115],[224488.24117484113,6758285.370738552],[224514.21572809064,6758286.7607752085],[224515.62620715014,6758256.155677675],[224516.23509721877,6758256.15128622],[224523.1579208308,6758117.725241502],[224520.86667834854,6758117.631522034],[224521.03278984484,6758112.790205756],[224495.30822600628,6758111.368812723]]]]},"properties":{"pk":1685,"id_way":555250748,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224055.5336359254,6758537.742423427],[224059.37503889648,6758529.99117942],[224050.37231809046,6758525.559300257],[224046.5236179859,6758533.31114975],[224055.5336359254,6758537.742423427]]]]},"properties":{"pk":1686,"id_way":557967953,"height":4.5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223568.40578609018,6757634.407760168],[223576.1302147254,6757628.924769085],[223552.16959999182,6757595.363682908],[223544.44070459215,6757600.856720838],[223568.40578609018,6757634.407760168]]]]},"properties":{"pk":1687,"id_way":566345430,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223516.55374466407,6757620.248643771],[223544.2433595839,6757600.751610531],[223587.964196856,6757569.873895885],[223584.58306988011,6757565.400659416],[223513.2702975053,6757615.647735532],[223516.55374466407,6757620.248643771]]]]},"properties":{"pk":1688,"id_way":566345431,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223523.41874808582,6757629.848607796],[223550.97723100582,6757610.357969923],[223547.71999558384,6757605.7996027],[223520.18741605265,6757625.332433649],[223523.41874808582,6757629.848607796]]]]},"properties":{"pk":1689,"id_way":566345432,"height":4.1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223532.14888078423,6757660.03117617],[223540.4970022274,6757654.09745765],[223513.1070408044,6757615.763268558],[223504.75960983342,6757621.696508928],[223532.14888078423,6757660.03117617]]]]},"properties":{"pk":1690,"id_way":566345433,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225009.86848309322,6758073.494287599],[225017.97613901546,6758076.412792449],[225059.9196274801,6758089.054942244],[225057.5119106617,6758096.786124305],[225080.72343983356,6758104.39167968],[225090.6184085391,6758072.027693334],[225093.83263075858,6758073.085015895],[225097.33095956963,6758062.436376519],[225094.03317206135,6758061.499132509],[225100.62457012,6758039.456271062],[225091.0388178241,6758036.817608236],[225091.6845226402,6758034.594047261],[225091.02102452086,6758033.508524005],[225089.7394213105,6758032.857539175],[225088.3914737715,6758033.917717615],[225087.7159497748,6758035.835302874],[225080.61158313247,6758034.0012343135],[225074.23649218102,6758055.33234938],[225080.13117844195,6758057.177305147],[225072.35419775822,6758080.504221217],[225013.19035329585,6758062.029909404],[225009.86848309322,6758073.494287599]]]]},"properties":{"pk":1691,"id_way":658737411,"height":4.9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224917.76339627316,6757958.382065217],[224933.18312802498,6757959.527075868],[224934.82568173608,6757937.822967231],[224935.77615192672,6757937.925117818],[224953.8048692114,6757759.764245057],[224928.90447380903,6757757.291326152],[224910.58083860384,6757934.867835213],[224920.57396779672,6757936.270367976],[224917.76339627316,6757958.382065217]]]]},"properties":{"pk":1692,"id_way":658737418,"height":4.4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224960.7359920416,6757890.41768312],[224987.8712857889,6757893.122876833],[224999.5229573182,6757774.084270268],[224973.20913613,6757771.612401721],[224960.7359920416,6757890.41768312]]]]},"properties":{"pk":1693,"id_way":658737419,"height":6.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[225023.17438186757,6757777.340156463],[225011.54112112088,6757890.347401316],[225036.8040052292,6757892.305167267],[225048.03425059695,6757779.319015332],[225023.17438186757,6757777.340156463]]]]},"properties":{"pk":1694,"id_way":658737421,"height":4.3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224931.60062144735,6757725.531529004],[224963.37674997805,6757728.266757073],[224972.00503684778,6757638.823847415],[224986.50808740564,6757639.963057416],[224989.30667803637,6757609.982518812],[224944.37312902082,6757605.500210808],[224931.60062144735,6757725.531529004]]]]},"properties":{"pk":1695,"id_way":658737474,"height":4.0}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224978.3531183946,6757719.838640269],[225004.98350079788,6757722.429031819],[225007.99873865914,6757692.075286155],[224981.65650175881,6757689.262568723],[224978.3531183946,6757719.838640269]]]]},"properties":{"pk":1696,"id_way":658737479,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[224543.74558169852,6757375.983849216],[224558.15033398615,6757378.070830989],[224558.13185913023,6757387.924017229],[224575.0689786966,6757392.332304802],[224584.15203034406,6757365.843585966],[224574.8525553807,6757361.819542576],[224530.7184514235,6757360.961652714],[224526.54020910396,6757376.019011708],[224536.80576524627,6757379.759805913],[224543.74558169852,6757375.983849216]]]]},"properties":{"pk":1697,"id_way":677068746,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223824.9937936233,6758544.045623928],[223830.8068333808,6758545.582771855],[223832.5809713765,6758538.874681896],[223826.75781482316,6758537.392293548],[223824.9937936233,6758544.045623928]]]]},"properties":{"pk":1698,"id_way":706337999,"height":4.8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223845.92955352977,6757446.276620479],[223887.8172693888,6757416.69085982],[223873.8677859077,6757395.610654133],[223831.96451700767,6757425.552631555],[223845.92955352977,6757446.276620479]]]]},"properties":{"pk":1699,"id_way":706658760,"height":4.2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223811.46383357025,6757395.48634304],[223846.63971774068,6757370.135002636],[223836.6181065281,6757355.412052752],[223801.55260841225,6757380.212188554],[223811.46383357025,6757395.48634304]]]]},"properties":{"pk":1700,"id_way":706658761,"height":4.6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[223748.8617859165,6758343.353773426],[223750.5079526763,6758337.412498683],[223744.6282275899,6758335.8043697],[223742.9884321911,6758341.734339758],[223748.8617859165,6758343.353773426]]]]},"properties":{"pk":1701,"id_way":706899915,"height":4.0}}]} \ No newline at end of file diff --git a/noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/dem_lorient.geojson b/noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/dem_lorient.geojson deleted file mode 100644 index e61e45140..000000000 --- a/noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/dem_lorient.geojson +++ /dev/null @@ -1 +0,0 @@ -{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6756825.0,-0.07]},"properties":{"height":-0.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6756825.0,-0.05]},"properties":{"height":-0.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6756825.0,-0.05]},"properties":{"height":-0.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6756825.0,0.0]},"properties":{"height":0.0}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6756825.0,-0.03]},"properties":{"height":-0.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6756825.0,-0.07]},"properties":{"height":-0.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6756900.0,-0.09]},"properties":{"height":-0.09}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6756900.0,-0.09]},"properties":{"height":-0.09}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6756900.0,-0.03]},"properties":{"height":-0.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6756900.0,-0.07]},"properties":{"height":-0.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6756900.0,0.07]},"properties":{"height":0.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6756900.0,-0.11]},"properties":{"height":-0.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6756900.0,-0.05]},"properties":{"height":-0.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6756900.0,-0.07]},"properties":{"height":-0.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6756900.0,0.0]},"properties":{"height":0.0}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6756900.0,-0.05]},"properties":{"height":-0.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6756900.0,-0.02]},"properties":{"height":-0.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6756975.0,-1.03]},"properties":{"height":-1.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6756975.0,3.87]},"properties":{"height":3.87}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6756975.0,3.29]},"properties":{"height":3.29}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6756975.0,1.89]},"properties":{"height":1.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6756975.0,-0.18]},"properties":{"height":-0.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6756975.0,0.07]},"properties":{"height":0.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6756975.0,-0.18]},"properties":{"height":-0.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6756975.0,-0.05]},"properties":{"height":-0.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6756975.0,-0.07]},"properties":{"height":-0.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6756975.0,0.01]},"properties":{"height":0.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6756975.0,-0.05]},"properties":{"height":-0.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6756975.0,0.07]},"properties":{"height":0.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757050.0,-1.51]},"properties":{"height":-1.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757050.0,3.39]},"properties":{"height":3.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757050.0,3.48]},"properties":{"height":3.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757050.0,3.67]},"properties":{"height":3.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757050.0,2.95]},"properties":{"height":2.95}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757050.0,3.24]},"properties":{"height":3.24}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757050.0,3.39]},"properties":{"height":3.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757050.0,2.94]},"properties":{"height":2.94}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757050.0,3.17]},"properties":{"height":3.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757050.0,0.18]},"properties":{"height":0.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757050.0,0.15]},"properties":{"height":0.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757050.0,0.0]},"properties":{"height":0.0}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757050.0,0.01]},"properties":{"height":0.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757125.0,3.84]},"properties":{"height":3.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757125.0,3.38]},"properties":{"height":3.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757125.0,3.77]},"properties":{"height":3.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757125.0,3.25]},"properties":{"height":3.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757125.0,3.71]},"properties":{"height":3.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757125.0,3.96]},"properties":{"height":3.96}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757125.0,3.85]},"properties":{"height":3.85}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757125.0,4.3]},"properties":{"height":4.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757125.0,2.08]},"properties":{"height":2.08}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757125.0,1.84]},"properties":{"height":1.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757125.0,6.28]},"properties":{"height":6.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757125.0,6.59]},"properties":{"height":6.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757125.0,3.84]},"properties":{"height":3.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757200.0,3.82]},"properties":{"height":3.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757200.0,3.96]},"properties":{"height":3.96}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757200.0,3.74]},"properties":{"height":3.74}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757200.0,3.28]},"properties":{"height":3.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757200.0,3.69]},"properties":{"height":3.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757200.0,3.75]},"properties":{"height":3.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757200.0,4.01]},"properties":{"height":4.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757200.0,3.91]},"properties":{"height":3.91}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757200.0,3.26]},"properties":{"height":3.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757200.0,5.4]},"properties":{"height":5.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757200.0,7.44]},"properties":{"height":7.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757200.0,7.21]},"properties":{"height":7.21}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757200.0,4.98]},"properties":{"height":4.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757275.0,4.05]},"properties":{"height":4.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757275.0,3.9]},"properties":{"height":3.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757275.0,3.89]},"properties":{"height":3.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757275.0,4.13]},"properties":{"height":4.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757275.0,4.32]},"properties":{"height":4.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757275.0,4.25]},"properties":{"height":4.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757275.0,4.17]},"properties":{"height":4.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757275.0,4.28]},"properties":{"height":4.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757275.0,3.84]},"properties":{"height":3.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757275.0,7.3]},"properties":{"height":7.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757275.0,7.38]},"properties":{"height":7.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757275.0,11.81]},"properties":{"height":11.81}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757275.0,7.19]},"properties":{"height":7.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757350.0,3.93]},"properties":{"height":3.93}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757350.0,3.94]},"properties":{"height":3.94}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757350.0,4.51]},"properties":{"height":4.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757350.0,4.32]},"properties":{"height":4.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757350.0,4.73]},"properties":{"height":4.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757350.0,4.67]},"properties":{"height":4.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757350.0,4.44]},"properties":{"height":4.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757350.0,4.67]},"properties":{"height":4.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757350.0,7.3]},"properties":{"height":7.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757350.0,7.53]},"properties":{"height":7.53}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757350.0,13.38]},"properties":{"height":13.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757350.0,14.77]},"properties":{"height":14.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757350.0,11.4]},"properties":{"height":11.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757425.0,4.73]},"properties":{"height":4.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757425.0,6.07]},"properties":{"height":6.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757425.0,4.84]},"properties":{"height":4.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757425.0,4.46]},"properties":{"height":4.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757425.0,4.03]},"properties":{"height":4.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757425.0,4.92]},"properties":{"height":4.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757425.0,4.34]},"properties":{"height":4.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757425.0,4.42]},"properties":{"height":4.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757425.0,7.61]},"properties":{"height":7.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757425.0,9.67]},"properties":{"height":9.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757425.0,15.03]},"properties":{"height":15.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757425.0,18.440001]},"properties":{"height":18.440001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757425.0,16.190001]},"properties":{"height":16.190001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757500.0,4.94]},"properties":{"height":4.94}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757500.0,5.34]},"properties":{"height":5.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757500.0,4.88]},"properties":{"height":4.88}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757500.0,4.07]},"properties":{"height":4.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757500.0,4.28]},"properties":{"height":4.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757500.0,4.28]},"properties":{"height":4.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757500.0,4.46]},"properties":{"height":4.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757500.0,7.69]},"properties":{"height":7.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757500.0,9.23]},"properties":{"height":9.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757500.0,10.89]},"properties":{"height":10.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757500.0,22.59]},"properties":{"height":22.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757500.0,21.51]},"properties":{"height":21.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757500.0,20.049999]},"properties":{"height":20.049999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757575.0,5.32]},"properties":{"height":5.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757575.0,5.98]},"properties":{"height":5.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757575.0,5.19]},"properties":{"height":5.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757575.0,4.42]},"properties":{"height":4.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757575.0,4.76]},"properties":{"height":4.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757575.0,4.26]},"properties":{"height":4.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757575.0,4.36]},"properties":{"height":4.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757575.0,9.18]},"properties":{"height":9.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757575.0,9.18]},"properties":{"height":9.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757575.0,17.43]},"properties":{"height":17.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757575.0,22.190001]},"properties":{"height":22.190001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757575.0,22.440001]},"properties":{"height":22.440001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757575.0,21.549999]},"properties":{"height":21.549999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757650.0,5.4]},"properties":{"height":5.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757650.0,6.23]},"properties":{"height":6.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757650.0,6.36]},"properties":{"height":6.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757650.0,4.9]},"properties":{"height":4.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757650.0,4.44]},"properties":{"height":4.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757650.0,4.28]},"properties":{"height":4.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757650.0,6.48]},"properties":{"height":6.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757650.0,9.47]},"properties":{"height":9.47}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757650.0,10.18]},"properties":{"height":10.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757650.0,16.209999]},"properties":{"height":16.209999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757650.0,21.15]},"properties":{"height":21.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757650.0,22.049999]},"properties":{"height":22.049999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757650.0,20.959999]},"properties":{"height":20.959999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757725.0,5.23]},"properties":{"height":5.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757725.0,4.86]},"properties":{"height":4.86}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757725.0,4.84]},"properties":{"height":4.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757725.0,4.4]},"properties":{"height":4.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757725.0,3.76]},"properties":{"height":3.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757725.0,3.56]},"properties":{"height":3.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757725.0,5.92]},"properties":{"height":5.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757725.0,6.59]},"properties":{"height":6.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757725.0,8.43]},"properties":{"height":8.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757725.0,10.46]},"properties":{"height":10.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757725.0,20.27]},"properties":{"height":20.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757725.0,20.700001]},"properties":{"height":20.700001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757725.0,20.389999]},"properties":{"height":20.389999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757800.0,4.48]},"properties":{"height":4.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757800.0,4.36]},"properties":{"height":4.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757800.0,3.41]},"properties":{"height":3.41}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757800.0,3.97]},"properties":{"height":3.97}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757800.0,2.85]},"properties":{"height":2.85}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757800.0,3.27]},"properties":{"height":3.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757800.0,3.64]},"properties":{"height":3.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757800.0,4.73]},"properties":{"height":4.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757800.0,6.5]},"properties":{"height":6.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757800.0,7.76]},"properties":{"height":7.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757800.0,14.64]},"properties":{"height":14.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757800.0,15.72]},"properties":{"height":15.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757800.0,19.68]},"properties":{"height":19.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757875.0,4.44]},"properties":{"height":4.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757875.0,4.3]},"properties":{"height":4.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757875.0,3.35]},"properties":{"height":3.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757875.0,3.07]},"properties":{"height":3.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757875.0,4.41]},"properties":{"height":4.41}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757875.0,4.8]},"properties":{"height":4.8}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757875.0,5.55]},"properties":{"height":5.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757875.0,5.51]},"properties":{"height":5.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757875.0,8.18]},"properties":{"height":8.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757875.0,10.1]},"properties":{"height":10.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757875.0,11.13]},"properties":{"height":11.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757875.0,14.09]},"properties":{"height":14.09}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757875.0,17.629999]},"properties":{"height":17.629999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6757950.0,4.48]},"properties":{"height":4.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6757950.0,3.75]},"properties":{"height":3.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6757950.0,2.57]},"properties":{"height":2.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6757950.0,4.69]},"properties":{"height":4.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6757950.0,5.66]},"properties":{"height":5.66}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6757950.0,8.02]},"properties":{"height":8.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6757950.0,9.39]},"properties":{"height":9.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6757950.0,11.69]},"properties":{"height":11.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6757950.0,15.27]},"properties":{"height":15.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6757950.0,15.86]},"properties":{"height":15.86}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6757950.0,16.1]},"properties":{"height":16.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6757950.0,15.75]},"properties":{"height":15.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6757950.0,19.07]},"properties":{"height":19.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758025.0,4.15]},"properties":{"height":4.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758025.0,3.66]},"properties":{"height":3.66}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758025.0,5.09]},"properties":{"height":5.09}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758025.0,5.61]},"properties":{"height":5.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758025.0,6.57]},"properties":{"height":6.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758025.0,6.9]},"properties":{"height":6.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758025.0,11.36]},"properties":{"height":11.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758025.0,15.35]},"properties":{"height":15.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758025.0,17.540001]},"properties":{"height":17.540001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758025.0,17.76]},"properties":{"height":17.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758025.0,18.190001]},"properties":{"height":18.190001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758025.0,18.870001]},"properties":{"height":18.870001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758025.0,19.67]},"properties":{"height":19.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758100.0,4.19]},"properties":{"height":4.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758100.0,3.58]},"properties":{"height":3.58}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758100.0,2.96]},"properties":{"height":2.96}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758100.0,4.78]},"properties":{"height":4.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758100.0,5.19]},"properties":{"height":5.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758100.0,2.73]},"properties":{"height":2.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758100.0,10.67]},"properties":{"height":10.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758100.0,14.89]},"properties":{"height":14.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758100.0,17.73]},"properties":{"height":17.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758100.0,18.370001]},"properties":{"height":18.370001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758100.0,19.190001]},"properties":{"height":19.190001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758100.0,19.780001]},"properties":{"height":19.780001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758100.0,20.790001]},"properties":{"height":20.790001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758175.0,4.86]},"properties":{"height":4.86}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758175.0,3.49]},"properties":{"height":3.49}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758175.0,3.5]},"properties":{"height":3.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758175.0,5.76]},"properties":{"height":5.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758175.0,7.57]},"properties":{"height":7.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758175.0,6.26]},"properties":{"height":6.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758175.0,7.55]},"properties":{"height":7.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758175.0,11.85]},"properties":{"height":11.85}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758175.0,15.14]},"properties":{"height":15.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758175.0,17.139999]},"properties":{"height":17.139999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758175.0,18.040001]},"properties":{"height":18.040001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758175.0,19.299999]},"properties":{"height":19.299999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758175.0,20.719999]},"properties":{"height":20.719999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758250.0,11.76]},"properties":{"height":11.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758250.0,6.57]},"properties":{"height":6.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758250.0,7.42]},"properties":{"height":7.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758250.0,9.03]},"properties":{"height":9.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758250.0,11.02]},"properties":{"height":11.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758250.0,11.51]},"properties":{"height":11.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758250.0,11.72]},"properties":{"height":11.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758250.0,10.63]},"properties":{"height":10.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758250.0,11.18]},"properties":{"height":11.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758250.0,14.96]},"properties":{"height":14.96}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758250.0,17.870001]},"properties":{"height":17.870001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758250.0,18.76]},"properties":{"height":18.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758250.0,19.209999]},"properties":{"height":19.209999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758325.0,12.03]},"properties":{"height":12.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758325.0,10.15]},"properties":{"height":10.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758325.0,11.05]},"properties":{"height":11.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758325.0,13.22]},"properties":{"height":13.22}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758325.0,13.9]},"properties":{"height":13.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758325.0,16.040001]},"properties":{"height":16.040001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758325.0,16.26]},"properties":{"height":16.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758325.0,14.25]},"properties":{"height":14.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758325.0,11.71]},"properties":{"height":11.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758325.0,14.06]},"properties":{"height":14.06}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758325.0,16.209999]},"properties":{"height":16.209999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758325.0,17.51]},"properties":{"height":17.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758325.0,18.139999]},"properties":{"height":18.139999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758400.0,11.56]},"properties":{"height":11.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758400.0,10.71]},"properties":{"height":10.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758400.0,14.25]},"properties":{"height":14.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758400.0,15.1]},"properties":{"height":15.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758400.0,16.15]},"properties":{"height":16.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758400.0,17.74]},"properties":{"height":17.74}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758400.0,17.84]},"properties":{"height":17.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758400.0,15.71]},"properties":{"height":15.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758400.0,13.78]},"properties":{"height":13.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758400.0,11.63]},"properties":{"height":11.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758400.0,13.52]},"properties":{"height":13.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758400.0,15.46]},"properties":{"height":15.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758400.0,17.530001]},"properties":{"height":17.530001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758475.0,12.57]},"properties":{"height":12.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758475.0,15.68]},"properties":{"height":15.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758475.0,15.59]},"properties":{"height":15.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758475.0,16.540001]},"properties":{"height":16.540001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758475.0,17.799999]},"properties":{"height":17.799999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758475.0,19.129999]},"properties":{"height":19.129999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758475.0,19.379999]},"properties":{"height":19.379999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758475.0,17.139999]},"properties":{"height":17.139999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758475.0,16.35]},"properties":{"height":16.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758475.0,16.639999]},"properties":{"height":16.639999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758475.0,16.379999]},"properties":{"height":16.379999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758475.0,16.84]},"properties":{"height":16.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758475.0,17.65]},"properties":{"height":17.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758550.0,11.5]},"properties":{"height":11.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758550.0,12.51]},"properties":{"height":12.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758550.0,14.27]},"properties":{"height":14.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758550.0,16.309999]},"properties":{"height":16.309999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758550.0,19.620001]},"properties":{"height":19.620001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758550.0,20.540001]},"properties":{"height":20.540001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758550.0,20.360001]},"properties":{"height":20.360001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758550.0,20.219999]},"properties":{"height":20.219999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758550.0,19.860001]},"properties":{"height":19.860001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758550.0,18.719999]},"properties":{"height":18.719999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758550.0,19.450001]},"properties":{"height":19.450001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758550.0,18.959999]},"properties":{"height":18.959999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758550.0,18.67]},"properties":{"height":18.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758625.0,10.71]},"properties":{"height":10.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758625.0,7.3]},"properties":{"height":7.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758625.0,10.89]},"properties":{"height":10.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758625.0,16.620001]},"properties":{"height":16.620001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758625.0,20.65]},"properties":{"height":20.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758625.0,22.290001]},"properties":{"height":22.290001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758625.0,21.870001]},"properties":{"height":21.870001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758625.0,22.190001]},"properties":{"height":22.190001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758625.0,22.299999]},"properties":{"height":22.299999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758625.0,22.360001]},"properties":{"height":22.360001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758625.0,21.75]},"properties":{"height":21.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758625.0,21.290001]},"properties":{"height":21.290001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758625.0,21.290001]},"properties":{"height":21.290001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758700.0,6.96]},"properties":{"height":6.96}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758700.0,9.81]},"properties":{"height":9.81}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758700.0,12.25]},"properties":{"height":12.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758700.0,16.940001]},"properties":{"height":16.940001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758700.0,20.950001]},"properties":{"height":20.950001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758700.0,23.120001]},"properties":{"height":23.120001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758700.0,22.93]},"properties":{"height":22.93}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758700.0,24.1]},"properties":{"height":24.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758700.0,24.110001]},"properties":{"height":24.110001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758700.0,24.799999]},"properties":{"height":24.799999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758700.0,24.59]},"properties":{"height":24.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758700.0,23.700001]},"properties":{"height":23.700001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758700.0,21.790001]},"properties":{"height":21.790001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758775.0,6.38]},"properties":{"height":6.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758775.0,10.22]},"properties":{"height":10.22}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758775.0,12.46]},"properties":{"height":12.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758775.0,15.8]},"properties":{"height":15.8}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758775.0,17.780001]},"properties":{"height":17.780001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758775.0,19.57]},"properties":{"height":19.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758775.0,22.370001]},"properties":{"height":22.370001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758775.0,24.67]},"properties":{"height":24.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758775.0,25.15]},"properties":{"height":25.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758775.0,24.6]},"properties":{"height":24.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758775.0,24.23]},"properties":{"height":24.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758775.0,23.530001]},"properties":{"height":23.530001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758775.0,21.26]},"properties":{"height":21.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758850.0,9.01]},"properties":{"height":9.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758850.0,8.68]},"properties":{"height":8.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758850.0,9.98]},"properties":{"height":9.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758850.0,11.44]},"properties":{"height":11.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758850.0,13.92]},"properties":{"height":13.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758850.0,17.950001]},"properties":{"height":17.950001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758850.0,21.16]},"properties":{"height":21.16}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758850.0,23.440001]},"properties":{"height":23.440001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758850.0,23.120001]},"properties":{"height":23.120001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758850.0,21.52]},"properties":{"height":21.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758850.0,19.32]},"properties":{"height":19.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758850.0,19.790001]},"properties":{"height":19.790001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758850.0,18.07]},"properties":{"height":18.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6758925.0,12.03]},"properties":{"height":12.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6758925.0,12.31]},"properties":{"height":12.31}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6758925.0,14.48]},"properties":{"height":14.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6758925.0,15.35]},"properties":{"height":15.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6758925.0,17.290001]},"properties":{"height":17.290001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6758925.0,21.059999]},"properties":{"height":21.059999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6758925.0,23.51]},"properties":{"height":23.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6758925.0,24.43]},"properties":{"height":24.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6758925.0,23.32]},"properties":{"height":23.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6758925.0,19.559999]},"properties":{"height":19.559999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6758925.0,15.18]},"properties":{"height":15.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6758925.0,13.38]},"properties":{"height":13.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6758925.0,10.71]},"properties":{"height":10.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6759000.0,14.23]},"properties":{"height":14.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6759000.0,14.05]},"properties":{"height":14.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6759000.0,17.809999]},"properties":{"height":17.809999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6759000.0,19.309999]},"properties":{"height":19.309999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6759000.0,21.040001]},"properties":{"height":21.040001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6759000.0,23.139999]},"properties":{"height":23.139999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6759000.0,24.870001]},"properties":{"height":24.870001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6759000.0,24.459999]},"properties":{"height":24.459999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6759000.0,21.559999]},"properties":{"height":21.559999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6759000.0,18.549999]},"properties":{"height":18.549999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6759000.0,16.790001]},"properties":{"height":16.790001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6759000.0,14.86]},"properties":{"height":14.86}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6759000.0,13.31]},"properties":{"height":13.31}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6759075.0,12.88]},"properties":{"height":12.88}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6759075.0,16.040001]},"properties":{"height":16.040001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6759075.0,18.709999]},"properties":{"height":18.709999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6759075.0,21.1]},"properties":{"height":21.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6759075.0,23.450001]},"properties":{"height":23.450001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6759075.0,24.68]},"properties":{"height":24.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6759075.0,25.030001]},"properties":{"height":25.030001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6759075.0,24.51]},"properties":{"height":24.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6759075.0,22.65]},"properties":{"height":22.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6759075.0,20.27]},"properties":{"height":20.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6759075.0,18.6]},"properties":{"height":18.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6759075.0,17.440001]},"properties":{"height":17.440001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6759075.0,14.64]},"properties":{"height":14.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6759150.0,7.73]},"properties":{"height":7.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6759150.0,11.26]},"properties":{"height":11.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6759150.0,16.77]},"properties":{"height":16.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6759150.0,19.959999]},"properties":{"height":19.959999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6759150.0,22.48]},"properties":{"height":22.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6759150.0,23.6]},"properties":{"height":23.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6759150.0,24.200001]},"properties":{"height":24.200001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6759150.0,23.440001]},"properties":{"height":23.440001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6759150.0,22.700001]},"properties":{"height":22.700001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6759150.0,21.059999]},"properties":{"height":21.059999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6759150.0,17.17]},"properties":{"height":17.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6759150.0,15.02]},"properties":{"height":15.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6759150.0,12.68]},"properties":{"height":12.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6759225.0,4.63]},"properties":{"height":4.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6759225.0,8.47]},"properties":{"height":8.47}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6759225.0,12.1]},"properties":{"height":12.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6759225.0,16.73]},"properties":{"height":16.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6759225.0,20.6]},"properties":{"height":20.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6759225.0,21.1]},"properties":{"height":21.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6759225.0,20.700001]},"properties":{"height":20.700001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6759225.0,21.530001]},"properties":{"height":21.530001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6759225.0,22.27]},"properties":{"height":22.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6759225.0,20.76]},"properties":{"height":20.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6759225.0,18.43]},"properties":{"height":18.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6759225.0,17.6]},"properties":{"height":17.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6759225.0,16.540001]},"properties":{"height":16.540001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6759300.0,4.63]},"properties":{"height":4.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6759300.0,7.67]},"properties":{"height":7.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6759300.0,11.56]},"properties":{"height":11.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6759300.0,15.61]},"properties":{"height":15.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6759300.0,13.47]},"properties":{"height":13.47}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6759300.0,16.700001]},"properties":{"height":16.700001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6759300.0,17.049999]},"properties":{"height":17.049999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6759300.0,19.77]},"properties":{"height":19.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6759300.0,22.700001]},"properties":{"height":22.700001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6759300.0,22.0]},"properties":{"height":22.0}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6759300.0,21.209999]},"properties":{"height":21.209999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6759300.0,20.57]},"properties":{"height":20.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6759300.0,18.620001]},"properties":{"height":18.620001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225000.0,6759375.0,4.23]},"properties":{"height":4.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225075.0,6759375.0,8.48]},"properties":{"height":8.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225150.0,6759375.0,11.39]},"properties":{"height":11.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225225.0,6759375.0,13.75]},"properties":{"height":13.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225300.0,6759375.0,14.73]},"properties":{"height":14.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225375.0,6759375.0,13.31]},"properties":{"height":13.31}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225450.0,6759375.0,15.02]},"properties":{"height":15.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225525.0,6759375.0,17.440001]},"properties":{"height":17.440001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225600.0,6759375.0,22.26]},"properties":{"height":22.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225675.0,6759375.0,24.040001]},"properties":{"height":24.040001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225750.0,6759375.0,23.370001]},"properties":{"height":23.370001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225825.0,6759375.0,21.889999]},"properties":{"height":21.889999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[225900.0,6759375.0,19.290001]},"properties":{"height":19.290001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6756825.0,13.85]},"properties":{"height":13.85}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6756825.0,15.13]},"properties":{"height":15.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6756825.0,16.620001]},"properties":{"height":16.620001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6756825.0,16.950001]},"properties":{"height":16.950001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6756825.0,15.02]},"properties":{"height":15.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6756825.0,9.3]},"properties":{"height":9.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6756825.0,8.5]},"properties":{"height":8.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6756825.0,6.88]},"properties":{"height":6.88}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6756825.0,5.19]},"properties":{"height":5.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6756825.0,5.17]},"properties":{"height":5.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6756825.0,4.46]},"properties":{"height":4.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6756825.0,3.46]},"properties":{"height":3.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6756825.0,3.01]},"properties":{"height":3.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6756825.0,3.11]},"properties":{"height":3.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6756825.0,2.55]},"properties":{"height":2.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6756825.0,3.36]},"properties":{"height":3.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6756825.0,4.13]},"properties":{"height":4.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6756825.0,3.88]},"properties":{"height":3.88}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6756825.0,4.3]},"properties":{"height":4.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6756900.0,16.110001]},"properties":{"height":16.110001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6756900.0,16.290001]},"properties":{"height":16.290001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6756900.0,17.35]},"properties":{"height":17.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6756900.0,17.18]},"properties":{"height":17.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6756900.0,15.36]},"properties":{"height":15.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6756900.0,11.13]},"properties":{"height":11.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6756900.0,8.68]},"properties":{"height":8.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6756900.0,10.93]},"properties":{"height":10.93}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6756900.0,7.82]},"properties":{"height":7.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6756900.0,5.88]},"properties":{"height":5.88}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6756900.0,5.9]},"properties":{"height":5.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6756900.0,4.8]},"properties":{"height":4.8}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6756900.0,5.42]},"properties":{"height":5.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6756900.0,3.52]},"properties":{"height":3.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6756900.0,4.34]},"properties":{"height":4.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6756900.0,3.82]},"properties":{"height":3.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6756900.0,3.82]},"properties":{"height":3.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6756900.0,4.15]},"properties":{"height":4.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6756900.0,3.89]},"properties":{"height":3.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6756900.0,-0.15]},"properties":{"height":-0.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6756975.0,16.5]},"properties":{"height":16.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6756975.0,17.6]},"properties":{"height":17.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6756975.0,17.610001]},"properties":{"height":17.610001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6756975.0,16.5]},"properties":{"height":16.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6756975.0,14.25]},"properties":{"height":14.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6756975.0,12.64]},"properties":{"height":12.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6756975.0,11.46]},"properties":{"height":11.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6756975.0,12.39]},"properties":{"height":12.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6756975.0,11.67]},"properties":{"height":11.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6756975.0,11.69]},"properties":{"height":11.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6756975.0,6.48]},"properties":{"height":6.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6756975.0,4.67]},"properties":{"height":4.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6756975.0,4.88]},"properties":{"height":4.88}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6756975.0,4.17]},"properties":{"height":4.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6756975.0,3.56]},"properties":{"height":3.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6756975.0,3.84]},"properties":{"height":3.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6756975.0,3.2]},"properties":{"height":3.2}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6756975.0,3.39]},"properties":{"height":3.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6756975.0,4.15]},"properties":{"height":4.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6756975.0,3.52]},"properties":{"height":3.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757050.0,16.68]},"properties":{"height":16.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757050.0,17.17]},"properties":{"height":17.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757050.0,17.73]},"properties":{"height":17.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757050.0,16.959999]},"properties":{"height":16.959999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757050.0,16.459999]},"properties":{"height":16.459999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757050.0,14.84]},"properties":{"height":14.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757050.0,13.55]},"properties":{"height":13.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757050.0,12.22]},"properties":{"height":12.22}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757050.0,10.78]},"properties":{"height":10.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757050.0,9.42]},"properties":{"height":9.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757050.0,7.98]},"properties":{"height":7.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757050.0,6.34]},"properties":{"height":6.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757050.0,3.75]},"properties":{"height":3.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757050.0,4.5]},"properties":{"height":4.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757050.0,4.13]},"properties":{"height":4.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757050.0,4.15]},"properties":{"height":4.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757050.0,3.67]},"properties":{"height":3.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757050.0,3.2]},"properties":{"height":3.2}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757050.0,3.48]},"properties":{"height":3.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757050.0,4.15]},"properties":{"height":4.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757050.0,1.25]},"properties":{"height":1.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757050.0,-1.3]},"properties":{"height":-1.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757050.0,-0.92]},"properties":{"height":-0.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757125.0,15.63]},"properties":{"height":15.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757125.0,16.290001]},"properties":{"height":16.290001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757125.0,16.450001]},"properties":{"height":16.450001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757125.0,16.209999]},"properties":{"height":16.209999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757125.0,15.0]},"properties":{"height":15.0}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757125.0,14.43]},"properties":{"height":14.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757125.0,12.39]},"properties":{"height":12.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757125.0,11.05]},"properties":{"height":11.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757125.0,10.27]},"properties":{"height":10.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757125.0,8.06]},"properties":{"height":8.06}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757125.0,6.96]},"properties":{"height":6.96}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757125.0,5.46]},"properties":{"height":5.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757125.0,4.59]},"properties":{"height":4.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757125.0,4.59]},"properties":{"height":4.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757125.0,3.97]},"properties":{"height":3.97}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757125.0,3.39]},"properties":{"height":3.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757125.0,3.61]},"properties":{"height":3.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757125.0,3.43]},"properties":{"height":3.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757125.0,3.56]},"properties":{"height":3.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757125.0,3.36]},"properties":{"height":3.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757125.0,3.3]},"properties":{"height":3.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757125.0,-1.2]},"properties":{"height":-1.2}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757125.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757125.0,-1.76]},"properties":{"height":-1.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757125.0,3.91]},"properties":{"height":3.91}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757200.0,14.73]},"properties":{"height":14.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757200.0,15.34]},"properties":{"height":15.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757200.0,15.35]},"properties":{"height":15.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757200.0,15.39]},"properties":{"height":15.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757200.0,13.97]},"properties":{"height":13.97}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757200.0,12.43]},"properties":{"height":12.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757200.0,10.06]},"properties":{"height":10.06}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757200.0,10.67]},"properties":{"height":10.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757200.0,6.46]},"properties":{"height":6.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757200.0,5.67]},"properties":{"height":5.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757200.0,5.46]},"properties":{"height":5.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757200.0,4.67]},"properties":{"height":4.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757200.0,4.13]},"properties":{"height":4.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757200.0,4.34]},"properties":{"height":4.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757200.0,3.75]},"properties":{"height":3.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757200.0,3.05]},"properties":{"height":3.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757200.0,2.94]},"properties":{"height":2.94}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757200.0,3.36]},"properties":{"height":3.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757200.0,2.81]},"properties":{"height":2.81}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757200.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757200.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757200.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757200.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757200.0,-1.75]},"properties":{"height":-1.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6757200.0,-1.75]},"properties":{"height":-1.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6757200.0,-1.75]},"properties":{"height":-1.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757200.0,-1.76]},"properties":{"height":-1.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757275.0,13.6]},"properties":{"height":13.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757275.0,14.27]},"properties":{"height":14.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757275.0,15.31]},"properties":{"height":15.31}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757275.0,14.64]},"properties":{"height":14.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757275.0,12.61]},"properties":{"height":12.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757275.0,10.56]},"properties":{"height":10.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757275.0,8.77]},"properties":{"height":8.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757275.0,6.92]},"properties":{"height":6.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757275.0,5.4]},"properties":{"height":5.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757275.0,4.75]},"properties":{"height":4.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757275.0,3.54]},"properties":{"height":3.54}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757275.0,3.96]},"properties":{"height":3.96}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757275.0,3.92]},"properties":{"height":3.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757275.0,4.19]},"properties":{"height":4.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757275.0,4.19]},"properties":{"height":4.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757275.0,3.93]},"properties":{"height":3.93}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757275.0,3.38]},"properties":{"height":3.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757275.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757275.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757275.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757275.0,4.69]},"properties":{"height":4.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757275.0,5.26]},"properties":{"height":5.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757275.0,-1.15]},"properties":{"height":-1.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757275.0,-1.73]},"properties":{"height":-1.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6757275.0,-1.74]},"properties":{"height":-1.74}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6757275.0,-1.74]},"properties":{"height":-1.74}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757275.0,0.23]},"properties":{"height":0.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757350.0,11.94]},"properties":{"height":11.94}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757350.0,13.03]},"properties":{"height":13.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757350.0,13.31]},"properties":{"height":13.31}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757350.0,12.4]},"properties":{"height":12.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757350.0,11.42]},"properties":{"height":11.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757350.0,10.14]},"properties":{"height":10.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757350.0,7.98]},"properties":{"height":7.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757350.0,5.3]},"properties":{"height":5.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757350.0,5.07]},"properties":{"height":5.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757350.0,4.0]},"properties":{"height":4.0}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757350.0,4.19]},"properties":{"height":4.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757350.0,3.52]},"properties":{"height":3.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757350.0,3.77]},"properties":{"height":3.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757350.0,4.5]},"properties":{"height":4.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757350.0,3.84]},"properties":{"height":3.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757350.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757350.0,1.23]},"properties":{"height":1.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757350.0,3.53]},"properties":{"height":3.53}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757350.0,4.0]},"properties":{"height":4.0}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757350.0,4.63]},"properties":{"height":4.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757350.0,5.51]},"properties":{"height":5.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757350.0,5.42]},"properties":{"height":5.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757350.0,3.98]},"properties":{"height":3.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757350.0,-1.71]},"properties":{"height":-1.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6757350.0,-1.72]},"properties":{"height":-1.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6757350.0,-1.72]},"properties":{"height":-1.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757350.0,4.01]},"properties":{"height":4.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757425.0,9.65]},"properties":{"height":9.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757425.0,11.15]},"properties":{"height":11.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757425.0,11.57]},"properties":{"height":11.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757425.0,10.92]},"properties":{"height":10.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757425.0,10.48]},"properties":{"height":10.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757425.0,10.14]},"properties":{"height":10.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757425.0,7.8]},"properties":{"height":7.8}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757425.0,5.07]},"properties":{"height":5.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757425.0,5.32]},"properties":{"height":5.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757425.0,3.78]},"properties":{"height":3.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757425.0,3.51]},"properties":{"height":3.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757425.0,3.75]},"properties":{"height":3.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757425.0,3.7]},"properties":{"height":3.7}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757425.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757425.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757425.0,4.32]},"properties":{"height":4.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757425.0,6.11]},"properties":{"height":6.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757425.0,11.98]},"properties":{"height":11.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757425.0,13.85]},"properties":{"height":13.85}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757425.0,11.26]},"properties":{"height":11.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757425.0,5.88]},"properties":{"height":5.88}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757425.0,6.0]},"properties":{"height":6.0}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757425.0,-1.69]},"properties":{"height":-1.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757425.0,-1.69]},"properties":{"height":-1.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6757425.0,-1.7]},"properties":{"height":-1.7}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6757425.0,-1.7]},"properties":{"height":-1.7}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757425.0,4.07]},"properties":{"height":4.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757500.0,8.46]},"properties":{"height":8.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757500.0,7.8]},"properties":{"height":7.8}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757500.0,8.86]},"properties":{"height":8.86}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757500.0,9.73]},"properties":{"height":9.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757500.0,10.26]},"properties":{"height":10.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757500.0,9.43]},"properties":{"height":9.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757500.0,9.44]},"properties":{"height":9.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757500.0,7.4]},"properties":{"height":7.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757500.0,4.84]},"properties":{"height":4.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757500.0,4.15]},"properties":{"height":4.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757500.0,4.01]},"properties":{"height":4.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757500.0,3.85]},"properties":{"height":3.85}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757500.0,-1.79]},"properties":{"height":-1.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757500.0,3.59]},"properties":{"height":3.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757500.0,4.51]},"properties":{"height":4.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757500.0,8.47]},"properties":{"height":8.47}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757500.0,10.06]},"properties":{"height":10.06}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757500.0,14.1]},"properties":{"height":14.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757500.0,13.72]},"properties":{"height":13.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757500.0,14.36]},"properties":{"height":14.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757500.0,7.78]},"properties":{"height":7.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757500.0,-1.65]},"properties":{"height":-1.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757500.0,-1.66]},"properties":{"height":-1.66}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757500.0,-1.66]},"properties":{"height":-1.66}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6757500.0,-1.67]},"properties":{"height":-1.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6757500.0,-0.07]},"properties":{"height":-0.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757500.0,4.55]},"properties":{"height":4.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757575.0,5.38]},"properties":{"height":5.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757575.0,5.32]},"properties":{"height":5.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757575.0,6.19]},"properties":{"height":6.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757575.0,7.4]},"properties":{"height":7.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757575.0,8.65]},"properties":{"height":8.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757575.0,8.56]},"properties":{"height":8.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757575.0,8.02]},"properties":{"height":8.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757575.0,6.3]},"properties":{"height":6.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757575.0,6.11]},"properties":{"height":6.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757575.0,4.05]},"properties":{"height":4.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757575.0,3.78]},"properties":{"height":3.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757575.0,4.36]},"properties":{"height":4.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757575.0,4.26]},"properties":{"height":4.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757575.0,3.58]},"properties":{"height":3.58}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757575.0,8.05]},"properties":{"height":8.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757575.0,10.02]},"properties":{"height":10.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757575.0,13.39]},"properties":{"height":13.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757575.0,13.32]},"properties":{"height":13.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757575.0,11.43]},"properties":{"height":11.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757575.0,7.23]},"properties":{"height":7.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757575.0,5.65]},"properties":{"height":5.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757575.0,-1.64]},"properties":{"height":-1.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757575.0,-1.64]},"properties":{"height":-1.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757575.0,-1.64]},"properties":{"height":-1.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6757575.0,-1.65]},"properties":{"height":-1.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6757575.0,3.9]},"properties":{"height":3.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757575.0,4.86]},"properties":{"height":4.86}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757650.0,6.94]},"properties":{"height":6.94}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757650.0,4.03]},"properties":{"height":4.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757650.0,4.84]},"properties":{"height":4.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757650.0,7.28]},"properties":{"height":7.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757650.0,7.03]},"properties":{"height":7.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757650.0,8.02]},"properties":{"height":8.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757650.0,6.63]},"properties":{"height":6.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757650.0,5.82]},"properties":{"height":5.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757650.0,4.48]},"properties":{"height":4.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757650.0,4.63]},"properties":{"height":4.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757650.0,4.17]},"properties":{"height":4.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757650.0,4.26]},"properties":{"height":4.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757650.0,5.69]},"properties":{"height":5.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757650.0,7.98]},"properties":{"height":7.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757650.0,11.14]},"properties":{"height":11.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757650.0,12.77]},"properties":{"height":12.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757650.0,14.39]},"properties":{"height":14.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757650.0,11.39]},"properties":{"height":11.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757650.0,10.89]},"properties":{"height":10.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757650.0,7.42]},"properties":{"height":7.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757650.0,5.55]},"properties":{"height":5.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757650.0,2.83]},"properties":{"height":2.83}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757650.0,-1.63]},"properties":{"height":-1.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757650.0,-1.63]},"properties":{"height":-1.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6757650.0,-1.63]},"properties":{"height":-1.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6757650.0,3.5]},"properties":{"height":3.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757650.0,5.13]},"properties":{"height":5.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757725.0,4.51]},"properties":{"height":4.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757725.0,4.25]},"properties":{"height":4.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757725.0,5.05]},"properties":{"height":5.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757725.0,5.67]},"properties":{"height":5.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757725.0,6.55]},"properties":{"height":6.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757725.0,6.38]},"properties":{"height":6.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757725.0,5.61]},"properties":{"height":5.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757725.0,4.55]},"properties":{"height":4.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757725.0,5.76]},"properties":{"height":5.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757725.0,4.48]},"properties":{"height":4.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757725.0,4.94]},"properties":{"height":4.94}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757725.0,6.15]},"properties":{"height":6.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757725.0,7.53]},"properties":{"height":7.53}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757725.0,9.77]},"properties":{"height":9.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757725.0,12.52]},"properties":{"height":12.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757725.0,13.52]},"properties":{"height":13.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757725.0,14.5]},"properties":{"height":14.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757725.0,9.55]},"properties":{"height":9.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757725.0,9.06]},"properties":{"height":9.06}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757725.0,7.8]},"properties":{"height":7.8}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757725.0,5.44]},"properties":{"height":5.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757725.0,4.82]},"properties":{"height":4.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757725.0,-1.62]},"properties":{"height":-1.62}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757725.0,-1.62]},"properties":{"height":-1.62}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6757725.0,-1.62]},"properties":{"height":-1.62}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6757725.0,3.65]},"properties":{"height":3.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757725.0,4.9]},"properties":{"height":4.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757800.0,5.28]},"properties":{"height":5.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757800.0,5.63]},"properties":{"height":5.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757800.0,6.05]},"properties":{"height":6.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757800.0,6.5]},"properties":{"height":6.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757800.0,6.09]},"properties":{"height":6.09}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757800.0,7.71]},"properties":{"height":7.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757800.0,4.46]},"properties":{"height":4.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757800.0,4.57]},"properties":{"height":4.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757800.0,5.13]},"properties":{"height":5.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757800.0,4.19]},"properties":{"height":4.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757800.0,8.02]},"properties":{"height":8.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757800.0,8.34]},"properties":{"height":8.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757800.0,10.26]},"properties":{"height":10.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757800.0,10.8]},"properties":{"height":10.8}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757800.0,12.77]},"properties":{"height":12.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757800.0,12.28]},"properties":{"height":12.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757800.0,11.56]},"properties":{"height":11.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757800.0,9.67]},"properties":{"height":9.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757800.0,8.14]},"properties":{"height":8.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757800.0,6.63]},"properties":{"height":6.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757800.0,5.59]},"properties":{"height":5.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757800.0,5.05]},"properties":{"height":5.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757800.0,-1.61]},"properties":{"height":-1.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757800.0,-1.61]},"properties":{"height":-1.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6757800.0,-1.61]},"properties":{"height":-1.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6757800.0,3.54]},"properties":{"height":3.54}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757800.0,4.25]},"properties":{"height":4.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757875.0,7.61]},"properties":{"height":7.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757875.0,6.51]},"properties":{"height":6.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757875.0,7.05]},"properties":{"height":7.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757875.0,8.92]},"properties":{"height":8.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757875.0,7.3]},"properties":{"height":7.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757875.0,9.01]},"properties":{"height":9.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757875.0,4.82]},"properties":{"height":4.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757875.0,7.32]},"properties":{"height":7.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757875.0,7.3]},"properties":{"height":7.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757875.0,8.21]},"properties":{"height":8.21}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757875.0,9.1]},"properties":{"height":9.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757875.0,10.31]},"properties":{"height":10.31}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757875.0,11.06]},"properties":{"height":11.06}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757875.0,10.96]},"properties":{"height":10.96}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757875.0,10.69]},"properties":{"height":10.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757875.0,9.52]},"properties":{"height":9.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757875.0,8.52]},"properties":{"height":8.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757875.0,8.27]},"properties":{"height":8.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757875.0,6.46]},"properties":{"height":6.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757875.0,4.92]},"properties":{"height":4.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757875.0,4.84]},"properties":{"height":4.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757875.0,3.84]},"properties":{"height":3.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757875.0,-1.59]},"properties":{"height":-1.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757875.0,-1.6]},"properties":{"height":-1.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6757875.0,-1.6]},"properties":{"height":-1.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6757875.0,3.74]},"properties":{"height":3.74}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757875.0,4.28]},"properties":{"height":4.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6757950.0,10.31]},"properties":{"height":10.31}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6757950.0,10.9]},"properties":{"height":10.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6757950.0,12.07]},"properties":{"height":12.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6757950.0,7.07]},"properties":{"height":7.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6757950.0,7.09]},"properties":{"height":7.09}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6757950.0,8.68]},"properties":{"height":8.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6757950.0,5.05]},"properties":{"height":5.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6757950.0,8.34]},"properties":{"height":8.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6757950.0,9.34]},"properties":{"height":9.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6757950.0,10.15]},"properties":{"height":10.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6757950.0,10.39]},"properties":{"height":10.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6757950.0,11.06]},"properties":{"height":11.06}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6757950.0,11.02]},"properties":{"height":11.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6757950.0,9.14]},"properties":{"height":9.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6757950.0,7.48]},"properties":{"height":7.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6757950.0,6.65]},"properties":{"height":6.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6757950.0,5.61]},"properties":{"height":5.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6757950.0,4.82]},"properties":{"height":4.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6757950.0,3.89]},"properties":{"height":3.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6757950.0,4.17]},"properties":{"height":4.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6757950.0,4.07]},"properties":{"height":4.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6757950.0,4.19]},"properties":{"height":4.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6757950.0,-1.58]},"properties":{"height":-1.58}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6757950.0,-1.58]},"properties":{"height":-1.58}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6757950.0,-1.58]},"properties":{"height":-1.58}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6757950.0,3.86]},"properties":{"height":3.86}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6757950.0,4.13]},"properties":{"height":4.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758025.0,13.46]},"properties":{"height":13.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758025.0,13.35]},"properties":{"height":13.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758025.0,13.4]},"properties":{"height":13.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758025.0,10.81]},"properties":{"height":10.81}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758025.0,9.06]},"properties":{"height":9.06}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758025.0,9.03]},"properties":{"height":9.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758025.0,6.44]},"properties":{"height":6.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758025.0,9.68]},"properties":{"height":9.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758025.0,13.25]},"properties":{"height":13.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758025.0,13.19]},"properties":{"height":13.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758025.0,12.31]},"properties":{"height":12.31}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758025.0,12.14]},"properties":{"height":12.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758025.0,10.86]},"properties":{"height":10.86}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758025.0,7.92]},"properties":{"height":7.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758025.0,5.09]},"properties":{"height":5.09}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758025.0,5.44]},"properties":{"height":5.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758025.0,4.34]},"properties":{"height":4.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758025.0,3.66]},"properties":{"height":3.66}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758025.0,3.73]},"properties":{"height":3.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758025.0,3.58]},"properties":{"height":3.58}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758025.0,3.83]},"properties":{"height":3.83}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758025.0,4.13]},"properties":{"height":4.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758025.0,-1.57]},"properties":{"height":-1.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758025.0,-1.57]},"properties":{"height":-1.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758025.0,-1.57]},"properties":{"height":-1.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758025.0,3.76]},"properties":{"height":3.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758025.0,3.79]},"properties":{"height":3.79}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758100.0,16.379999]},"properties":{"height":16.379999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758100.0,16.309999]},"properties":{"height":16.309999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758100.0,13.39]},"properties":{"height":13.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758100.0,13.6]},"properties":{"height":13.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758100.0,11.56]},"properties":{"height":11.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758100.0,8.35]},"properties":{"height":8.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758100.0,9.85]},"properties":{"height":9.85}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758100.0,11.1]},"properties":{"height":11.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758100.0,12.25]},"properties":{"height":12.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758100.0,14.09]},"properties":{"height":14.09}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758100.0,13.31]},"properties":{"height":13.31}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758100.0,12.68]},"properties":{"height":12.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758100.0,11.39]},"properties":{"height":11.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758100.0,9.36]},"properties":{"height":9.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758100.0,4.21]},"properties":{"height":4.21}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758100.0,5.25]},"properties":{"height":5.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758100.0,4.78]},"properties":{"height":4.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758100.0,4.05]},"properties":{"height":4.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758100.0,3.61]},"properties":{"height":3.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758100.0,3.71]},"properties":{"height":3.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758100.0,3.35]},"properties":{"height":3.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758100.0,-0.68]},"properties":{"height":-0.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758100.0,-1.54]},"properties":{"height":-1.54}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758100.0,-1.54]},"properties":{"height":-1.54}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758100.0,-0.62]},"properties":{"height":-0.62}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758100.0,3.84]},"properties":{"height":3.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758100.0,3.99]},"properties":{"height":3.99}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758175.0,18.559999]},"properties":{"height":18.559999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758175.0,17.790001]},"properties":{"height":17.790001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758175.0,15.89]},"properties":{"height":15.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758175.0,12.4]},"properties":{"height":12.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758175.0,10.39]},"properties":{"height":10.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758175.0,9.11]},"properties":{"height":9.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758175.0,10.22]},"properties":{"height":10.22}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758175.0,12.3]},"properties":{"height":12.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758175.0,13.27]},"properties":{"height":13.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758175.0,13.9]},"properties":{"height":13.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758175.0,14.05]},"properties":{"height":14.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758175.0,14.02]},"properties":{"height":14.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758175.0,11.89]},"properties":{"height":11.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758175.0,8.34]},"properties":{"height":8.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758175.0,6.17]},"properties":{"height":6.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758175.0,5.44]},"properties":{"height":5.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758175.0,5.15]},"properties":{"height":5.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758175.0,5.13]},"properties":{"height":5.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758175.0,4.82]},"properties":{"height":4.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758175.0,4.44]},"properties":{"height":4.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758175.0,3.35]},"properties":{"height":3.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758175.0,-0.43]},"properties":{"height":-0.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758175.0,-1.53]},"properties":{"height":-1.53}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758175.0,-1.53]},"properties":{"height":-1.53}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758175.0,0.6]},"properties":{"height":0.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758175.0,5.5]},"properties":{"height":5.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758175.0,5.73]},"properties":{"height":5.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758250.0,19.200001]},"properties":{"height":19.200001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758250.0,18.15]},"properties":{"height":18.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758250.0,15.67]},"properties":{"height":15.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758250.0,12.93]},"properties":{"height":12.93}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758250.0,11.02]},"properties":{"height":11.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758250.0,9.64]},"properties":{"height":9.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758250.0,10.75]},"properties":{"height":10.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758250.0,13.71]},"properties":{"height":13.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758250.0,14.69]},"properties":{"height":14.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758250.0,15.84]},"properties":{"height":15.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758250.0,14.51]},"properties":{"height":14.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758250.0,13.35]},"properties":{"height":13.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758250.0,11.72]},"properties":{"height":11.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758250.0,9.77]},"properties":{"height":9.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758250.0,8.42]},"properties":{"height":8.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758250.0,5.09]},"properties":{"height":5.09}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758250.0,5.42]},"properties":{"height":5.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758250.0,5.82]},"properties":{"height":5.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758250.0,5.36]},"properties":{"height":5.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758250.0,3.99]},"properties":{"height":3.99}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758250.0,3.56]},"properties":{"height":3.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758250.0,-0.94]},"properties":{"height":-0.94}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758250.0,-1.51]},"properties":{"height":-1.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758250.0,-1.52]},"properties":{"height":-1.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758250.0,-0.11]},"properties":{"height":-0.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758250.0,5.76]},"properties":{"height":5.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758250.0,11.43]},"properties":{"height":11.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758325.0,17.469999]},"properties":{"height":17.469999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758325.0,18.200001]},"properties":{"height":18.200001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758325.0,16.790001]},"properties":{"height":16.790001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758325.0,15.89]},"properties":{"height":15.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758325.0,12.72]},"properties":{"height":12.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758325.0,9.11]},"properties":{"height":9.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758325.0,10.25]},"properties":{"height":10.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758325.0,12.52]},"properties":{"height":12.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758325.0,15.57]},"properties":{"height":15.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758325.0,16.799999]},"properties":{"height":16.799999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758325.0,14.11]},"properties":{"height":14.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758325.0,12.68]},"properties":{"height":12.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758325.0,11.09]},"properties":{"height":11.09}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758325.0,11.23]},"properties":{"height":11.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758325.0,7.9]},"properties":{"height":7.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758325.0,5.4]},"properties":{"height":5.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758325.0,4.48]},"properties":{"height":4.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758325.0,3.72]},"properties":{"height":3.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758325.0,3.78]},"properties":{"height":3.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758325.0,4.07]},"properties":{"height":4.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758325.0,3.64]},"properties":{"height":3.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758325.0,-1.5]},"properties":{"height":-1.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758325.0,-1.5]},"properties":{"height":-1.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758325.0,-1.5]},"properties":{"height":-1.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758325.0,2.96]},"properties":{"height":2.96}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758325.0,5.84]},"properties":{"height":5.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758325.0,11.52]},"properties":{"height":11.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758400.0,14.85]},"properties":{"height":14.85}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758400.0,15.14]},"properties":{"height":15.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758400.0,15.46]},"properties":{"height":15.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758400.0,14.72]},"properties":{"height":14.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758400.0,11.96]},"properties":{"height":11.96}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758400.0,10.52]},"properties":{"height":10.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758400.0,10.55]},"properties":{"height":10.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758400.0,13.17]},"properties":{"height":13.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758400.0,16.25]},"properties":{"height":16.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758400.0,17.290001]},"properties":{"height":17.290001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758400.0,14.15]},"properties":{"height":14.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758400.0,11.72]},"properties":{"height":11.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758400.0,10.11]},"properties":{"height":10.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758400.0,4.3]},"properties":{"height":4.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758400.0,6.8]},"properties":{"height":6.8}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758400.0,6.11]},"properties":{"height":6.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758400.0,5.65]},"properties":{"height":5.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758400.0,4.03]},"properties":{"height":4.03}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758400.0,3.82]},"properties":{"height":3.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758400.0,4.38]},"properties":{"height":4.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758400.0,3.82]},"properties":{"height":3.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758400.0,-1.5]},"properties":{"height":-1.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758400.0,-1.5]},"properties":{"height":-1.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758400.0,5.21]},"properties":{"height":5.21}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758400.0,5.21]},"properties":{"height":5.21}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758400.0,10.97]},"properties":{"height":10.97}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758400.0,11.64]},"properties":{"height":11.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758475.0,14.93]},"properties":{"height":14.93}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758475.0,13.98]},"properties":{"height":13.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758475.0,12.19]},"properties":{"height":12.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758475.0,11.47]},"properties":{"height":11.47}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758475.0,11.36]},"properties":{"height":11.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758475.0,12.1]},"properties":{"height":12.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758475.0,14.23]},"properties":{"height":14.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758475.0,16.42]},"properties":{"height":16.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758475.0,17.139999]},"properties":{"height":17.139999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758475.0,15.77]},"properties":{"height":15.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758475.0,14.78]},"properties":{"height":14.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758475.0,12.44]},"properties":{"height":12.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758475.0,9.75]},"properties":{"height":9.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758475.0,6.55]},"properties":{"height":6.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758475.0,5.98]},"properties":{"height":5.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758475.0,5.9]},"properties":{"height":5.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758475.0,4.67]},"properties":{"height":4.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758475.0,4.3]},"properties":{"height":4.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758475.0,4.17]},"properties":{"height":4.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758475.0,4.38]},"properties":{"height":4.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758475.0,1.35]},"properties":{"height":1.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758475.0,-1.48]},"properties":{"height":-1.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758475.0,-1.48]},"properties":{"height":-1.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758475.0,5.21]},"properties":{"height":5.21}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758475.0,5.23]},"properties":{"height":5.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758475.0,11.17]},"properties":{"height":11.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758475.0,11.56]},"properties":{"height":11.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758550.0,16.01]},"properties":{"height":16.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758550.0,15.72]},"properties":{"height":15.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758550.0,15.35]},"properties":{"height":15.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758550.0,15.36]},"properties":{"height":15.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758550.0,15.43]},"properties":{"height":15.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758550.0,15.5]},"properties":{"height":15.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758550.0,15.6]},"properties":{"height":15.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758550.0,15.67]},"properties":{"height":15.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758550.0,15.76]},"properties":{"height":15.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758550.0,15.34]},"properties":{"height":15.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758550.0,14.59]},"properties":{"height":14.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758550.0,12.68]},"properties":{"height":12.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758550.0,9.71]},"properties":{"height":9.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758550.0,9.78]},"properties":{"height":9.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758550.0,11.05]},"properties":{"height":11.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758550.0,10.69]},"properties":{"height":10.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758550.0,10.21]},"properties":{"height":10.21}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758550.0,5.15]},"properties":{"height":5.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758550.0,7.57]},"properties":{"height":7.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758550.0,5.36]},"properties":{"height":5.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758550.0,-1.47]},"properties":{"height":-1.47}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758550.0,-1.47]},"properties":{"height":-1.47}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758550.0,-1.47]},"properties":{"height":-1.47}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758550.0,5.13]},"properties":{"height":5.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758550.0,5.19]},"properties":{"height":5.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758550.0,11.15]},"properties":{"height":11.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758550.0,11.48]},"properties":{"height":11.48}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758625.0,16.969999]},"properties":{"height":16.969999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758625.0,13.78]},"properties":{"height":13.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758625.0,15.35]},"properties":{"height":15.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758625.0,15.32]},"properties":{"height":15.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758625.0,15.47]},"properties":{"height":15.47}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758625.0,16.110001]},"properties":{"height":16.110001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758625.0,15.36]},"properties":{"height":15.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758625.0,15.56]},"properties":{"height":15.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758625.0,15.6]},"properties":{"height":15.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758625.0,14.68]},"properties":{"height":14.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758625.0,14.78]},"properties":{"height":14.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758625.0,13.39]},"properties":{"height":13.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758625.0,11.73]},"properties":{"height":11.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758625.0,12.14]},"properties":{"height":12.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758625.0,12.92]},"properties":{"height":12.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758625.0,12.64]},"properties":{"height":12.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758625.0,10.67]},"properties":{"height":10.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758625.0,8.25]},"properties":{"height":8.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758625.0,6.84]},"properties":{"height":6.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758625.0,4.69]},"properties":{"height":4.69}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758625.0,-1.45]},"properties":{"height":-1.45}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758625.0,-1.45]},"properties":{"height":-1.45}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758625.0,-1.46]},"properties":{"height":-1.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758625.0,4.42]},"properties":{"height":4.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758625.0,4.9]},"properties":{"height":4.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758625.0,9.75]},"properties":{"height":9.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758625.0,11.68]},"properties":{"height":11.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758700.0,18.0]},"properties":{"height":18.0}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758700.0,15.68]},"properties":{"height":15.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758700.0,14.25]},"properties":{"height":14.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758700.0,13.36]},"properties":{"height":13.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758700.0,13.94]},"properties":{"height":13.94}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758700.0,14.98]},"properties":{"height":14.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758700.0,16.879999]},"properties":{"height":16.879999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758700.0,15.67]},"properties":{"height":15.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758700.0,15.76]},"properties":{"height":15.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758700.0,15.43]},"properties":{"height":15.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758700.0,16.030001]},"properties":{"height":16.030001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758700.0,15.5]},"properties":{"height":15.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758700.0,15.25]},"properties":{"height":15.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758700.0,13.14]},"properties":{"height":13.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758700.0,12.52]},"properties":{"height":12.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758700.0,11.56]},"properties":{"height":11.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758700.0,10.18]},"properties":{"height":10.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758700.0,9.0]},"properties":{"height":9.0}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758700.0,4.21]},"properties":{"height":4.21}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758700.0,3.58]},"properties":{"height":3.58}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758700.0,-1.44]},"properties":{"height":-1.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758700.0,-1.44]},"properties":{"height":-1.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758700.0,-1.44]},"properties":{"height":-1.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758700.0,4.26]},"properties":{"height":4.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758700.0,4.71]},"properties":{"height":4.71}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758700.0,5.19]},"properties":{"height":5.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758700.0,5.15]},"properties":{"height":5.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758775.0,23.450001]},"properties":{"height":23.450001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758775.0,21.0]},"properties":{"height":21.0}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758775.0,19.25]},"properties":{"height":19.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758775.0,20.280001]},"properties":{"height":20.280001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758775.0,18.68]},"properties":{"height":18.68}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758775.0,18.42]},"properties":{"height":18.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758775.0,22.01]},"properties":{"height":22.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758775.0,22.370001]},"properties":{"height":22.370001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758775.0,20.639999]},"properties":{"height":20.639999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758775.0,18.01]},"properties":{"height":18.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758775.0,16.610001]},"properties":{"height":16.610001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758775.0,14.31]},"properties":{"height":14.31}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758775.0,12.78]},"properties":{"height":12.78}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758775.0,12.06]},"properties":{"height":12.06}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758775.0,12.85]},"properties":{"height":12.85}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758775.0,12.07]},"properties":{"height":12.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758775.0,10.1]},"properties":{"height":10.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758775.0,8.22]},"properties":{"height":8.22}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758775.0,9.26]},"properties":{"height":9.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758775.0,5.57]},"properties":{"height":5.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758775.0,-1.42]},"properties":{"height":-1.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758775.0,-1.42]},"properties":{"height":-1.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758775.0,-1.42]},"properties":{"height":-1.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758775.0,6.82]},"properties":{"height":6.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758775.0,9.19]},"properties":{"height":9.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758775.0,10.46]},"properties":{"height":10.46}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758775.0,9.93]},"properties":{"height":9.93}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758850.0,29.030001]},"properties":{"height":29.030001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758850.0,26.07]},"properties":{"height":26.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758850.0,28.51]},"properties":{"height":28.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758850.0,26.25]},"properties":{"height":26.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758850.0,23.629999]},"properties":{"height":23.629999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758850.0,22.84]},"properties":{"height":22.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758850.0,22.389999]},"properties":{"height":22.389999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758850.0,21.42]},"properties":{"height":21.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758850.0,19.370001]},"properties":{"height":19.370001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758850.0,15.01]},"properties":{"height":15.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758850.0,14.35]},"properties":{"height":14.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758850.0,13.27]},"properties":{"height":13.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758850.0,9.21]},"properties":{"height":9.21}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758850.0,8.52]},"properties":{"height":8.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758850.0,11.14]},"properties":{"height":11.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758850.0,10.84]},"properties":{"height":10.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758850.0,7.11]},"properties":{"height":7.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758850.0,5.65]},"properties":{"height":5.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758850.0,5.76]},"properties":{"height":5.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758850.0,-0.05]},"properties":{"height":-0.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758850.0,-1.4]},"properties":{"height":-1.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758850.0,-1.4]},"properties":{"height":-1.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758850.0,-1.39]},"properties":{"height":-1.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758850.0,6.11]},"properties":{"height":6.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758850.0,8.72]},"properties":{"height":8.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758850.0,13.85]},"properties":{"height":13.85}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758850.0,11.22]},"properties":{"height":11.22}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6758925.0,32.740002]},"properties":{"height":32.740002}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6758925.0,30.870001]},"properties":{"height":30.870001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6758925.0,29.75]},"properties":{"height":29.75}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6758925.0,27.059999]},"properties":{"height":27.059999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6758925.0,24.5]},"properties":{"height":24.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6758925.0,21.32]},"properties":{"height":21.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6758925.0,17.76]},"properties":{"height":17.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6758925.0,16.25]},"properties":{"height":16.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6758925.0,13.05]},"properties":{"height":13.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6758925.0,11.14]},"properties":{"height":11.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6758925.0,10.27]},"properties":{"height":10.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6758925.0,5.92]},"properties":{"height":5.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6758925.0,5.94]},"properties":{"height":5.94}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6758925.0,5.76]},"properties":{"height":5.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6758925.0,7.01]},"properties":{"height":7.01}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6758925.0,8.28]},"properties":{"height":8.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6758925.0,6.61]},"properties":{"height":6.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6758925.0,4.88]},"properties":{"height":4.88}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6758925.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6758925.0,-1.39]},"properties":{"height":-1.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6758925.0,-1.39]},"properties":{"height":-1.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6758925.0,-1.39]},"properties":{"height":-1.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6758925.0,3.39]},"properties":{"height":3.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6758925.0,3.89]},"properties":{"height":3.89}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6758925.0,5.57]},"properties":{"height":5.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6758925.0,8.56]},"properties":{"height":8.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6758925.0,11.51]},"properties":{"height":11.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6759000.0,33.200001]},"properties":{"height":33.200001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6759000.0,31.559999]},"properties":{"height":31.559999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6759000.0,30.139999]},"properties":{"height":30.139999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6759000.0,26.200001]},"properties":{"height":26.200001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6759000.0,23.200001]},"properties":{"height":23.200001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6759000.0,19.950001]},"properties":{"height":19.950001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6759000.0,18.18]},"properties":{"height":18.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6759000.0,16.6]},"properties":{"height":16.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6759000.0,9.15]},"properties":{"height":9.15}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6759000.0,7.05]},"properties":{"height":7.05}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6759000.0,7.86]},"properties":{"height":7.86}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6759000.0,4.65]},"properties":{"height":4.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6759000.0,1.52]},"properties":{"height":1.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6759000.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6759000.0,0.07]},"properties":{"height":0.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6759000.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6759000.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6759000.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6759000.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6759000.0,-1.39]},"properties":{"height":-1.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6759000.0,-1.39]},"properties":{"height":-1.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6759000.0,-0.98]},"properties":{"height":-0.98}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6759000.0,3.18]},"properties":{"height":3.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6759000.0,3.08]},"properties":{"height":3.08}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6759000.0,3.91]},"properties":{"height":3.91}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6759000.0,6.84]},"properties":{"height":6.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6759000.0,11.64]},"properties":{"height":11.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6759075.0,31.139999]},"properties":{"height":31.139999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6759075.0,30.299999]},"properties":{"height":30.299999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6759075.0,28.85]},"properties":{"height":28.85}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6759075.0,24.879999]},"properties":{"height":24.879999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6759075.0,21.639999]},"properties":{"height":21.639999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6759075.0,18.790001]},"properties":{"height":18.790001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6759075.0,17.52]},"properties":{"height":17.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6759075.0,13.77]},"properties":{"height":13.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6759075.0,8.64]},"properties":{"height":8.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6759075.0,3.82]},"properties":{"height":3.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6759075.0,3.77]},"properties":{"height":3.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6759075.0,4.23]},"properties":{"height":4.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6759075.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6759075.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6759075.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6759075.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6759075.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6759075.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6759075.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6759075.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6759075.0,-1.39]},"properties":{"height":-1.39}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6759075.0,3.43]},"properties":{"height":3.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6759075.0,3.2]},"properties":{"height":3.2}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6759075.0,1.32]},"properties":{"height":1.32}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6759075.0,5.96]},"properties":{"height":5.96}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6759075.0,9.55]},"properties":{"height":9.55}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6759075.0,11.92]},"properties":{"height":11.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6759150.0,26.450001]},"properties":{"height":26.450001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6759150.0,26.459999]},"properties":{"height":26.459999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6759150.0,26.52]},"properties":{"height":26.52}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6759150.0,22.360001]},"properties":{"height":22.360001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6759150.0,17.02]},"properties":{"height":17.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6759150.0,12.27]},"properties":{"height":12.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6759150.0,15.72]},"properties":{"height":15.72}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6759150.0,15.1]},"properties":{"height":15.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6759150.0,10.43]},"properties":{"height":10.43}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6759150.0,10.34]},"properties":{"height":10.34}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6759150.0,11.19]},"properties":{"height":11.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6759150.0,0.56]},"properties":{"height":0.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6759150.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6759150.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6759150.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6759150.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6759150.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6759150.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6759150.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6759150.0,-0.18]},"properties":{"height":-0.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6759150.0,-1.4]},"properties":{"height":-1.4}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6759150.0,3.57]},"properties":{"height":3.57}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6759150.0,1.14]},"properties":{"height":1.14}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6759150.0,6.19]},"properties":{"height":6.19}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6759150.0,7.51]},"properties":{"height":7.51}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6759150.0,7.73]},"properties":{"height":7.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6759150.0,6.59]},"properties":{"height":6.59}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6759225.0,21.73]},"properties":{"height":21.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6759225.0,22.02]},"properties":{"height":22.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6759225.0,23.799999]},"properties":{"height":23.799999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6759225.0,20.110001]},"properties":{"height":20.110001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6759225.0,13.27]},"properties":{"height":13.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6759225.0,8.47]},"properties":{"height":8.47}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6759225.0,11.1]},"properties":{"height":11.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6759225.0,12.38]},"properties":{"height":12.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6759225.0,7.84]},"properties":{"height":7.84}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6759225.0,10.18]},"properties":{"height":10.18}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6759225.0,3.44]},"properties":{"height":3.44}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6759225.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6759225.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6759225.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6759225.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6759225.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6759225.0,-1.38]},"properties":{"height":-1.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6759225.0,-0.23]},"properties":{"height":-0.23}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6759225.0,0.37]},"properties":{"height":0.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6759225.0,0.66]},"properties":{"height":0.66}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6759225.0,4.42]},"properties":{"height":4.42}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6759225.0,-0.25]},"properties":{"height":-0.25}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6759225.0,2.17]},"properties":{"height":2.17}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6759225.0,4.09]},"properties":{"height":4.09}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6759225.0,4.3]},"properties":{"height":4.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6759225.0,2.88]},"properties":{"height":2.88}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6759225.0,4.88]},"properties":{"height":4.88}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6759300.0,18.389999]},"properties":{"height":18.389999}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6759300.0,19.02]},"properties":{"height":19.02}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6759300.0,20.700001]},"properties":{"height":20.700001}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6759300.0,18.6]},"properties":{"height":18.6}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6759300.0,12.56]},"properties":{"height":12.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6759300.0,4.38]},"properties":{"height":4.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6759300.0,4.82]},"properties":{"height":4.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6759300.0,5.3]},"properties":{"height":5.3}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6759300.0,3.41]},"properties":{"height":3.41}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6759300.0,0.36]},"properties":{"height":0.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6759300.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6759300.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6759300.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6759300.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6759300.0,-0.76]},"properties":{"height":-0.76}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6759300.0,-0.1]},"properties":{"height":-0.1}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6759300.0,0.28]},"properties":{"height":0.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6759300.0,0.49]},"properties":{"height":0.49}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6759300.0,0.82]},"properties":{"height":0.82}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6759300.0,4.73]},"properties":{"height":4.73}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6759300.0,6.07]},"properties":{"height":6.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6759300.0,3.99]},"properties":{"height":3.99}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6759300.0,-0.21]},"properties":{"height":-0.21}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6759300.0,2.91]},"properties":{"height":2.91}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6759300.0,2.61]},"properties":{"height":2.61}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6759300.0,3.67]},"properties":{"height":3.67}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6759300.0,5.63]},"properties":{"height":5.63}},{"type":"Feature","geometry":{"type":"Point","coordinates":[222975.0,6759375.0,15.9]},"properties":{"height":15.9}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223050.0,6759375.0,15.28]},"properties":{"height":15.28}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223125.0,6759375.0,14.77]},"properties":{"height":14.77}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223200.0,6759375.0,15.06]},"properties":{"height":15.06}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223275.0,6759375.0,10.35]},"properties":{"height":10.35}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223350.0,6759375.0,5.13]},"properties":{"height":5.13}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223425.0,6759375.0,5.36]},"properties":{"height":5.36}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223500.0,6759375.0,4.26]},"properties":{"height":4.26}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223575.0,6759375.0,3.5]},"properties":{"height":3.5}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223650.0,6759375.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223725.0,6759375.0,-1.37]},"properties":{"height":-1.37}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223800.0,6759375.0,3.21]},"properties":{"height":3.21}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223875.0,6759375.0,3.97]},"properties":{"height":3.97}},{"type":"Feature","geometry":{"type":"Point","coordinates":[223950.0,6759375.0,0.94]},"properties":{"height":0.94}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224025.0,6759375.0,0.81]},"properties":{"height":0.81}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224100.0,6759375.0,0.62]},"properties":{"height":0.62}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224175.0,6759375.0,0.64]},"properties":{"height":0.64}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224250.0,6759375.0,0.86]},"properties":{"height":0.86}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224325.0,6759375.0,4.65]},"properties":{"height":4.65}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224400.0,6759375.0,7.11]},"properties":{"height":7.11}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224475.0,6759375.0,6.92]},"properties":{"height":6.92}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224550.0,6759375.0,3.06]},"properties":{"height":3.06}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224625.0,6759375.0,2.56]},"properties":{"height":2.56}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224700.0,6759375.0,2.38]},"properties":{"height":2.38}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224775.0,6759375.0,3.27]},"properties":{"height":3.27}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224850.0,6759375.0,3.07]},"properties":{"height":3.07}},{"type":"Feature","geometry":{"type":"Point","coordinates":[224925.0,6759375.0,4.8]},"properties":{"height":4.8}}]} \ No newline at end of file diff --git a/noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/lw_roads.geojson b/noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/lw_roads.geojson deleted file mode 100644 index 37fb2f215..000000000 --- a/noisemodelling-tutorial-01/src/main/resources/org/noise_planet/nmtutorial01/lw_roads.geojson +++ /dev/null @@ -1,33934 +0,0 @@ -{ - "type": "FeatureCollection", - "crs": { - "type": "name", - "properties": { - "name": "urn:ogc:def:crs:EPSG::2154" - } - }, - "features": [ - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223222.88127646822, - 6757058.7121578045, - 0.05 - ], - [ - 223234.48495982075, - 6757120.318653769, - 0.05 - ], - [ - 223241.82073010656, - 6757159.263244189, - 0.05 - ], - [ - 223244.99588302913, - 6757176.128015889, - 0.05 - ], - [ - 223251.72390414187, - 6757211.833451514, - 0.05 - ], - [ - 223264.19529968814, - 6757278.040371546, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 1, - "lwd63": 86.50283580679425, - "lwd125": 76.49341395236712, - "lwd250": 75.05905120808356, - "lwd500": 75.38030171010958, - "lwd1000": 77.21485107085624, - "lwd2000": 74.50056202752108, - "lwd4000": 69.7375925296927, - "lwd8000": 62.26928736255882, - "lwe63": 80.6104012372824, - "lwe125": 70.60098039396205, - "lwe250": 69.16661808923507, - "lwe500": 69.48786847983625, - "lwe1000": 71.32241734054502, - "lwe2000": 68.60812912312961, - "lwe4000": 63.845163169579415, - "lwe8000": 56.376882388135705, - "lwn63": 74.57382902827649, - "lwn125": 64.56441229023557, - "lwn250": 63.13005177018767, - "lwn500": 63.451301708383866, - "lwn1000": 65.28584853884821, - "lwn2000": 62.571563674816026, - "lwn4000": 57.80861211163778, - "lwn8000": 50.340430338630966 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223464.6675235125, - 6758078.1284381375, - 0.05 - ], - [ - 223460.9570541333, - 6758078.261052692, - 0.05 - ], - [ - 223456.71857144852, - 6758079.39495833, - 0.05 - ], - [ - 223452.87614130403, - 6758081.243698745, - 0.05 - ], - [ - 223449.91626803332, - 6758082.664429671, - 0.05 - ], - [ - 223444.85560706147, - 6758086.461981218, - 0.05 - ], - [ - 223429.45780572575, - 6758101.695453515, - 0.05 - ], - [ - 223421.0067642298, - 6758109.958194633, - 0.05 - ], - [ - 223361.11276488833, - 6758168.6264537275, - 0.05 - ], - [ - 223344.7802274077, - 6758184.938946263, - 0.05 - ], - [ - 223341.01059529244, - 6758188.710282085, - 0.05 - ], - [ - 223324.13984396379, - 6758204.966022049, - 0.05 - ], - [ - 223305.3285948272, - 6758223.998173123, - 0.05 - ], - [ - 223276.39680183167, - 6758252.208613005, - 0.05 - ], - [ - 223271.83106600336, - 6758256.545962597, - 0.05 - ], - [ - 223270.7123748412, - 6758258.88805303, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 2, - "lwd63": 84.76340448114351, - "lwd125": 77.71392571660246, - "lwd250": 76.45640664271421, - "lwd500": 78.10187887639283, - "lwd1000": 82.1842740699675, - "lwd2000": 78.60572664495353, - "lwd4000": 72.00288106998227, - "lwd8000": 63.996292863451515, - "lwe63": 78.5957436509043, - "lwe125": 71.54626562706629, - "lwe250": 70.2887468630589, - "lwe500": 71.93421870800442, - "lwe1000": 76.01661338734425, - "lwe2000": 72.43806638412865, - "lwe4000": 65.83522349469918, - "lwe8000": 57.82865356993433, - "lwn63": 6.020599913279624, - "lwn125": 6.020599913279624, - "lwn250": 6.020599913279624, - "lwn500": 6.020599913279624, - "lwn1000": 6.020599913279624, - "lwn2000": 6.020599913279624, - "lwn4000": 6.020599913279624, - "lwn8000": 6.020599913279624 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223553.3971031342, - 6757818.686091136, - 0.05 - ], - [ - 223552.33988467348, - 6757822.070935655, - 0.05 - ], - [ - 223531.23570678686, - 6757888.772591468, - 0.05 - ], - [ - 223528.7034938556, - 6757896.791044069, - 0.05 - ], - [ - 223518.51734811877, - 6757928.992117789, - 0.05 - ], - [ - 223515.15756483452, - 6757939.607756921, - 0.05 - ], - [ - 223512.64244411502, - 6757947.557960741, - 0.05 - ], - [ - 223510.52932906145, - 6757954.249543019, - 0.05 - ], - [ - 223491.2345163623, - 6758015.231896177, - 0.05 - ], - [ - 223479.37279817357, - 6758052.740579001, - 0.05 - ], - [ - 223478.30074617895, - 6758056.12664663, - 0.05 - ], - [ - 223477.71376333653, - 6758057.979852781, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 3, - "lwd63": 86.9754564586566, - "lwd125": 76.966034568075, - "lwd250": 75.5316718080741, - "lwd500": 75.8529223140844, - "lwd1000": 77.68747169271104, - "lwd2000": 74.97318261984321, - "lwd4000": 70.21021299528095, - "lwd8000": 62.741906956177374, - "lwe63": 6.020599913279624, - "lwe125": 6.020599913279624, - "lwe250": 6.020599913279624, - "lwe500": 6.020599913279624, - "lwe1000": 6.020599913279624, - "lwe2000": 6.020599913279624, - "lwe4000": 6.020599913279624, - "lwe8000": 6.020599913279624, - "lwn63": 6.020599913279624, - "lwn125": 6.020599913279624, - "lwn250": 6.020599913279624, - "lwn500": 6.020599913279624, - "lwn1000": 6.020599913279624, - "lwn2000": 6.020599913279624, - "lwn4000": 6.020599913279624, - "lwn8000": 6.020599913279624 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223664.3003474155, - 6758808.456002241, - 0.05 - ], - [ - 223664.82768761885, - 6758805.492942608, - 0.05 - ], - [ - 223666.4416802533, - 6758802.9548580265, - 0.05 - ], - [ - 223668.91047190718, - 6758801.228322432, - 0.05 - ], - [ - 223671.8561565976, - 6758800.566799023, - 0.05 - ], - [ - 223674.82945493812, - 6758801.084607284, - 0.05 - ], - [ - 223677.37902653596, - 6758802.684443143, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 4, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224063.47660395864, - 6758152.231359334, - 0.05 - ], - [ - 224093.64909257187, - 6758070.041886768, - 0.05 - ], - [ - 224109.30106265406, - 6758026.544074643, - 0.05 - ], - [ - 224118.5469450312, - 6758000.450457608, - 0.05 - ], - [ - 224123.28605090873, - 6757986.513697589, - 0.05 - ], - [ - 224136.36357866944, - 6757950.513667039, - 0.05 - ], - [ - 224150.86154764856, - 6757910.9659046745, - 0.05 - ], - [ - 224186.20572407107, - 6757812.520549983, - 0.05 - ], - [ - 224197.13816108461, - 6757781.230496689, - 0.05 - ], - [ - 224212.50803049025, - 6757737.00908452, - 0.05 - ], - [ - 224223.27601169806, - 6757706.378887532, - 0.05 - ], - [ - 224234.4172181675, - 6757673.7568089515, - 0.05 - ], - [ - 224234.81779687793, - 6757657.194028779, - 0.05 - ], - [ - 224233.9998679413, - 6757652.366633356, - 0.05 - ], - [ - 224232.74402644875, - 6757644.999689287, - 0.05 - ], - [ - 224229.51922953158, - 6757635.684859781, - 0.05 - ], - [ - 224217.88975616626, - 6757623.113255301, - 0.05 - ], - [ - 224206.16702763154, - 6757616.189393763, - 0.05 - ], - [ - 224197.176202902, - 6757609.3015379105, - 0.05 - ], - [ - 224187.76577497623, - 6757605.13388599, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 5, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223871.06618105882, - 6758476.382142789, - 0.05 - ], - [ - 223901.0468100609, - 6758395.321355753, - 0.05 - ], - [ - 223911.98126949026, - 6758365.769192144, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 6, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223845.51184355112, - 6758343.012448697, - 0.05 - ], - [ - 223857.45006772992, - 6758346.562980646, - 0.05 - ], - [ - 223863.5358029828, - 6758348.479320249, - 0.05 - ], - [ - 223911.98126949026, - 6758365.769192144, - 0.05 - ], - [ - 223926.28986276797, - 6758329.591039093, - 0.05 - ], - [ - 223975.68270282424, - 6758346.046970212, - 0.05 - ], - [ - 223984.0824838273, - 6758348.880167855, - 0.05 - ], - [ - 224017.95687655755, - 6758359.1542090485, - 0.05 - ], - [ - 224067.50480954052, - 6758376.980542559, - 0.05 - ], - [ - 224100.07535100396, - 6758387.962179369, - 0.05 - ], - [ - 224111.99562055228, - 6758393.064046533, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 7, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223926.28986276797, - 6758329.591039093, - 0.05 - ], - [ - 223945.3466209069, - 6758298.591865573, - 0.05 - ], - [ - 223960.2186804008, - 6758258.400120296, - 0.05 - ], - [ - 223972.04818218952, - 6758205.936265913, - 0.05 - ], - [ - 223963.06717470067, - 6758191.434789596, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 8, - "lwd63": 69.23337176130693, - "lwd125": 59.2239682542633, - "lwd250": 57.78961348608122, - "lwd500": 58.11086196621637, - "lwd1000": 59.94540225337552, - "lwd2000": 57.231128197005475, - "lwd4000": 52.468223012343444, - "lwd8000": 45.00036031456698, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223963.06717470067, - 6758191.434789596, - 0.05 - ], - [ - 223980.04790852283, - 6758172.797880435, - 0.05 - ], - [ - 223983.86638044106, - 6758165.90196237, - 0.05 - ], - [ - 223997.03482891602, - 6758129.927589925, - 0.05 - ], - [ - 224026.87962997996, - 6758048.343802291, - 0.05 - ], - [ - 224043.65408792876, - 6758002.73764634, - 0.05 - ], - [ - 224058.19877274125, - 6757963.219256706, - 0.05 - ], - [ - 224064.9164243451, - 6757944.084474925, - 0.05 - ], - [ - 224071.2201363616, - 6757927.179006507, - 0.05 - ], - [ - 224076.50330912613, - 6757912.997666218, - 0.05 - ], - [ - 224107.67358354427, - 6757826.659442504, - 0.05 - ], - [ - 224110.52591588406, - 6757818.871847074, - 0.05 - ], - [ - 224121.80822345038, - 6757788.289070853, - 0.05 - ], - [ - 224132.90093937342, - 6757757.777361308, - 0.05 - ], - [ - 224136.78836546442, - 6757747.1641924875, - 0.05 - ], - [ - 224159.47013051796, - 6757684.272809163, - 0.05 - ], - [ - 224168.62958536233, - 6757658.866301725, - 0.05 - ], - [ - 224186.5159086982, - 6757609.024575711, - 0.05 - ], - [ - 224187.76577497623, - 6757605.13388599, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 9, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224063.47660395864, - 6758152.231359334, - 0.05 - ], - [ - 224054.2555270256, - 6758154.034461945, - 0.05 - ], - [ - 224048.72736423882, - 6758155.115968781, - 0.05 - ], - [ - 223995.65297637903, - 6758165.708587802, - 0.05 - ], - [ - 223983.86638044106, - 6758165.90196237, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 10, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224356.25029423973, - 6757182.140499514, - 0.05 - ], - [ - 224359.448749931, - 6757178.449430606, - 0.05 - ], - [ - 224361.1304994956, - 6757173.94435454, - 0.05 - ], - [ - 224360.02744820563, - 6757167.724333715, - 0.05 - ], - [ - 224320.94690224854, - 6757062.753923693, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 11, - "lwd63": 81.89725490106659, - "lwd125": 71.88783370853906, - "lwd250": 70.45347125200192, - "lwd500": 70.77472168108605, - "lwd1000": 72.60927071449348, - "lwd2000": 69.89498221182919, - "lwd4000": 65.13201503418793, - "lwd8000": 57.66372583065063, - "lwe63": 76.39340352366376, - "lwe125": 66.3839849143855, - "lwe250": 64.94962358085901, - "lwe500": 65.27087372526692, - "lwe1000": 67.10542148114162, - "lwe2000": 64.39113508859629, - "lwe4000": 59.62817696611757, - "lwe8000": 52.15995006422352, - "lwn63": 73.38310396559334, - "lwn125": 63.37368895209104, - "lwn250": 61.939329181747304, - "lwn500": 62.26057892989822, - "lwn1000": 64.09512490750173, - "lwn2000": 61.38084145215147, - "lwn4000": 56.617895934032056, - "lwn8000": 49.14975575138363 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224198.7455936022, - 6757243.754991727, - 0.05 - ], - [ - 224323.49939008022, - 6757197.332658464, - 0.05 - ], - [ - 224338.21283946483, - 6757191.642890154, - 0.05 - ], - [ - 224340.77373392985, - 6757188.716605954, - 0.05 - ], - [ - 224356.25029423973, - 6757182.140499514, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 12, - "lwd63": 81.89725490106659, - "lwd125": 71.88783370853906, - "lwd250": 70.45347125200192, - "lwd500": 70.77472168108605, - "lwd1000": 72.60927071449348, - "lwd2000": 69.89498221182919, - "lwd4000": 65.13201503418793, - "lwd8000": 57.66372583065063, - "lwe63": 76.39340352366376, - "lwe125": 66.3839849143855, - "lwe250": 64.94962358085901, - "lwe500": 65.27087372526692, - "lwe1000": 67.10542148114162, - "lwe2000": 64.39113508859629, - "lwe4000": 59.62817696611757, - "lwe8000": 52.15995006422352, - "lwn63": 73.38310396559334, - "lwn125": 63.37368895209104, - "lwn250": 61.939329181747304, - "lwn500": 62.26057892989822, - "lwn1000": 64.09512490750173, - "lwn2000": 61.38084145215147, - "lwn4000": 56.617895934032056, - "lwn8000": 49.14975575138363 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223455.21886243462, - 6757454.372319427, - 0.05 - ], - [ - 223533.72220825625, - 6757437.11747906, - 0.05 - ], - [ - 223553.42621998844, - 6757423.509614314, - 0.05 - ], - [ - 223615.5930091854, - 6757380.567088964, - 0.05 - ], - [ - 223671.76409262768, - 6757339.246453336, - 0.05 - ], - [ - 223734.27338774566, - 6757293.9145715665, - 0.05 - ], - [ - 223748.14292725245, - 6757283.832742263, - 0.05 - ], - [ - 223765.87489944557, - 6757270.931090575, - 0.05 - ], - [ - 223834.00588222675, - 6757224.065273133, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 13, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223787.770420285, - 6757374.410255257, - 0.05 - ], - [ - 223872.5634653757, - 6757314.907968064, - 0.05 - ], - [ - 223884.69508168346, - 6757306.393534638, - 0.05 - ], - [ - 223890.23122332006, - 6757302.513482887, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 14, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223636.65559910698, - 6757477.703851863, - 0.05 - ], - [ - 223690.18168001558, - 6757555.298227939, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 15, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223959.69097099104, - 6757401.685719432, - 0.05 - ], - [ - 223955.9075571851, - 6757396.261692507, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 16, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223884.44937743508, - 6757577.545123223, - 0.05 - ], - [ - 223877.41624138947, - 6757567.813335387, - 0.05 - ], - [ - 223865.45314613846, - 6757550.375894143, - 0.05 - ], - [ - 223832.63980828557, - 6757501.805878681, - 0.05 - ], - [ - 223828.78525891423, - 6757496.153587884, - 0.05 - ], - [ - 223825.19077811763, - 6757489.811501708, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 17, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223734.27338774566, - 6757293.9145715665, - 0.05 - ], - [ - 223754.55648556276, - 6757324.43501759, - 0.05 - ], - [ - 223756.00307302532, - 6757326.614433559, - 0.05 - ], - [ - 223774.03441687406, - 6757353.738662426, - 0.05 - ], - [ - 223787.770420285, - 6757374.410255257, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 18, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223892.09110398887, - 6757043.972695812, - 0.05 - ], - [ - 223886.39671335195, - 6757058.098118712, - 0.05 - ], - [ - 223831.91225005628, - 6757103.504756363, - 0.05 - ], - [ - 223825.30520088575, - 6757105.29769928, - 0.05 - ], - [ - 223819.50428086397, - 6757107.203918428, - 0.05 - ], - [ - 223777.25185909297, - 6757136.664836553, - 0.05 - ], - [ - 223773.0317070071, - 6757139.524706666, - 0.05 - ], - [ - 223770.22355253994, - 6757141.434577853, - 0.05 - ], - [ - 223711.42231266922, - 6757183.735533429, - 0.05 - ], - [ - 223706.68943088286, - 6757186.948965959, - 0.05 - ], - [ - 223702.4878648664, - 6757189.851978492, - 0.05 - ], - [ - 223673.77329232072, - 6757209.671055205, - 0.05 - ], - [ - 223664.77826831257, - 6757215.781309239, - 0.05 - ], - [ - 223632.67934352398, - 6757238.471099787, - 0.05 - ], - [ - 223612.5653445752, - 6757252.691365468, - 0.05 - ], - [ - 223552.94379513204, - 6757294.770533036, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 19, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224106.97930704785, - 6757277.910099557, - 0.05 - ], - [ - 224098.51419623924, - 6757272.886016517, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 20, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223945.79769551422, - 6757381.851323904, - 0.05 - ], - [ - 223951.6947641053, - 6757377.786141183, - 0.05 - ], - [ - 224030.1671171884, - 6757323.700896448, - 0.05 - ], - [ - 224060.55718502332, - 6757301.162362116, - 0.05 - ], - [ - 224090.74758624437, - 6757278.662407963, - 0.05 - ], - [ - 224098.51419623924, - 6757272.886016517, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 21, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223915.35284722847, - 6757169.434470559, - 0.05 - ], - [ - 223928.93102069816, - 6757190.854780055, - 0.05 - ], - [ - 223922.4098576515, - 6757221.376765533, - 0.05 - ], - [ - 223922.89049759164, - 6757227.145379378, - 0.05 - ], - [ - 223928.5256720616, - 6757241.537895108, - 0.05 - ], - [ - 223944.45966656605, - 6757264.016514136, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 22, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223972.30734608875, - 6757244.257606481, - 0.05 - ], - [ - 224025.99001169216, - 6757317.963051931, - 0.05 - ], - [ - 224030.1671171884, - 6757323.700896448, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 23, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223890.23122332006, - 6757302.513482887, - 0.05 - ], - [ - 223893.79389619606, - 6757299.985426329, - 0.05 - ], - [ - 223944.45966656605, - 6757264.016514136, - 0.05 - ], - [ - 223972.30734608875, - 6757244.257606481, - 0.05 - ], - [ - 224005.8573738386, - 6757220.438303749, - 0.05 - ], - [ - 224030.12862243276, - 6757203.219939933, - 0.05 - ], - [ - 224043.31951489026, - 6757193.851276481, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 24, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223552.94379513204, - 6757294.770533036, - 0.05 - ], - [ - 223615.5930091854, - 6757380.567088964, - 0.05 - ], - [ - 223637.6020078861, - 6757410.947779099, - 0.05 - ], - [ - 223667.45719102275, - 6757455.6314703105, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 25, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223765.87489944557, - 6757270.931090575, - 0.05 - ], - [ - 223709.48237528745, - 6757190.903445387, - 0.05 - ], - [ - 223706.68943088286, - 6757186.948965959, - 0.05 - ], - [ - 223704.27287094487, - 6757183.465695589, - 0.05 - ], - [ - 223616.03911788145, - 6757056.730546813, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 26, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223552.94379513204, - 6757294.770533036, - 0.05 - ], - [ - 223507.3229636487, - 6757292.369704128, - 0.05 - ], - [ - 223446.1743490653, - 6757290.131387414, - 0.05 - ], - [ - 223274.5948494578, - 6757278.894138715, - 0.05 - ], - [ - 223264.19529968814, - 6757278.040371546, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 27, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223513.5941594767, - 6757123.07953193, - 0.05 - ], - [ - 223517.46068961144, - 6757150.188096684, - 0.05 - ], - [ - 223505.60033543938, - 6757157.778491801, - 0.05 - ], - [ - 223474.16837133234, - 6757154.008700027, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 28, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223251.72390414187, - 6757211.833451514, - 0.05 - ], - [ - 223425.33764687536, - 6757219.84047752, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 29, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223517.6522861265, - 6757055.760006994, - 0.05 - ], - [ - 223553.74203953485, - 6757116.537055541, - 0.05 - ], - [ - 223632.67934352398, - 6757238.471099787, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 30, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223507.3229636487, - 6757292.369704128, - 0.05 - ], - [ - 223508.46333472384, - 6757283.404789818, - 0.05 - ], - [ - 223475.45053881867, - 6757169.321026659, - 0.05 - ], - [ - 223474.16837133234, - 6757154.008700027, - 0.05 - ], - [ - 223478.1812378447, - 6757128.481784565, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 31, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223452.11499957048, - 6757402.835348768, - 0.05 - ], - [ - 223366.84923335764, - 6757406.748864313, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 32, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223323.00315323123, - 6757565.6557938615, - 0.05 - ], - [ - 223343.63465089322, - 6757563.720881089, - 0.05 - ], - [ - 223365.7507507623, - 6757559.503595425, - 0.05 - ], - [ - 223447.50117520546, - 6757543.746258963, - 0.05 - ], - [ - 223459.16835356527, - 6757541.499415911, - 0.05 - ], - [ - 223466.70368011144, - 6757539.943122821, - 0.05 - ], - [ - 223577.61200309766, - 6757516.949632197, - 0.05 - ], - [ - 223583.63134131004, - 6757515.705442069, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 33, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223365.7507507623, - 6757559.503595425, - 0.05 - ], - [ - 223338.4654306466, - 6757412.308623303, - 0.05 - ], - [ - 223287.4568271853, - 6757403.890985491, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 34, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223612.5653445752, - 6757252.691365468, - 0.05 - ], - [ - 223671.76409262768, - 6757339.246453336, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 35, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223533.72220825625, - 6757437.11747906, - 0.05 - ], - [ - 223579.21267102967, - 6757508.750107801, - 0.05 - ], - [ - 223583.63134131004, - 6757515.705442069, - 0.05 - ], - [ - 223586.54962384253, - 6757520.374278824, - 0.05 - ], - [ - 223606.3242511024, - 6757551.949682422, - 0.05 - ], - [ - 223610.54391918005, - 6757558.675879272, - 0.05 - ], - [ - 223620.3318273782, - 6757574.304435799, - 0.05 - ], - [ - 223625.03415600897, - 6757581.794221371, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 36, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223472.50315353315, - 6757710.82238911, - 0.05 - ], - [ - 223490.21960322856, - 6757696.728285382, - 0.05 - ], - [ - 223493.86328427022, - 6757695.207760294, - 0.05 - ], - [ - 223558.5387276144, - 6757649.486735661, - 0.05 - ], - [ - 223563.671253127, - 6757645.828428395, - 0.05 - ], - [ - 223569.98375736125, - 6757641.327977626, - 0.05 - ], - [ - 223626.39422536298, - 6757601.146551561, - 0.05 - ], - [ - 223630.5742367471, - 6757598.167166061, - 0.05 - ], - [ - 223633.92237271433, - 6757595.778868051, - 0.05 - ], - [ - 223636.39649825334, - 6757594.018499219, - 0.05 - ], - [ - 223681.80256293662, - 6757562.139039793, - 0.05 - ], - [ - 223690.18168001558, - 6757555.298227939, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 37, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223451.3928676881, - 6757693.333339478, - 0.05 - ], - [ - 223465.64143490908, - 6757675.584563229, - 0.05 - ], - [ - 223463.14877331565, - 6757610.956453654, - 0.05 - ], - [ - 223462.9437135816, - 6757607.394915096, - 0.05 - ], - [ - 223459.65506936703, - 6757549.942764805, - 0.05 - ], - [ - 223459.16835356527, - 6757541.499415911, - 0.05 - ], - [ - 223458.78352663456, - 6757533.014394931, - 0.05 - ], - [ - 223455.21886243462, - 6757454.372319427, - 0.05 - ], - [ - 223452.11499957048, - 6757402.835348768, - 0.05 - ], - [ - 223446.1743490653, - 6757290.131387414, - 0.05 - ], - [ - 223425.33764687536, - 6757219.84047752, - 0.05 - ], - [ - 223403.0027605266, - 6757140.875917556, - 0.05 - ], - [ - 223376.16801738337, - 6757054.149072676, - 0.05 - ], - [ - 223367.29911944125, - 6756965.792250361, - 0.05 - ], - [ - 223365.39513925283, - 6756944.555543794, - 0.05 - ], - [ - 223362.08670973306, - 6756902.587962585, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 38, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223380.97273299482, - 6757623.482043047, - 0.05 - ], - [ - 223390.3878666337, - 6757614.394579119, - 0.05 - ], - [ - 223457.73410038644, - 6757611.215593856, - 0.05 - ], - [ - 223463.14877331565, - 6757610.956453654, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 39, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222837.7406755443, - 6758775.985866912, - 0.05 - ], - [ - 222900.918670926, - 6758806.544067394, - 0.05 - ], - [ - 222905.2159563278, - 6758807.723511011, - 0.05 - ], - [ - 222950.4983745044, - 6758803.747892404, - 0.05 - ], - [ - 223010.26315326372, - 6758817.026958148, - 0.05 - ], - [ - 223018.23308403796, - 6758818.076606911, - 0.05 - ], - [ - 223054.81916596548, - 6758825.539678114, - 0.05 - ], - [ - 223103.22143861034, - 6758842.948986511, - 0.05 - ], - [ - 223113.68182025861, - 6758847.096824652, - 0.05 - ], - [ - 223120.98679789522, - 6758847.174870185, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 40, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223064.9538643285, - 6758954.837674115, - 0.05 - ], - [ - 223063.95905916684, - 6758949.601065345, - 0.05 - ], - [ - 223057.3218227275, - 6758914.657325286, - 0.05 - ], - [ - 223054.81916596548, - 6758825.539678114, - 0.05 - ], - [ - 223061.77265930915, - 6758770.435539792, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 41, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223018.23308403796, - 6758818.076606911, - 0.05 - ], - [ - 223022.24608349893, - 6758796.784692877, - 0.05 - ], - [ - 223028.16999995348, - 6758758.227740547, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 42, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223139.856947298, - 6758767.185971479, - 0.05 - ], - [ - 223144.82104207104, - 6758766.294079649, - 0.05 - ], - [ - 223149.55096140614, - 6758765.109016291, - 0.05 - ], - [ - 223155.28308555798, - 6758763.6757110525, - 0.05 - ], - [ - 223186.06495282712, - 6758755.969902427, - 0.05 - ], - [ - 223235.95128467557, - 6758773.605853442, - 0.05 - ], - [ - 223263.0884758163, - 6758783.205228779, - 0.05 - ], - [ - 223308.09199362743, - 6758799.118611686, - 0.05 - ], - [ - 223313.86814627482, - 6758799.810949286, - 0.05 - ], - [ - 223318.74607096612, - 6758796.830560454, - 0.05 - ], - [ - 223338.9178497324, - 6758779.404884714, - 0.05 - ], - [ - 223359.12386482296, - 6758761.285417107, - 0.05 - ], - [ - 223405.40465895552, - 6758720.927384241, - 0.05 - ], - [ - 223414.82789213356, - 6758712.708563227, - 0.05 - ], - [ - 223439.1055510856, - 6758695.0183292935, - 0.05 - ], - [ - 223488.02797961782, - 6758700.361302062, - 0.05 - ], - [ - 223494.63073050644, - 6758701.143081649, - 0.05 - ], - [ - 223533.45441030635, - 6758705.697327798, - 0.05 - ], - [ - 223541.30068582774, - 6758706.612765532, - 0.05 - ], - [ - 223563.55052646121, - 6758709.407548475, - 0.05 - ], - [ - 223566.20337932103, - 6758709.772847597, - 0.05 - ], - [ - 223618.57158143533, - 6758716.555089402, - 0.05 - ], - [ - 223623.26341766852, - 6758717.223859998, - 0.05 - ], - [ - 223677.19866778405, - 6758724.9835489895, - 0.05 - ], - [ - 223690.42250387382, - 6758726.86930441, - 0.05 - ], - [ - 223703.47858401993, - 6758731.889739663, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 43, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222862.88937659224, - 6758622.575868499, - 0.05 - ], - [ - 222871.15718115965, - 6758619.499178343, - 0.05 - ], - [ - 222944.17980575218, - 6758619.811300503, - 0.05 - ], - [ - 223011.9152713216, - 6758619.626787559, - 0.05 - ], - [ - 223020.88556939492, - 6758621.0525653185, - 0.05 - ], - [ - 223051.50153206225, - 6758631.361738126, - 0.05 - ], - [ - 223058.69076516735, - 6758634.001724357, - 0.05 - ], - [ - 223084.75290917617, - 6758643.586975616, - 0.05 - ], - [ - 223123.95506300183, - 6758664.984348155, - 0.05 - ], - [ - 223128.27482274675, - 6758665.604795869, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 44, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223051.50153206225, - 6758631.361738126, - 0.05 - ], - [ - 223049.47299516707, - 6758636.48616831, - 0.05 - ], - [ - 223038.37287672033, - 6758664.582355931, - 0.05 - ], - [ - 223033.08645806642, - 6758679.333685683, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 45, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223038.37287672033, - 6758664.582355931, - 0.05 - ], - [ - 223019.29402148275, - 6758660.85306103, - 0.05 - ], - [ - 222984.39673412679, - 6758654.58000326, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 46, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223144.82104207104, - 6758766.294079649, - 0.05 - ], - [ - 223156.42657037906, - 6758669.615132684, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 47, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223414.82789213356, - 6758712.708563227, - 0.05 - ], - [ - 223410.2841990788, - 6758708.851135256, - 0.05 - ], - [ - 223407.85464153992, - 6758706.78468652, - 0.05 - ], - [ - 223399.98701446096, - 6758703.931600365, - 0.05 - ], - [ - 223364.8259463359, - 6758700.241447235, - 0.05 - ], - [ - 223359.8845389791, - 6758700.484797306, - 0.05 - ], - [ - 223353.81288409268, - 6758702.926261785, - 0.05 - ], - [ - 223346.21960909932, - 6758725.0422872165, - 0.05 - ], - [ - 223320.85697771324, - 6758719.356528707, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 48, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223242.72580993053, - 6758865.019758809, - 0.05 - ], - [ - 223263.0884758163, - 6758783.205228779, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 49, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223438.15393887047, - 6758862.843914839, - 0.05 - ], - [ - 223426.53262838576, - 6758817.913894621, - 0.05 - ], - [ - 223425.4389236712, - 6758792.197361506, - 0.05 - ], - [ - 223509.6244221846, - 6758782.139313941, - 0.05 - ], - [ - 223493.04379271943, - 6758849.312286175, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 50, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223338.9178497324, - 6758779.404884714, - 0.05 - ], - [ - 223344.33901591995, - 6758781.563891069, - 0.05 - ], - [ - 223409.66332651844, - 6758810.44898383, - 0.05 - ], - [ - 223426.53262838576, - 6758817.913894621, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 51, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223509.6244221846, - 6758782.139313941, - 0.05 - ], - [ - 223520.75224437867, - 6758757.620035739, - 0.05 - ], - [ - 223534.07795863965, - 6758724.485061042, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 52, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223681.85768758558, - 6758789.548444939, - 0.05 - ], - [ - 223520.75224437867, - 6758757.620035739, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 53, - "lwd63": 74.80202133263722, - "lwd125": 63.46681363911763, - "lwd250": 61.92943742035383, - "lwd500": 61.083171818486825, - "lwd1000": 61.08462562782606, - "lwd2000": 60.04915997293725, - "lwd4000": 56.319429170657, - "lwd8000": 49.03613814679069, - "lwe63": 69.32352255665018, - "lwe125": 57.988333195461124, - "lwe250": 56.450965381277626, - "lwe500": 55.60470584461696, - "lwe1000": 55.60615964249051, - "lwe2000": 54.570703208140756, - "lwe4000": 50.841031533630165, - "lwe8000": 43.55818673417338, - "lwn63": 66.40096379186707, - "lwn125": 55.06579898403314, - "lwn250": 53.528442426419474, - "lwn500": 52.682191013085635, - "lwn1000": 52.68364479560286, - "lwn2000": 51.64820071056823, - "lwn4000": 47.918608226006825, - "lwn8000": 40.63636097453439 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223901.30390191014, - 6758193.6562288385, - 0.05 - ], - [ - 223900.93835259404, - 6758194.622064526, - 0.05 - ], - [ - 223887.76567067712, - 6758231.745176058, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 54, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223588.2020588186, - 6757838.569289994, - 0.05 - ], - [ - 223590.92216544208, - 6757841.158545267, - 0.05 - ], - [ - 223607.60051626287, - 6757857.679559629, - 0.05 - ], - [ - 223611.88437325152, - 6757861.7587893205, - 0.05 - ], - [ - 223617.42078127066, - 6757862.916722211, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 55, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223714.87154520408, - 6758698.264856723, - 0.05 - ], - [ - 223725.59669510188, - 6758701.879619266, - 0.05 - ], - [ - 223733.38063914003, - 6758703.792407094, - 0.05 - ], - [ - 223737.9628159759, - 6758704.59273941, - 0.05 - ], - [ - 223761.98560129345, - 6758707.936168892, - 0.05 - ], - [ - 223805.21977570717, - 6758713.964051554, - 0.05 - ], - [ - 223944.96003212134, - 6758731.350662495, - 0.05 - ], - [ - 223953.77952721447, - 6758731.474677996, - 0.05 - ], - [ - 223995.24084900902, - 6758732.029076587, - 0.05 - ], - [ - 224118.17422487854, - 6758748.134617869, - 0.05 - ], - [ - 224267.58078435832, - 6758774.501994206, - 0.05 - ], - [ - 224291.59962065658, - 6758778.739578695, - 0.05 - ], - [ - 224319.0113082095, - 6758783.573007714, - 0.05 - ], - [ - 224341.2537345694, - 6758787.407897811, - 0.05 - ], - [ - 224359.26634152915, - 6758790.335616981, - 0.05 - ], - [ - 224362.46416561812, - 6758790.935975366, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 56, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223748.99096458533, - 6758865.988136796, - 0.05 - ], - [ - 223766.61674388516, - 6758820.378747352, - 0.05 - ], - [ - 223784.46129379782, - 6758770.493706376, - 0.05 - ], - [ - 223796.23549380386, - 6758738.421056429, - 0.05 - ], - [ - 223805.21977570717, - 6758713.964051554, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 57, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223915.81536477152, - 6758939.673525173, - 0.05 - ], - [ - 223927.63967362157, - 6758854.872877461, - 0.05 - ], - [ - 223936.20036302716, - 6758791.6484047305, - 0.05 - ], - [ - 223938.10632333637, - 6758779.411445496, - 0.05 - ], - [ - 223944.96003212134, - 6758731.350662495, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 58, - "lwd63": 75.90171332041136, - "lwd125": 66.50354895698379, - "lwd250": 65.07810131032979, - "lwd500": 67.03547618298532, - "lwd1000": 68.69573012731246, - "lwd2000": 63.98750464460184, - "lwd4000": 59.83951230326983, - "lwd8000": 52.46266685676584, - "lwe63": 70.43578425158094, - "lwe125": 61.037628557169114, - "lwe250": 59.612184715440435, - "lwe500": 61.569554654148824, - "lwe1000": 63.22980584560604, - "lwe2000": 58.52159193169619, - "lwe4000": 54.37362754144347, - "lwe8000": 46.99698499689735, - "lwn63": 67.42548586626533, - "lwn125": 58.02734228036127, - "lwn250": 56.601903753170085, - "lwn500": 58.55926680037521, - "lwn1000": 60.21951414674617, - "lwn2000": 55.51131639158329, - "lwn4000": 51.363391041634046, - "lwn8000": 43.98703187968516 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223784.46129379782, - 6758770.493706376, - 0.05 - ], - [ - 223936.20036302716, - 6758791.6484047305, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 59, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224096.59533901588, - 6758964.684933335, - 0.05 - ], - [ - 224103.80184597196, - 6758884.849967091, - 0.05 - ], - [ - 224110.48171475547, - 6758815.156507165, - 0.05 - ], - [ - 224118.17422487854, - 6758748.134617869, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 60, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223938.10632333637, - 6758779.411445496, - 0.05 - ], - [ - 224110.48171475547, - 6758815.156507165, - 0.05 - ], - [ - 224168.2274034365, - 6758820.79611446, - 0.05 - ], - [ - 224197.12020977773, - 6758860.287240102, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 61, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224233.6695534591, - 6758833.606858374, - 0.05 - ], - [ - 224256.575427941, - 6758816.877937305, - 0.05 - ], - [ - 224264.0167008933, - 6758795.076545268, - 0.05 - ], - [ - 224267.58078435832, - 6758774.501994206, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 62, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223301.6187954211, - 6757567.205757065, - 0.05 - ], - [ - 223295.0924617708, - 6757566.362186444, - 0.05 - ], - [ - 223275.59774431208, - 6757566.176673736, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 63, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222509.9690245777, - 6758244.200397368, - 0.05 - ], - [ - 222616.3647540487, - 6758214.485747177, - 0.05 - ], - [ - 222625.77188814222, - 6758212.197137096, - 0.05 - ], - [ - 222667.61517204728, - 6758201.988309476, - 0.05 - ], - [ - 222754.05349549168, - 6758195.226772373, - 0.05 - ], - [ - 222757.37315196858, - 6758195.281391429, - 0.05 - ], - [ - 222765.58984228905, - 6758194.817113697, - 0.05 - ], - [ - 222771.93549453228, - 6758193.991497427, - 0.05 - ], - [ - 222786.40522892697, - 6758192.764867871, - 0.05 - ], - [ - 222788.9744397633, - 6758192.5569703225, - 0.05 - ], - [ - 222842.47319712152, - 6758188.239316028, - 0.05 - ], - [ - 222848.19058725215, - 6758188.010812188, - 0.05 - ], - [ - 222865.566982879, - 6758193.070128218, - 0.05 - ], - [ - 222915.29672953737, - 6758209.256198125, - 0.05 - ], - [ - 222940.71951954358, - 6758218.0678106835, - 0.05 - ], - [ - 222979.61675737635, - 6758225.990250485, - 0.05 - ], - [ - 222982.45299681113, - 6758226.57455792, - 0.05 - ], - [ - 223079.0969067625, - 6758245.532918584, - 0.05 - ], - [ - 223085.9651955358, - 6758241.689162916, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 64, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223075.16969871277, - 6758467.929351549, - 0.05 - ], - [ - 223080.14381984575, - 6758457.026731672, - 0.05 - ], - [ - 223082.7383850058, - 6758449.604882151, - 0.05 - ], - [ - 223107.67324043193, - 6758365.391480312, - 0.05 - ], - [ - 223110.5640140166, - 6758356.797573733, - 0.05 - ], - [ - 223114.0243936879, - 6758349.762754629, - 0.05 - ], - [ - 223118.7427084407, - 6758343.595991686, - 0.05 - ], - [ - 223124.83277724416, - 6758338.310377822, - 0.05 - ], - [ - 223131.2161129297, - 6758329.957967611, - 0.05 - ], - [ - 223133.46019704017, - 6758325.730200498, - 0.05 - ], - [ - 223134.4930486164, - 6758323.907774081, - 0.05 - ], - [ - 223135.37821595243, - 6758319.143375724, - 0.05 - ], - [ - 223135.33186644776, - 6758315.223433923, - 0.05 - ], - [ - 223134.7373087941, - 6758311.682226542, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 65, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223096.88228060154, - 6758253.703221687, - 0.05 - ], - [ - 223104.3609129298, - 6758249.598340478, - 0.05 - ], - [ - 223139.05825239414, - 6758248.6318396265, - 0.05 - ], - [ - 223147.85498420644, - 6758248.55591213, - 0.05 - ], - [ - 223158.33810552052, - 6758248.510844036, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 66, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223158.33810552052, - 6758248.510844036, - 0.05 - ], - [ - 223158.27737249812, - 6758245.5284022335, - 0.05 - ], - [ - 223158.2137269731, - 6758241.487246434, - 0.05 - ], - [ - 223158.35100513924, - 6758239.280219663, - 0.05 - ], - [ - 223158.8754097268, - 6758237.677260932, - 0.05 - ], - [ - 223174.475315359, - 6758198.271464482, - 0.05 - ], - [ - 223181.7773662227, - 6758180.358899764, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 67, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222991.0241082005, - 6758108.738960103, - 0.05 - ], - [ - 223034.86508245015, - 6758076.835551261, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 68, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223006.33932329604, - 6758129.860820169, - 0.05 - ], - [ - 222980.81073312543, - 6758143.908521716, - 0.05 - ], - [ - 222960.67420819652, - 6758146.083503735, - 0.05 - ], - [ - 222934.75104427466, - 6758137.780432716, - 0.05 - ], - [ - 222863.84192754125, - 6758109.585842367, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 69, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222763.82901380776, - 6757629.088591206, - 0.05 - ], - [ - 222770.41181931755, - 6757645.588338477, - 0.05 - ], - [ - 222795.2335014292, - 6757658.739680201, - 0.05 - ], - [ - 222856.35518286272, - 6757671.083382496, - 0.05 - ], - [ - 222904.62776934105, - 6757680.822054887, - 0.05 - ], - [ - 222937.50293956156, - 6757687.214036888, - 0.05 - ], - [ - 222975.9670108172, - 6757695.316646817, - 0.05 - ], - [ - 223012.1496092782, - 6757702.634236161, - 0.05 - ], - [ - 223062.08182349778, - 6757712.730389952, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 70, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223063.5248695843, - 6757570.291218644, - 0.05 - ], - [ - 223064.14924652426, - 6757579.314229496, - 0.05 - ], - [ - 223067.38224506762, - 6757649.790443925, - 0.05 - ], - [ - 223070.26016343845, - 6757706.205823963, - 0.05 - ], - [ - 223062.08182349778, - 6757712.730389952, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 71, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222975.9670108172, - 6757695.316646817, - 0.05 - ], - [ - 222990.08031401224, - 6757638.262713638, - 0.05 - ], - [ - 222991.14648654166, - 6757580.982155792, - 0.05 - ], - [ - 222990.48972110922, - 6757572.117818717, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 72, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223375.87972827756, - 6757641.583527747, - 0.05 - ], - [ - 223366.49991154898, - 6757650.735047832, - 0.05 - ], - [ - 223364.30816892924, - 6757652.918588186, - 0.05 - ], - [ - 223321.86786006828, - 6757695.328770656, - 0.05 - ], - [ - 223317.49191379594, - 6757699.69528231, - 0.05 - ], - [ - 223300.72576869134, - 6757717.915462355, - 0.05 - ], - [ - 223296.53118593513, - 6757722.479122664, - 0.05 - ], - [ - 223258.7665824396, - 6757807.560840408, - 0.05 - ], - [ - 223250.54598419473, - 6757818.212875422, - 0.05 - ], - [ - 223126.8096521736, - 6757905.4415803915, - 0.05 - ], - [ - 223074.17268623773, - 6757913.5658538295, - 0.05 - ], - [ - 223057.28377939464, - 6757924.9526243005, - 0.05 - ], - [ - 222967.97005094227, - 6757985.157016971, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 73, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223147.85498420644, - 6758248.55591213, - 0.05 - ], - [ - 223147.71986512037, - 6758245.490310052, - 0.05 - ], - [ - 223147.74789278104, - 6758241.932202159, - 0.05 - ], - [ - 223147.67879349733, - 6758234.569729123, - 0.05 - ], - [ - 223147.45067898562, - 6758232.77123945, - 0.05 - ], - [ - 223146.84702000464, - 6758231.3486677185, - 0.05 - ], - [ - 223049.95491888328, - 6758098.332440641, - 0.05 - ], - [ - 223042.15460274566, - 6758087.2145074485, - 0.05 - ], - [ - 223034.86508245015, - 6758076.835551261, - 0.05 - ], - [ - 222967.97005094227, - 6757985.157016971, - 0.05 - ], - [ - 222922.57283470267, - 6757921.7139661, - 0.05 - ], - [ - 222878.74553032068, - 6757861.053535005, - 0.05 - ], - [ - 222864.19594386232, - 6757858.050527286, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 74, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223049.95491888328, - 6758098.332440641, - 0.05 - ], - [ - 223015.6432518944, - 6758123.133605605, - 0.05 - ], - [ - 223006.33932329604, - 6758129.860820169, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 75, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223211.7051255203, - 6758248.989139947, - 0.05 - ], - [ - 223212.8724068384, - 6758247.713204102, - 0.05 - ], - [ - 223213.3373596453, - 6758246.304553822, - 0.05 - ], - [ - 223213.2164887564, - 6758244.80950395, - 0.05 - ], - [ - 223213.04899888847, - 6758239.762384608, - 0.05 - ], - [ - 223213.72975755355, - 6758236.931786728, - 0.05 - ], - [ - 223215.64848890278, - 6758234.25747977, - 0.05 - ], - [ - 223232.56813885993, - 6758218.331850263, - 0.05 - ], - [ - 223279.2918326414, - 6758171.405392672, - 0.05 - ], - [ - 223300.43200008955, - 6758151.51611301, - 0.05 - ], - [ - 223313.02103616414, - 6758140.321502382, - 0.05 - ], - [ - 223380.49850095587, - 6758072.423405668, - 0.05 - ], - [ - 223404.67507206538, - 6758049.168072517, - 0.05 - ], - [ - 223417.01238239696, - 6758038.016357926, - 0.05 - ], - [ - 223450.67587434588, - 6757924.786965601, - 0.05 - ], - [ - 223456.13294535677, - 6757906.3551329225, - 0.05 - ], - [ - 223465.8181070608, - 6757871.864737982, - 0.05 - ], - [ - 223446.70559147978, - 6757832.946280301, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 76, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223446.70559147978, - 6757832.946280301, - 0.05 - ], - [ - 223421.0647287175, - 6757795.39140718, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 77, - "lwd63": 75.90171332041136, - "lwd125": 66.50354895698379, - "lwd250": 65.07810131032979, - "lwd500": 67.03547618298532, - "lwd1000": 68.69573012731246, - "lwd2000": 63.98750464460184, - "lwd4000": 59.83951230326983, - "lwd8000": 52.46266685676584, - "lwe63": 70.43578425158094, - "lwe125": 61.037628557169114, - "lwe250": 59.612184715440435, - "lwe500": 61.569554654148824, - "lwe1000": 63.22980584560604, - "lwe2000": 58.52159193169619, - "lwe4000": 54.37362754144347, - "lwe8000": 46.99698499689735, - "lwn63": 67.42548586626533, - "lwn125": 58.02734228036127, - "lwn250": 56.601903753170085, - "lwn500": 58.55926680037521, - "lwn1000": 60.21951414674617, - "lwn2000": 55.51131639158329, - "lwn4000": 51.363391041634046, - "lwn8000": 43.98703187968516 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223421.0647287175, - 6757795.39140718, - 0.05 - ], - [ - 223414.110046966, - 6757788.9643669855, - 0.05 - ], - [ - 223317.49191379594, - 6757699.69528231, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 78, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223324.13984396379, - 6758204.966022049, - 0.05 - ], - [ - 223319.17158071068, - 6758200.697085363, - 0.05 - ], - [ - 223317.4151627897, - 6758198.776894793, - 0.05 - ], - [ - 223315.46128632815, - 6758196.738903396, - 0.05 - ], - [ - 223314.41329300002, - 6758193.724798675, - 0.05 - ], - [ - 223313.91806009272, - 6758189.830003882, - 0.05 - ], - [ - 223313.02103616414, - 6758140.321502382, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 79, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223380.49850095587, - 6758072.423405668, - 0.05 - ], - [ - 223411.564111698, - 6758101.112732326, - 0.05 - ], - [ - 223415.65680603817, - 6758104.872867695, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 80, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223188.96104832, - 6757567.149531239, - 0.05 - ], - [ - 223182.9774905509, - 6757557.489681543, - 0.05 - ], - [ - 223175.145407909, - 6757544.401160441, - 0.05 - ], - [ - 223135.49217206618, - 6757499.185365867, - 0.05 - ], - [ - 223051.25396718702, - 6757402.364861867, - 0.05 - ], - [ - 222892.00285487785, - 6757253.716097861, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 81, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223022.0177427327, - 6757571.329241517, - 0.05 - ], - [ - 223021.71961308754, - 6757561.5998911485, - 0.05 - ], - [ - 223020.32799959445, - 6757555.826915345, - 0.05 - ], - [ - 222962.47116848588, - 6757493.781269211, - 0.05 - ], - [ - 222895.50380979752, - 6757421.549175495, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 82, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222920.733188781, - 6757380.617186885, - 0.05 - ], - [ - 223004.07695807423, - 6757455.00294757, - 0.05 - ], - [ - 223115.81676576898, - 6757552.374677453, - 0.05 - ], - [ - 223117.80035302992, - 6757559.426273579, - 0.05 - ], - [ - 223118.69470091572, - 6757568.906767183, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 83, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222962.47116848588, - 6757493.781269211, - 0.05 - ], - [ - 223004.07695807423, - 6757455.00294757, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 84, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223117.55788298085, - 6757314.562072731, - 0.05 - ], - [ - 223164.60882343183, - 6757472.286125688, - 0.05 - ], - [ - 223135.49217206618, - 6757499.185365867, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 85, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223076.40793586458, - 6757299.954046724, - 0.05 - ], - [ - 223101.32721231296, - 6757221.873563437, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 86, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222890.5066154126, - 6757229.26955879, - 0.05 - ], - [ - 222897.48695280025, - 6757230.421544441, - 0.05 - ], - [ - 223062.88310950896, - 6757294.482189977, - 0.05 - ], - [ - 223076.40793586458, - 6757299.954046724, - 0.05 - ], - [ - 223117.55788298085, - 6757314.562072731, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 87, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223244.99588302913, - 6757176.128015889, - 0.05 - ], - [ - 223162.64950737037, - 6757180.577375127, - 0.05 - ], - [ - 223129.9370130995, - 6757173.156456675, - 0.05 - ], - [ - 223049.37829807785, - 6757151.457424938, - 0.05 - ], - [ - 222914.3977112671, - 6757100.107519836, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 88, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223129.9370130995, - 6757173.156456675, - 0.05 - ], - [ - 223145.84423495881, - 6757118.811828026, - 0.05 - ], - [ - 223150.60844169674, - 6757114.034850968, - 0.05 - ], - [ - 223189.75480447634, - 6757108.496032372, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 89, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224210.40410070738, - 6758682.105186451, - 0.05 - ], - [ - 224201.05188852776, - 6758688.700648532, - 0.05 - ], - [ - 224196.64511743112, - 6758691.842893456, - 0.05 - ], - [ - 224190.35367225116, - 6758694.078274091, - 0.05 - ], - [ - 224176.79452932277, - 6758697.535452137, - 0.05 - ], - [ - 224153.06763824623, - 6758702.883218087, - 0.05 - ], - [ - 224133.2948997385, - 6758705.348243219, - 0.05 - ], - [ - 224113.37528220692, - 6758706.086299261, - 0.05 - ], - [ - 224094.78909764404, - 6758705.557548723, - 0.05 - ], - [ - 223979.2846778049, - 6758691.171248743, - 0.05 - ], - [ - 223905.45051784615, - 6758681.515266305, - 0.05 - ], - [ - 223826.55977369874, - 6758669.470658702, - 0.05 - ], - [ - 223769.62204948516, - 6758662.788074074, - 0.05 - ], - [ - 223752.13520123594, - 6758660.332384499, - 0.05 - ], - [ - 223750.04620215332, - 6758658.851372794, - 0.05 - ], - [ - 223749.27077212016, - 6758656.69578926, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 90, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223826.55977369874, - 6758669.470658702, - 0.05 - ], - [ - 223868.17758689454, - 6758559.680957307, - 0.05 - ], - [ - 223897.07810111425, - 6758485.919225039, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 91, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224016.07165179832, - 6758600.566131291, - 0.05 - ], - [ - 223918.96963218693, - 6758574.028061336, - 0.05 - ], - [ - 223868.17758689454, - 6758559.680957307, - 0.05 - ], - [ - 223790.92319821648, - 6758541.48532665, - 0.05 - ], - [ - 223773.73841440765, - 6758538.492403892, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 92, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223979.2846778049, - 6758691.171248743, - 0.05 - ], - [ - 224016.07165179832, - 6758600.566131291, - 0.05 - ], - [ - 224036.08295542002, - 6758555.79078918, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 93, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223905.45051784615, - 6758681.515266305, - 0.05 - ], - [ - 223918.96963218693, - 6758574.028061336, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 94, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223727.14714239357, - 6758664.212028575, - 0.05 - ], - [ - 224094.84357192984, - 6758716.19828064, - 0.05 - ], - [ - 224114.13197045354, - 6758716.85985369, - 0.05 - ], - [ - 224134.68281625892, - 6758715.747603633, - 0.05 - ], - [ - 224155.04357763735, - 6758713.770172973, - 0.05 - ], - [ - 224180.41957314406, - 6758709.95020632, - 0.05 - ], - [ - 224210.7200152608, - 6758701.764791916, - 0.05 - ], - [ - 224219.19192366808, - 6758698.885344034, - 0.05 - ], - [ - 224227.48371401272, - 6758696.009294435, - 0.05 - ], - [ - 224234.32978606888, - 6758692.91549675, - 0.05 - ], - [ - 224258.8533352589, - 6758679.366698773, - 0.05 - ], - [ - 224276.85483131185, - 6758667.057549597, - 0.05 - ], - [ - 224297.05548153247, - 6758650.2349920375, - 0.05 - ], - [ - 224318.5907458812, - 6758632.903575814, - 0.05 - ], - [ - 224330.78483152937, - 6758627.617326603, - 0.05 - ], - [ - 224344.05637426028, - 6758624.785640658, - 0.05 - ], - [ - 224367.611580113, - 6758624.20101417, - 0.05 - ], - [ - 224388.23639404762, - 6758628.010539167, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 95, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223897.07810111425, - 6758485.919225039, - 0.05 - ], - [ - 223909.46710657357, - 6758450.085446575, - 0.05 - ], - [ - 223967.92616166716, - 6758464.326805231, - 0.05 - ], - [ - 224008.12877338234, - 6758476.0851859655, - 0.05 - ], - [ - 224004.17886392534, - 6758533.68705542, - 0.05 - ], - [ - 224001.59375400434, - 6758537.886249308, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 96, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223967.92616166716, - 6758464.326805231, - 0.05 - ], - [ - 223946.58493491774, - 6758388.055863909, - 0.05 - ], - [ - 223942.5501431906, - 6758373.64559523, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 97, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224337.74457495078, - 6758557.344553268, - 0.05 - ], - [ - 224327.89321235399, - 6758581.145944744, - 0.05 - ], - [ - 224317.35633275087, - 6758600.454809499, - 0.05 - ], - [ - 224306.24361412297, - 6758616.1651830245, - 0.05 - ], - [ - 224293.36172036384, - 6758629.231627609, - 0.05 - ], - [ - 224277.90095199068, - 6758640.332542414, - 0.05 - ], - [ - 224266.5202685768, - 6758648.339961129, - 0.05 - ], - [ - 224251.87095330562, - 6758658.037884829, - 0.05 - ], - [ - 224243.23906010092, - 6758662.568752634, - 0.05 - ], - [ - 224234.65730820812, - 6758664.832807128, - 0.05 - ], - [ - 224224.01368906104, - 6758666.416079432, - 0.05 - ], - [ - 224216.8366823112, - 6758671.743636021, - 0.05 - ], - [ - 224210.40410070738, - 6758682.105186451, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 98, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224122.70078362944, - 6758611.511757277, - 0.05 - ], - [ - 224147.08576106, - 6758562.894982104, - 0.05 - ], - [ - 224221.44860759488, - 6758597.357397007, - 0.05 - ], - [ - 224231.62426346645, - 6758575.903874703, - 0.05 - ], - [ - 224305.0183918352, - 6758542.55094868, - 0.05 - ], - [ - 224337.74457495078, - 6758557.344553268, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 99, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224188.6683909609, - 6758561.401186198, - 0.05 - ], - [ - 224220.58649715455, - 6758573.628739886, - 0.05 - ], - [ - 224231.62426346645, - 6758575.903874703, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 100, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223960.2186804008, - 6758258.400120296, - 0.05 - ], - [ - 224007.76893144968, - 6758269.81071763, - 0.05 - ], - [ - 224044.44048763858, - 6758278.599591945, - 0.05 - ], - [ - 224058.32349956053, - 6758281.937836323, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 101, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224045.5435330086, - 6757795.502076778, - 0.05 - ], - [ - 224045.2501884693, - 6757797.922285192, - 0.05 - ], - [ - 224031.6215927513, - 6757834.825267442, - 0.05 - ], - [ - 224000.9652368832, - 6757919.227569221, - 0.05 - ], - [ - 223976.812868856, - 6757983.88825964, - 0.05 - ], - [ - 223961.67287075322, - 6758027.200244883, - 0.05 - ], - [ - 223945.52312366676, - 6758070.292843957, - 0.05 - ], - [ - 223932.1610141935, - 6758110.106287788, - 0.05 - ], - [ - 223901.30390191014, - 6758193.6562288385, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 102, - "lwd63": 79.34379918076603, - "lwd125": 71.62531343283393, - "lwd250": 71.32317717306759, - "lwd500": 73.3559386245894, - "lwd1000": 77.77430854000383, - "lwd2000": 75.55868033926954, - "lwd4000": 67.3990949432874, - "lwd8000": 58.71928948033953, - "lwe63": 73.83994803251942, - "lwe125": 66.12146481748954, - "lwe250": 65.81932877734933, - "lwe500": 67.85208900733588, - "lwe1000": 72.27045761616219, - "lwe2000": 70.05482990788161, - "lwe4000": 61.895251346191486, - "lwe8000": 53.21549733768662, - "lwn63": 70.82964879342514, - "lwn125": 63.111169104089846, - "lwn250": 62.80903336965987, - "lwn500": 64.84179189932092, - "lwn1000": 69.26015868943053, - "lwn2000": 67.04453166662529, - "lwn4000": 58.88496261797058, - "lwn8000": 50.205280230648796 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223997.03482891602, - 6758129.927589925, - 0.05 - ], - [ - 223932.1610141935, - 6758110.106287788, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 103, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223961.67287075322, - 6758027.200244883, - 0.05 - ], - [ - 224026.87962997996, - 6758048.343802291, - 0.05 - ], - [ - 224093.64909257187, - 6758070.041886768, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 104, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224043.65408792876, - 6758002.73764634, - 0.05 - ], - [ - 224109.30106265406, - 6758026.544074643, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 105, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224000.9652368832, - 6757919.227569221, - 0.05 - ], - [ - 224064.9164243451, - 6757944.084474925, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 106, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224005.20082664466, - 6757772.652347919, - 0.05 - ], - [ - 224010.03639492596, - 6757777.423000429, - 0.05 - ], - [ - 224030.798176397, - 6757785.3112886725, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 107, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224055.30025435, - 6757720.957184447, - 0.05 - ], - [ - 224062.54757489567, - 6757721.330962259, - 0.05 - ], - [ - 224104.53770708613, - 6757735.621275789, - 0.05 - ], - [ - 224125.39703106426, - 6757742.855517578, - 0.05 - ], - [ - 224136.78836546442, - 6757747.1641924875, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 108, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224132.90093937342, - 6757757.777361308, - 0.05 - ], - [ - 224197.13816108461, - 6757781.230496689, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 109, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224159.47013051796, - 6757684.272809163, - 0.05 - ], - [ - 224223.27601169806, - 6757706.378887532, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 110, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224058.19877274125, - 6757963.219256706, - 0.05 - ], - [ - 224123.28605090873, - 6757986.513697589, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 111, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224071.2201363616, - 6757927.179006507, - 0.05 - ], - [ - 224136.36357866944, - 6757950.513667039, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 112, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223708.05052675394, - 6758575.097639576, - 0.05 - ], - [ - 223701.20379337046, - 6758575.204769423, - 0.05 - ], - [ - 223693.40063803847, - 6758574.731497713, - 0.05 - ], - [ - 223681.65485724388, - 6758572.815498821, - 0.05 - ], - [ - 223667.19494155463, - 6758570.427655271, - 0.05 - ], - [ - 223622.77318315214, - 6758563.114424146, - 0.05 - ], - [ - 223568.58472358662, - 6758554.194013108, - 0.05 - ], - [ - 223548.1064532146, - 6758541.2350609545, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 113, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223531.024064507, - 6758527.790004899, - 0.05 - ], - [ - 223535.22688626964, - 6758498.95920837, - 0.05 - ], - [ - 223541.99898291932, - 6758459.688080074, - 0.05 - ], - [ - 223544.91079041845, - 6758442.788364785, - 0.05 - ], - [ - 223557.33756138326, - 6758371.436981824, - 0.05 - ], - [ - 223565.91535542381, - 6758321.107351169, - 0.05 - ], - [ - 223566.2639562867, - 6758319.095060915, - 0.05 - ], - [ - 223568.58817818027, - 6758305.620327218, - 0.05 - ], - [ - 223575.72567238554, - 6758264.257644776, - 0.05 - ], - [ - 223579.19166911521, - 6758255.517237784, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 114, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223575.1271053183, - 6758248.56675186, - 0.05 - ], - [ - 223573.3910534148, - 6758246.990397362, - 0.05 - ], - [ - 223539.07084194594, - 6758188.2328790575, - 0.05 - ], - [ - 223528.14520931506, - 6758170.611933589, - 0.05 - ], - [ - 223523.15780751838, - 6758156.334575837, - 0.05 - ], - [ - 223520.56286846445, - 6758149.989925547, - 0.05 - ], - [ - 223516.4440100717, - 6758139.298542582, - 0.05 - ], - [ - 223511.47213072132, - 6758131.540803831, - 0.05 - ], - [ - 223508.90633075644, - 6758128.348341589, - 0.05 - ], - [ - 223507.25961788784, - 6758126.2966205655, - 0.05 - ], - [ - 223495.3374296266, - 6758109.090646604, - 0.05 - ], - [ - 223483.12068665726, - 6758093.636243639, - 0.05 - ], - [ - 223482.1132039334, - 6758092.145951978, - 0.05 - ], - [ - 223481.000501692, - 6758091.121180142, - 0.05 - ], - [ - 223474.49337777082, - 6758084.925450088, - 0.05 - ], - [ - 223470.83049005194, - 6758082.111464099, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 115, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223483.99534606427, - 6758078.038108847, - 0.05 - ], - [ - 223484.9139911019, - 6758080.382733995, - 0.05 - ], - [ - 223489.0741239736, - 6758086.745814064, - 0.05 - ], - [ - 223502.94057690713, - 6758104.195972248, - 0.05 - ], - [ - 223517.12445619196, - 6758122.133263785, - 0.05 - ], - [ - 223526.93589134765, - 6758135.17371323, - 0.05 - ], - [ - 223537.18082021707, - 6758147.811310501, - 0.05 - ], - [ - 223549.09760219452, - 6758159.555874311, - 0.05 - ], - [ - 223570.47367341403, - 6758195.059174916, - 0.05 - ], - [ - 223589.58823914215, - 6758233.465044367, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 116, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223596.6335287115, - 6758241.021903064, - 0.05 - ], - [ - 223646.08932918002, - 6758258.138931462, - 0.05 - ], - [ - 223750.2597980427, - 6758292.71859627, - 0.05 - ], - [ - 223832.37665338878, - 6758319.238072914, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 117, - "lwd63": 76.31779255765063, - "lwd125": 68.59930780970882, - "lwd250": 68.29717163665092, - "lwd500": 70.32993260591032, - "lwd1000": 74.74830200548354, - "lwd2000": 72.53267399917006, - "lwd4000": 64.37309130136873, - "lwd8000": 55.69330615273513, - "lwe63": 70.80731998649959, - "lwe125": 63.088840333511655, - "lwe250": 62.78670460223332, - "lwe500": 64.81946311436528, - "lwe1000": 69.2378298857252, - "lwe2000": 67.02220286998673, - "lwe4000": 58.862633919404395, - "lwe8000": 50.182952270437255, - "lwn63": 67.79702147234785, - "lwn125": 60.07854890708419, - "lwn250": 59.776413790376104, - "lwn500": 61.80916888433674, - "lwn1000": 66.22753199951853, - "lwn2000": 64.0119063617962, - "lwn4000": 55.85235653527084, - "lwn8000": 47.17281886230607 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223843.35092217074, - 6758348.9274980435, - 0.05 - ], - [ - 223824.33840827126, - 6758341.924229127, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 118, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223296.23410012992, - 6758293.486875775, - 0.05 - ], - [ - 223300.06700997642, - 6758289.197633016, - 0.05 - ], - [ - 223336.32791557832, - 6758252.614429274, - 0.05 - ], - [ - 223361.78943178552, - 6758227.783589233, - 0.05 - ], - [ - 223373.77404773375, - 6758216.459600179, - 0.05 - ], - [ - 223386.1575717199, - 6758204.768996881, - 0.05 - ], - [ - 223391.83918640448, - 6758200.843170759, - 0.05 - ], - [ - 223396.14185672527, - 6758199.2024168335, - 0.05 - ], - [ - 223400.19466810417, - 6758198.562776871, - 0.05 - ], - [ - 223405.81872836075, - 6758199.133776224, - 0.05 - ], - [ - 223424.31305801903, - 6758203.524710511, - 0.05 - ], - [ - 223431.49925562815, - 6758203.891468375, - 0.05 - ], - [ - 223438.0604507379, - 6758202.012501042, - 0.05 - ], - [ - 223443.45674352272, - 6758198.555655469, - 0.05 - ], - [ - 223504.2694219951, - 6758138.041692738, - 0.05 - ], - [ - 223505.47440407786, - 6758136.9522710955, - 0.05 - ], - [ - 223511.47213072132, - 6758131.540803831, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 119, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223314.39924109064, - 6758311.5700625, - 0.05 - ], - [ - 223333.97791407007, - 6758292.92175411, - 0.05 - ], - [ - 223343.11097835825, - 6758292.451081283, - 0.05 - ], - [ - 223359.65335162298, - 6758309.339087259, - 0.05 - ], - [ - 223359.78130747454, - 6758317.1538077295, - 0.05 - ], - [ - 223339.43871771474, - 6758336.488000633, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 120, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223372.24445729784, - 6758370.442629317, - 0.05 - ], - [ - 223435.29520844133, - 6758307.796128067, - 0.05 - ], - [ - 223439.42312985705, - 6758300.272863686, - 0.05 - ], - [ - 223440.79814451933, - 6758293.194999599, - 0.05 - ], - [ - 223463.49464752147, - 6758271.5419497555, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 121, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223361.78943178552, - 6758227.783589233, - 0.05 - ], - [ - 223430.63704186142, - 6758297.036904721, - 0.05 - ], - [ - 223439.42312985705, - 6758300.272863686, - 0.05 - ], - [ - 223450.85385730985, - 6758299.02590291, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 122, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223450.85385730985, - 6758299.02590291, - 0.05 - ], - [ - 223487.32165921095, - 6758334.769653129, - 0.05 - ], - [ - 223490.46832269098, - 6758341.337235232, - 0.05 - ], - [ - 223491.35321335058, - 6758348.288215571, - 0.05 - ], - [ - 223475.685997001, - 6758446.50904912, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 123, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223509.07315608143, - 6758454.278117873, - 0.05 - ], - [ - 223523.31789880502, - 6758366.171012063, - 0.05 - ], - [ - 223529.52910997375, - 6758327.491416818, - 0.05 - ], - [ - 223531.99025113002, - 6758314.875048352, - 0.05 - ], - [ - 223533.2750880319, - 6758308.261517541, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 124, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223523.31789880502, - 6758366.171012063, - 0.05 - ], - [ - 223548.25596009672, - 6758370.030515103, - 0.05 - ], - [ - 223557.33756138326, - 6758371.436981824, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 125, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223535.22688626964, - 6758498.95920837, - 0.05 - ], - [ - 223691.79260544875, - 6758513.687855566, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 126, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223544.91079041845, - 6758442.788364785, - 0.05 - ], - [ - 223583.3591710797, - 6758446.492785343, - 0.05 - ], - [ - 223638.98542921746, - 6758453.38001171, - 0.05 - ], - [ - 223696.30007593991, - 6758461.2572049685, - 0.05 - ], - [ - 223701.180590611, - 6758461.933105547, - 0.05 - ], - [ - 223714.21121947432, - 6758466.911069858, - 0.05 - ], - [ - 223718.38389576733, - 6758468.502454334, - 0.05 - ], - [ - 223778.6348313429, - 6758470.391546648, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 127, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223604.20364253485, - 6758323.565312729, - 0.05 - ], - [ - 223628.9866355895, - 6758332.297684093, - 0.05 - ], - [ - 223664.8107725485, - 6758344.920290725, - 0.05 - ], - [ - 223728.89846878895, - 6758368.703422172, - 0.05 - ], - [ - 223805.2718988263, - 6758395.507965958, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 128, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223739.11484217487, - 6758581.483844908, - 0.05 - ], - [ - 223741.23462308286, - 6758575.527469984, - 0.05 - ], - [ - 223761.17540278478, - 6758519.476218619, - 0.05 - ], - [ - 223778.6348313429, - 6758470.391546648, - 0.05 - ], - [ - 223805.2718988263, - 6758395.507965958, - 0.05 - ], - [ - 223824.33840827126, - 6758341.924229127, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 129, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223824.33840827126, - 6758341.924229127, - 0.05 - ], - [ - 223744.189045695, - 6758316.773095658, - 0.05 - ], - [ - 223678.7166458881, - 6758296.233849301, - 0.05 - ], - [ - 223638.0457427021, - 6758280.379941587, - 0.05 - ], - [ - 223590.85127391026, - 6758260.917837311, - 0.05 - ], - [ - 223584.71474366466, - 6758255.583807795, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 130, - "lwd63": 76.31779255765063, - "lwd125": 68.59930780970882, - "lwd250": 68.29717163665092, - "lwd500": 70.32993260591032, - "lwd1000": 74.74830200548354, - "lwd2000": 72.53267399917006, - "lwd4000": 64.37309130136873, - "lwd8000": 55.69330615273513, - "lwe63": 70.80731998649959, - "lwe125": 63.088840333511655, - "lwe250": 62.78670460223332, - "lwe500": 64.81946311436528, - "lwe1000": 69.2378298857252, - "lwe2000": 67.02220286998673, - "lwe4000": 58.862633919404395, - "lwe8000": 50.182952270437255, - "lwn63": 67.79702147234785, - "lwn125": 60.07854890708419, - "lwn250": 59.776413790376104, - "lwn500": 61.80916888433674, - "lwn1000": 66.22753199951853, - "lwn2000": 64.0119063617962, - "lwn4000": 55.85235653527084, - "lwn8000": 47.17281886230607 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223583.3591710797, - 6758446.492785343, - 0.05 - ], - [ - 223604.20364253485, - 6758323.565312729, - 0.05 - ], - [ - 223619.2163916924, - 6758304.406262953, - 0.05 - ], - [ - 223638.0457427021, - 6758280.379941587, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 131, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223664.8107725485, - 6758344.920290725, - 0.05 - ], - [ - 223638.98542921746, - 6758453.38001171, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 132, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223691.79260544875, - 6758513.687855566, - 0.05 - ], - [ - 223699.3448316544, - 6758472.0577373905, - 0.05 - ], - [ - 223701.180590611, - 6758461.933105547, - 0.05 - ], - [ - 223703.4574919155, - 6758454.292015882, - 0.05 - ], - [ - 223728.89846878895, - 6758368.703422172, - 0.05 - ], - [ - 223744.189045695, - 6758316.773095658, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 133, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223776.48632921802, - 6758198.963277064, - 0.05 - ], - [ - 223750.2597980427, - 6758292.71859627, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 134, - "lwd63": 75.90171332041136, - "lwd125": 66.50354895698379, - "lwd250": 65.07810131032979, - "lwd500": 67.03547618298532, - "lwd1000": 68.69573012731246, - "lwd2000": 63.98750464460184, - "lwd4000": 59.83951230326983, - "lwd8000": 52.46266685676584, - "lwe63": 70.43578425158094, - "lwe125": 61.037628557169114, - "lwe250": 59.612184715440435, - "lwe500": 61.569554654148824, - "lwe1000": 63.22980584560604, - "lwe2000": 58.52159193169619, - "lwe4000": 54.37362754144347, - "lwe8000": 46.99698499689735, - "lwn63": 67.42548586626533, - "lwn125": 58.02734228036127, - "lwn250": 56.601903753170085, - "lwn500": 58.55926680037521, - "lwn1000": 60.21951414674617, - "lwn2000": 55.51131639158329, - "lwn4000": 51.363391041634046, - "lwn8000": 43.98703187968516 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223832.37665338878, - 6758319.238072914, - 0.05 - ], - [ - 223851.83412153396, - 6758325.793016437, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 135, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223863.5358029828, - 6758348.479320249, - 0.05 - ], - [ - 223822.47183111892, - 6758458.636512909, - 0.05 - ], - [ - 223790.92319821648, - 6758541.48532665, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 136, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223815.15566744428, - 6758055.681790359, - 0.05 - ], - [ - 223818.41665976332, - 6758061.248228377, - 0.05 - ], - [ - 223833.72793026472, - 6758087.388341892, - 0.05 - ], - [ - 223848.69104990351, - 6758113.500863788, - 0.05 - ], - [ - 223862.21652518876, - 6758145.737572372, - 0.05 - ], - [ - 223865.45852903457, - 6758161.125831776, - 0.05 - ], - [ - 223878.0554356475, - 6758220.9699596455, - 0.05 - ], - [ - 223887.76567067712, - 6758231.745176058, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 137, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223759.2231164187, - 6757985.180685158, - 0.05 - ], - [ - 223777.17842379573, - 6757993.227812145, - 0.05 - ], - [ - 223815.15566744428, - 6758055.681790359, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 138, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223887.76567067712, - 6758231.745176058, - 0.05 - ], - [ - 223893.80987842864, - 6758228.024661991, - 0.05 - ], - [ - 223900.57712989382, - 6758223.855647548, - 0.05 - ], - [ - 223923.54145811684, - 6758215.090801324, - 0.05 - ], - [ - 223943.5534923753, - 6758205.884417241, - 0.05 - ], - [ - 223963.06717470067, - 6758191.434789596, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 139, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223672.00913097762, - 6757856.701906405, - 0.05 - ], - [ - 223678.63233874325, - 6757858.284871092, - 0.05 - ], - [ - 223681.99078041542, - 6757863.007370607, - 0.05 - ], - [ - 223719.1262557106, - 6757915.2961122235, - 0.05 - ], - [ - 223757.3242429872, - 6757981.8673883565, - 0.05 - ], - [ - 223759.2231164187, - 6757985.180685158, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 140, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223617.42078127066, - 6757862.916722211, - 0.05 - ], - [ - 223672.00913097762, - 6757856.701906405, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 141, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223611.65155323996, - 6757889.031388534, - 0.05 - ], - [ - 223617.42078127066, - 6757862.916722211, - 0.05 - ], - [ - 223622.57377962815, - 6757847.7867977, - 0.05 - ], - [ - 223629.71094852587, - 6757839.630530944, - 0.05 - ], - [ - 223652.45625289757, - 6757822.366325524, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 142, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223650.7126124447, - 6757958.731476305, - 0.05 - ], - [ - 223644.5731531753, - 6757962.9503726885, - 0.05 - ], - [ - 223615.68527921755, - 6757958.60682496, - 0.05 - ], - [ - 223589.14998950285, - 6757950.629026137, - 0.05 - ], - [ - 223543.21373526618, - 6757936.817211822, - 0.05 - ], - [ - 223533.7286703947, - 6757933.960794108, - 0.05 - ], - [ - 223529.14000668103, - 6757932.436558988, - 0.05 - ], - [ - 223518.51734811877, - 6757928.992117789, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 143, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223615.68527921755, - 6757958.60682496, - 0.05 - ], - [ - 223617.08699503104, - 6757953.0651337905, - 0.05 - ], - [ - 223623.98522325727, - 6757932.08709094, - 0.05 - ], - [ - 223626.02620993048, - 6757928.968345701, - 0.05 - ], - [ - 223631.35828888224, - 6757925.829000383, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 144, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223611.65155323996, - 6757889.031388534, - 0.05 - ], - [ - 223617.18458732124, - 6757903.922383454, - 0.05 - ], - [ - 223631.35828888224, - 6757925.829000383, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 145, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223594.78297781682, - 6758235.88782489, - 0.05 - ], - [ - 223678.31018796685, - 6758155.594572566, - 0.05 - ], - [ - 223733.7325538108, - 6758102.306924174, - 0.05 - ], - [ - 223798.60120698542, - 6758065.16672637, - 0.05 - ], - [ - 223815.15566744428, - 6758055.681790359, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 146, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223486.55001164292, - 6758072.904818762, - 0.05 - ], - [ - 223489.26881524484, - 6758073.710647111, - 0.05 - ], - [ - 223496.85315640975, - 6758075.839957497, - 0.05 - ], - [ - 223567.54793632327, - 6758095.008041046, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 147, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223567.54793632327, - 6758095.008041046, - 0.05 - ], - [ - 223614.72110327944, - 6758068.402212047, - 0.05 - ], - [ - 223640.9567807928, - 6758053.598028247, - 0.05 - ], - [ - 223690.56771576055, - 6758025.6144030085, - 0.05 - ], - [ - 223752.9121375975, - 6757992.76848323, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 148, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223776.48632921802, - 6758198.963277064, - 0.05 - ], - [ - 223785.63170126884, - 6758222.5692700725, - 0.05 - ], - [ - 223832.45087734074, - 6758238.228716796, - 0.05 - ], - [ - 223879.3071279502, - 6758253.885521812, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 149, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223815.15566744428, - 6758055.681790359, - 0.05 - ], - [ - 223874.75895594835, - 6758021.564839605, - 0.05 - ], - [ - 223865.16959553672, - 6758003.723998708, - 0.05 - ], - [ - 223857.33172733, - 6757989.141513106, - 0.05 - ], - [ - 223842.11491132347, - 6757960.820106648, - 0.05 - ], - [ - 223834.27694535744, - 6757946.237654299, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 150, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223874.75895594835, - 6758021.564839605, - 0.05 - ], - [ - 223954.86178574176, - 6757975.694916152, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 151, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223976.812868856, - 6757983.88825964, - 0.05 - ], - [ - 223954.86178574176, - 6757975.694916152, - 0.05 - ], - [ - 223952.4836955387, - 6757970.168613005, - 0.05 - ], - [ - 223947.8209659803, - 6757959.342546573, - 0.05 - ], - [ - 223928.7136384023, - 6757914.949336436, - 0.05 - ], - [ - 223927.4741077844, - 6757912.073224023, - 0.05 - ], - [ - 223920.97932381416, - 6757896.992114747, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 152, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223834.27694535744, - 6757946.237654299, - 0.05 - ], - [ - 223920.97932381416, - 6757896.992114747, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 153, - "lwd63": 75.90171332041136, - "lwd125": 66.50354895698379, - "lwd250": 65.07810131032979, - "lwd500": 67.03547618298532, - "lwd1000": 68.69573012731246, - "lwd2000": 63.98750464460184, - "lwd4000": 59.83951230326983, - "lwd8000": 52.46266685676584, - "lwe63": 70.43578425158094, - "lwe125": 61.037628557169114, - "lwe250": 59.612184715440435, - "lwe500": 61.569554654148824, - "lwe1000": 63.22980584560604, - "lwe2000": 58.52159193169619, - "lwe4000": 54.37362754144347, - "lwe8000": 46.99698499689735, - "lwn63": 67.42548586626533, - "lwn125": 58.02734228036127, - "lwn250": 56.601903753170085, - "lwn500": 58.55926680037521, - "lwn1000": 60.21951414674617, - "lwn2000": 55.51131639158329, - "lwn4000": 51.363391041634046, - "lwn8000": 43.98703187968516 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223732.31190165982, - 6757765.221865437, - 0.05 - ], - [ - 223752.719664147, - 6757801.8628955865, - 0.05 - ], - [ - 223755.24336565635, - 6757806.396463513, - 0.05 - ], - [ - 223758.50325398456, - 6757812.319659519, - 0.05 - ], - [ - 223785.6701732289, - 6757861.635001898, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 154, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223988.27329111466, - 6757736.543391362, - 0.05 - ], - [ - 223981.35164922668, - 6757740.111638515, - 0.05 - ], - [ - 223925.17755612085, - 6757779.780105187, - 0.05 - ], - [ - 223880.47611838486, - 6757808.457519478, - 0.05 - ], - [ - 223848.6950025402, - 6757829.181226255, - 0.05 - ], - [ - 223789.06824008975, - 6757868.05980375, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 155, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223652.45625289757, - 6757822.366325524, - 0.05 - ], - [ - 223657.6092819473, - 6757818.684139001, - 0.05 - ], - [ - 223690.91558466933, - 6757794.882304627, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 156, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223733.37595198653, - 6757821.03675253, - 0.05 - ], - [ - 223736.77656122862, - 6757827.026601576, - 0.05 - ], - [ - 223755.98065984627, - 6757860.86668975, - 0.05 - ], - [ - 223785.6701732289, - 6757861.635001898, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 157, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224005.20082664466, - 6757772.652347919, - 0.05 - ], - [ - 224002.25871521968, - 6757766.937468866, - 0.05 - ], - [ - 223990.44245369808, - 6757741.25056696, - 0.05 - ], - [ - 223988.27329111466, - 6757736.543391362, - 0.05 - ], - [ - 223968.31472772598, - 6757693.155104306, - 0.05 - ], - [ - 223965.60563127534, - 6757687.254233055, - 0.05 - ], - [ - 223963.14468138973, - 6757681.912961694, - 0.05 - ], - [ - 223936.98888437584, - 6757628.346438769, - 0.05 - ], - [ - 223933.58399577602, - 6757622.022434104, - 0.05 - ], - [ - 223930.77666590392, - 6757616.95435953, - 0.05 - ], - [ - 223906.3081278265, - 6757574.610226922, - 0.05 - ], - [ - 223901.03036344144, - 6757566.04088129, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 158, - "lwd63": 79.58541795648755, - "lwd125": 75.01138955005958, - "lwd250": 73.4660816531774, - "lwd500": 76.2201230648869, - "lwd1000": 79.81013336156867, - "lwd2000": 73.43206404074253, - "lwd4000": 67.49528740241702, - "lwd8000": 59.71607348100428, - "lwe63": 74.08156678034479, - "lwe125": 69.50753928418013, - "lwe250": 67.96223198467482, - "lwe500": 70.71627245940243, - "lwe1000": 74.30628216083798, - "lwe2000": 67.92821438792969, - "lwe4000": 61.99144362861625, - "lwe8000": 54.21226913163469, - "lwn63": 71.07126750242018, - "lwn125": 66.49724127330482, - "lwn250": 64.95193480532332, - "lwn500": 67.7059739758109, - "lwn1000": 71.29598284868798, - "lwn2000": 64.91791723041766, - "lwn4000": 58.981154654430384, - "lwn8000": 51.20203503383784 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224020.22678229434, - 6757657.76588376, - 0.05 - ], - [ - 224014.98396055313, - 6757660.618969479, - 0.05 - ], - [ - 223972.72932081245, - 6757683.5804918725, - 0.05 - ], - [ - 223965.60563127534, - 6757687.254233055, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 159, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224030.798176397, - 6757785.3112886725, - 0.05 - ], - [ - 224032.98791778192, - 6757779.561232818, - 0.05 - ], - [ - 224043.4637754814, - 6757752.030679921, - 0.05 - ], - [ - 224055.30025435, - 6757720.957184447, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 160, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224188.35675358376, - 6757565.025180998, - 0.05 - ], - [ - 224162.42578602192, - 6757570.973899536, - 0.05 - ], - [ - 224157.45894121117, - 6757571.285439727, - 0.05 - ], - [ - 224152.50664801133, - 6757576.62294737, - 0.05 - ], - [ - 224148.29229923512, - 6757582.068122489, - 0.05 - ], - [ - 224136.23860023415, - 6757590.798692313, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 161, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224188.35675358376, - 6757565.025180998, - 0.05 - ], - [ - 224188.0905461965, - 6757562.750448867, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 162, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223987.51771235053, - 6757593.3249974735, - 0.05 - ], - [ - 223993.4655193215, - 6757589.891102092, - 0.05 - ], - [ - 224014.5376227912, - 6757577.768358722, - 0.05 - ], - [ - 224015.5580614193, - 6757577.184406998, - 0.05 - ], - [ - 224051.28611404204, - 6757556.622580201, - 0.05 - ], - [ - 224056.1779860112, - 6757553.797856783, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 163, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224056.1779860112, - 6757553.797856783, - 0.05 - ], - [ - 224052.98425149312, - 6757548.225873462, - 0.05 - ], - [ - 224020.8853552313, - 6757492.18475666, - 0.05 - ], - [ - 224017.80928784155, - 6757486.581000088, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 164, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224017.80928784155, - 6757486.581000088, - 0.05 - ], - [ - 224004.58710597706, - 6757464.251211512, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 165, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223985.611923559, - 6757437.804465437, - 0.05 - ], - [ - 223974.71896817797, - 6757422.6324019525, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 166, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223974.71896817797, - 6757422.6324019525, - 0.05 - ], - [ - 223959.69097099104, - 6757401.685719432, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 167, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224070.53196957114, - 6757547.300331295, - 0.05 - ], - [ - 224078.12801571802, - 6757547.055232032, - 0.05 - ], - [ - 224085.18694994, - 6757547.70062777, - 0.05 - ], - [ - 224089.87978444685, - 6757548.837909676, - 0.05 - ], - [ - 224148.10099508922, - 6757565.998946027, - 0.05 - ], - [ - 224157.45894121117, - 6757571.285439727, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 168, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224080.72811542777, - 6757444.084451268, - 0.05 - ], - [ - 224109.03226140386, - 6757480.680173172, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 169, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224159.83531708264, - 6757388.177383134, - 0.05 - ], - [ - 224153.5624708832, - 6757392.618210927, - 0.05 - ], - [ - 224129.10859925486, - 6757409.895443015, - 0.05 - ], - [ - 224113.20443953323, - 6757421.132573198, - 0.05 - ], - [ - 224080.72811542777, - 6757444.084451268, - 0.05 - ], - [ - 224023.9335503634, - 6757484.214133038, - 0.05 - ], - [ - 224017.80928784155, - 6757486.581000088, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 170, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223884.44937743508, - 6757577.545123223, - 0.05 - ], - [ - 223851.42833642417, - 6757601.924575947, - 0.05 - ], - [ - 223801.54916849948, - 6757638.74514562, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 171, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224368.03242605372, - 6758737.707243454, - 0.05 - ], - [ - 224369.3434360617, - 6758734.391252308, - 0.05 - ], - [ - 224370.06033502676, - 6758730.97827435, - 0.05 - ], - [ - 224375.06862333138, - 6758713.486441761, - 0.05 - ], - [ - 224378.0296348394, - 6758698.01009278, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 172, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223488.02797961782, - 6758700.361302062, - 0.05 - ], - [ - 223489.84444349358, - 6758695.3990933485, - 0.05 - ], - [ - 223491.01044981112, - 6758691.78247764, - 0.05 - ], - [ - 223493.78611770814, - 6758689.295382429, - 0.05 - ], - [ - 223496.42458308907, - 6758687.621946311, - 0.05 - ], - [ - 223500.42743619514, - 6758687.29849537, - 0.05 - ], - [ - 223504.8421367961, - 6758687.699751735, - 0.05 - ], - [ - 223535.03693531558, - 6758691.513330145, - 0.05 - ], - [ - 223556.88387363276, - 6758694.251472133, - 0.05 - ], - [ - 223558.75964718958, - 6758695.604737993, - 0.05 - ], - [ - 223560.21655733208, - 6758697.448865503, - 0.05 - ], - [ - 223564.42033213825, - 6758705.101485755, - 0.05 - ], - [ - 223566.20337932103, - 6758709.772847597, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 173, - "lwd63": 72.90398384473386, - "lwd125": 63.505822900955735, - "lwd250": 62.08037675522438, - "lwd500": 64.03774968159404, - "lwd1000": 65.69800254000175, - "lwd2000": 60.989781620817006, - "lwd4000": 56.84180030533177, - "lwd8000": 49.465034898738985, - "lwe63": 67.42548586626533, - "lwe125": 58.02734228036127, - "lwe250": 56.601903753170085, - "lwe500": 58.55926680037521, - "lwe1000": 60.21951414674617, - "lwe2000": 55.51131639158329, - "lwe4000": 51.363391041634046, - "lwe8000": 43.98703187968516, - "lwn63": 64.50292816964144, - "lwn125": 55.104807831953096, - "lwn250": 53.67937950856182, - "lwn500": 55.63672932421901, - "lwn1000": 57.29696928807486, - "lwn2000": 52.58880255736542, - "lwn4000": 48.44095216258455, - "lwn8000": 41.065137020184075 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223556.88387363276, - 6758694.251472133, - 0.05 - ], - [ - 223574.6588055864, - 6758695.99220839, - 0.05 - ], - [ - 223621.26737869304, - 6758701.913349613, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 174, - "lwd63": 72.90398384473386, - "lwd125": 63.505822900955735, - "lwd250": 62.08037675522438, - "lwd500": 64.03774968159404, - "lwd1000": 65.69800254000175, - "lwd2000": 60.989781620817006, - "lwd4000": 56.84180030533177, - "lwd8000": 49.465034898738985, - "lwe63": 67.42548586626533, - "lwe125": 58.02734228036127, - "lwe250": 56.601903753170085, - "lwe500": 58.55926680037521, - "lwe1000": 60.21951414674617, - "lwe2000": 55.51131639158329, - "lwe4000": 51.363391041634046, - "lwe8000": 43.98703187968516, - "lwn63": 64.50292816964144, - "lwn125": 55.104807831953096, - "lwn250": 53.67937950856182, - "lwn500": 55.63672932421901, - "lwn1000": 57.29696928807486, - "lwn2000": 52.58880255736542, - "lwn4000": 48.44095216258455, - "lwn8000": 41.065137020184075 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223574.6588055864, - 6758695.99220839, - 0.05 - ], - [ - 223575.88385378948, - 6758691.245015835, - 0.05 - ], - [ - 223577.1591167745, - 6758686.281977575, - 0.05 - ], - [ - 223581.2171829887, - 6758684.036870334, - 0.05 - ], - [ - 223616.7123417399, - 6758687.957689074, - 0.05 - ], - [ - 223621.44552174903, - 6758692.301563748, - 0.05 - ], - [ - 223621.26737869304, - 6758701.913349613, - 0.05 - ], - [ - 223619.5048593892, - 6758711.452487124, - 0.05 - ], - [ - 223618.57158143533, - 6758716.555089402, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 175, - "lwd63": 72.90398384473386, - "lwd125": 63.505822900955735, - "lwd250": 62.08037675522438, - "lwd500": 64.03774968159404, - "lwd1000": 65.69800254000175, - "lwd2000": 60.989781620817006, - "lwd4000": 56.84180030533177, - "lwd8000": 49.465034898738985, - "lwe63": 67.42548586626533, - "lwe125": 58.02734228036127, - "lwe250": 56.601903753170085, - "lwe500": 58.55926680037521, - "lwe1000": 60.21951414674617, - "lwe2000": 55.51131639158329, - "lwe4000": 51.363391041634046, - "lwe8000": 43.98703187968516, - "lwn63": 64.50292816964144, - "lwn125": 55.104807831953096, - "lwn250": 53.67937950856182, - "lwn500": 55.63672932421901, - "lwn1000": 57.29696928807486, - "lwn2000": 52.58880255736542, - "lwn4000": 48.44095216258455, - "lwn8000": 41.065137020184075 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223548.1064532146, - 6758541.2350609545, - 0.05 - ], - [ - 223564.45678315446, - 6758544.03837941, - 0.05 - ], - [ - 223624.25814483524, - 6758554.511758462, - 0.05 - ], - [ - 223659.30112218118, - 6758560.643038531, - 0.05 - ], - [ - 223694.18736635678, - 6758567.534013743, - 0.05 - ], - [ - 223701.81713129382, - 6758570.886014064, - 0.05 - ], - [ - 223704.92358630506, - 6758572.585795926, - 0.05 - ], - [ - 223708.05052675394, - 6758575.097639576, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 176, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223903.3764899454, - 6757721.86053246, - 0.05 - ], - [ - 223905.59656455618, - 6757727.756268631, - 0.05 - ], - [ - 223925.17755612085, - 6757779.780105187, - 0.05 - ], - [ - 223939.70442826638, - 6757819.393256701, - 0.05 - ], - [ - 223952.82601280883, - 6757855.19623171, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 177, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223876.0892994798, - 6757661.641816496, - 0.05 - ], - [ - 223899.27933263103, - 6757712.828047685, - 0.05 - ], - [ - 223903.3764899454, - 6757721.86053246, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 178, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223264.19529968814, - 6757278.040371546, - 0.05 - ], - [ - 223280.28063623933, - 6757365.056044828, - 0.05 - ], - [ - 223287.4568271853, - 6757403.890985491, - 0.05 - ], - [ - 223312.56308260723, - 6757539.736174168, - 0.05 - ], - [ - 223312.12158174708, - 6757559.66883728, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 179, - "lwd63": 87.3451918691436, - "lwd125": 77.33576995289717, - "lwd250": 75.901407181739, - "lwd500": 76.22265769057759, - "lwd1000": 78.05720708189668, - "lwd2000": 75.34291798806458, - "lwd4000": 70.57994827353804, - "lwd8000": 63.11164161545118, - "lwe63": 81.5803862733485, - "lwe125": 71.57096515745872, - "lwe250": 70.13660273423817, - "lwe500": 70.45785315487672, - "lwe1000": 72.29240215038334, - "lwe2000": 69.5781137103204, - "lwe4000": 64.81514680132078, - "lwe8000": 57.34685944611585, - "lwn63": 76.15759286545348, - "lwn125": 66.14817445681444, - "lwn250": 64.71381321051142, - "lwn500": 65.03506333280872, - "lwn1000": 66.86961098945835, - "lwn2000": 64.15532476080446, - "lwn4000": 59.39236734163286, - "lwn8000": 51.924145278613935 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223887.76567067712, - 6758231.745176058, - 0.05 - ], - [ - 223879.3071279502, - 6758253.885521812, - 0.05 - ], - [ - 223851.83412153396, - 6758325.793016437, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 180, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223755.70435918478, - 6758587.0661976915, - 0.05 - ], - [ - 223755.1335154802, - 6758588.840048891, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 181, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224045.5435330086, - 6757795.502076778, - 0.05 - ], - [ - 224052.3855753743, - 6757797.469075852, - 0.05 - ], - [ - 224075.7415601425, - 6757805.738936822, - 0.05 - ], - [ - 224110.52591588406, - 6757818.871847074, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 182, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223727.14714239357, - 6758664.212028575, - 0.05 - ], - [ - 223722.13984720805, - 6758677.134287478, - 0.05 - ], - [ - 223720.8888262057, - 6758681.002941841, - 0.05 - ], - [ - 223719.51210020843, - 6758684.525052466, - 0.05 - ], - [ - 223714.87154520408, - 6758698.264856723, - 0.05 - ], - [ - 223703.47858401993, - 6758731.889739663, - 0.05 - ], - [ - 223681.85768758558, - 6758789.548444939, - 0.05 - ], - [ - 223677.37902653596, - 6758802.684443143, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 183, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224404.20484750095, - 6758547.336015645, - 0.05 - ], - [ - 224389.71005070518, - 6758540.50171913, - 0.05 - ], - [ - 224363.05706572736, - 6758528.684605018, - 0.05 - ], - [ - 224308.8040474243, - 6758506.453562897, - 0.05 - ], - [ - 224299.5789057057, - 6758502.794776655, - 0.05 - ], - [ - 224284.00830036832, - 6758496.604838618, - 0.05 - ], - [ - 224270.91680158477, - 6758490.304119122, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 184, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223196.57049696322, - 6758325.576509145, - 0.05 - ], - [ - 223208.1570405704, - 6758336.85666536, - 0.05 - ], - [ - 223212.45695579145, - 6758341.970970448, - 0.05 - ], - [ - 223223.97155080317, - 6758355.709274495, - 0.05 - ], - [ - 223229.7890121175, - 6758364.624587374, - 0.05 - ], - [ - 223232.39945703413, - 6758370.87870754, - 0.05 - ], - [ - 223233.83430450765, - 6758374.30739974, - 0.05 - ], - [ - 223236.60447615717, - 6758385.419775239, - 0.05 - ], - [ - 223237.20850113087, - 6758400.608667266, - 0.05 - ], - [ - 223232.33726985502, - 6758428.50173569, - 0.05 - ], - [ - 223231.29482991213, - 6758434.48269159, - 0.05 - ], - [ - 223225.27328862145, - 6758473.994610862, - 0.05 - ], - [ - 223224.1328801131, - 6758484.063236308, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 185, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223151.72060893936, - 6758310.866296134, - 0.05 - ], - [ - 223162.45537573955, - 6758311.982444121, - 0.05 - ], - [ - 223165.6470468085, - 6758312.593829876, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 186, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224388.23639404762, - 6758628.010539167, - 0.05 - ], - [ - 224392.74441434653, - 6758629.943170217, - 0.05 - ], - [ - 224397.42915930145, - 6758635.651422982, - 0.05 - ], - [ - 224399.57398297545, - 6758646.680854186, - 0.05 - ], - [ - 224398.97764151904, - 6758675.074965097, - 0.05 - ], - [ - 224400.50782962766, - 6758724.98902317, - 0.05 - ], - [ - 224397.77020217624, - 6758756.375962025, - 0.05 - ], - [ - 224394.16014705691, - 6758786.451085772, - 0.05 - ], - [ - 224390.0552712913, - 6758809.36536541, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 187, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224218.70897229767, - 6757476.6026870515, - 0.05 - ], - [ - 224228.98767790187, - 6757553.2314857105, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 188, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224280.13425714307, - 6757383.600923929, - 0.05 - ], - [ - 224306.48202430567, - 6757540.627288779, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 189, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223404.67507206538, - 6758049.168072517, - 0.05 - ], - [ - 223346.49613380223, - 6757961.730535491, - 0.05 - ], - [ - 223368.30310159415, - 6757878.451681847, - 0.05 - ], - [ - 223358.66921463917, - 6757863.803115459, - 0.05 - ], - [ - 223349.5496611811, - 6757849.937856322, - 0.05 - ], - [ - 223300.27965465287, - 6757849.68422937, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 190, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223912.86848870863, - 6757558.274680709, - 0.05 - ], - [ - 223911.79555978294, - 6757543.212949303, - 0.05 - ], - [ - 223913.9866391109, - 6757541.018538394, - 0.05 - ], - [ - 223988.93457960163, - 6757488.476557247, - 0.05 - ], - [ - 223997.199039865, - 6757499.95943854, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 191, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223887.10778322676, - 6757653.317495065, - 0.05 - ], - [ - 223851.42833642417, - 6757601.924575947, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 192, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223321.9505377434, - 6757578.771437482, - 0.05 - ], - [ - 223329.0182595916, - 6757584.4535662215, - 0.05 - ], - [ - 223383.34139110037, - 6757637.814863171, - 0.05 - ], - [ - 223433.4990103505, - 6757687.087916636, - 0.05 - ], - [ - 223439.7678027223, - 6757693.492376787, - 0.05 - ], - [ - 223452.23765413492, - 6757705.370459685, - 0.05 - ], - [ - 223459.56685275928, - 6757713.0826027375, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 193, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223324.49835631513, - 6757572.156132311, - 0.05 - ], - [ - 223337.66248434933, - 6757580.990559466, - 0.05 - ], - [ - 223380.97273299482, - 6757623.482043047, - 0.05 - ], - [ - 223389.2521654677, - 6757631.507458483, - 0.05 - ], - [ - 223420.89992567396, - 6757662.167455295, - 0.05 - ], - [ - 223439.01967213396, - 6757682.372628096, - 0.05 - ], - [ - 223446.9253758834, - 6757691.264318913, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 194, - "lwd63": 83.30409175142825, - "lwd125": 76.2546130811617, - "lwd250": 74.99709404671418, - "lwd500": 76.642566230916, - "lwd1000": 80.72496135904034, - "lwd2000": 77.14641398771164, - "lwd4000": 70.54356875454842, - "lwd8000": 62.536982874873075, - "lwe63": 6.020599913279624, - "lwe125": 6.020599913279624, - "lwe250": 6.020599913279624, - "lwe500": 6.020599913279624, - "lwe1000": 6.020599913279624, - "lwe2000": 6.020599913279624, - "lwe4000": 6.020599913279624, - "lwe8000": 6.020599913279624, - "lwn63": 6.020599913279624, - "lwn125": 6.020599913279624, - "lwn250": 6.020599913279624, - "lwn500": 6.020599913279624, - "lwn1000": 6.020599913279624, - "lwn2000": 6.020599913279624, - "lwn4000": 6.020599913279624, - "lwn8000": 6.020599913279624 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223475.41854832694, - 6757721.410336383, - 0.05 - ], - [ - 223540.92152212677, - 6757785.607164974, - 0.05 - ], - [ - 223554.80675925274, - 6757799.934848461, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 195, - "lwd63": 85.85212732702338, - "lwd125": 75.84270552927153, - "lwd250": 74.40834280962632, - "lwd500": 74.72959330540668, - "lwd1000": 76.56414263812485, - "lwd2000": 73.84985364108475, - "lwd4000": 69.08688434192293, - "lwd8000": 61.618580541678334, - "lwe63": 6.020599913279624, - "lwe125": 6.020599913279624, - "lwe250": 6.020599913279624, - "lwe500": 6.020599913279624, - "lwe1000": 6.020599913279624, - "lwe2000": 6.020599913279624, - "lwe4000": 6.020599913279624, - "lwe8000": 6.020599913279624, - "lwn63": 6.020599913279624, - "lwn125": 6.020599913279624, - "lwn250": 6.020599913279624, - "lwn500": 6.020599913279624, - "lwn1000": 6.020599913279624, - "lwn2000": 6.020599913279624, - "lwn4000": 6.020599913279624, - "lwn8000": 6.020599913279624 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223548.8678907748, - 6757806.545325891, - 0.05 - ], - [ - 223532.61646381026, - 6757790.101435211, - 0.05 - ], - [ - 223478.36432556756, - 6757736.933843022, - 0.05 - ], - [ - 223466.98183185945, - 6757726.974272903, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 196, - "lwd63": 86.53276061610428, - "lwd125": 76.52333875926946, - "lwd250": 75.0889760139392, - "lwd500": 75.41022651623061, - "lwd1000": 77.24477587816797, - "lwd2000": 74.53048683286607, - "lwd4000": 69.76751732659787, - "lwd8000": 62.2992121013954, - "lwe63": 82.02679751313504, - "lwe125": 72.01737629085146, - "lwe250": 70.58301382137853, - "lwe500": 70.90426425374177, - "lwe1000": 72.73881330186492, - "lwe2000": 70.0245247748945, - "lwe4000": 65.26155749294803, - "lwe8000": 57.79326757176041, - "lwn63": 77.36514659199398, - "lwn125": 67.35572726180995, - "lwn250": 65.9213656148857, - "lwn500": 66.24261583873798, - "lwn1000": 68.07716395113286, - "lwn2000": 65.36287696971813, - "lwn4000": 60.599916320224025, - "lwn8000": 53.131672031974055 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223458.10784449405, - 6757718.472904683, - 0.05 - ], - [ - 223446.55411243456, - 6757708.348857084, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 197, - "lwd63": 86.53276061610428, - "lwd125": 76.52333875926946, - "lwd250": 75.0889760139392, - "lwd500": 75.41022651623061, - "lwd1000": 77.24477587816797, - "lwd2000": 74.53048683286607, - "lwd4000": 69.76751732659787, - "lwd8000": 62.2992121013954, - "lwe63": 82.02679751313504, - "lwe125": 72.01737629085146, - "lwe250": 70.58301382137853, - "lwe500": 70.90426425374177, - "lwe1000": 72.73881330186492, - "lwe2000": 70.0245247748945, - "lwe4000": 65.26155749294803, - "lwe8000": 57.79326757176041, - "lwn63": 77.36514659199398, - "lwn125": 67.35572726180995, - "lwn250": 65.9213656148857, - "lwn500": 66.24261583873798, - "lwn1000": 68.07716395113286, - "lwn2000": 65.36287696971813, - "lwn4000": 60.599916320224025, - "lwn8000": 53.131672031974055 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223454.3034620459, - 6757699.953421205, - 0.05 - ], - [ - 223463.84446301672, - 6757709.638182224, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 198, - "lwd63": 85.85212732702338, - "lwd125": 75.84270552927153, - "lwd250": 74.40834280962632, - "lwd500": 74.72959330540668, - "lwd1000": 76.56414263812485, - "lwd2000": 73.84985364108475, - "lwd4000": 69.08688434192293, - "lwd8000": 61.618580541678334, - "lwe63": 6.020599913279624, - "lwe125": 6.020599913279624, - "lwe250": 6.020599913279624, - "lwe500": 6.020599913279624, - "lwe1000": 6.020599913279624, - "lwe2000": 6.020599913279624, - "lwe4000": 6.020599913279624, - "lwe8000": 6.020599913279624, - "lwn63": 6.020599913279624, - "lwn125": 6.020599913279624, - "lwn250": 6.020599913279624, - "lwn500": 6.020599913279624, - "lwn1000": 6.020599913279624, - "lwn2000": 6.020599913279624, - "lwn4000": 6.020599913279624, - "lwn8000": 6.020599913279624 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223437.07316000975, - 6757700.710273281, - 0.05 - ], - [ - 223377.88543308893, - 6757643.51703569, - 0.05 - ], - [ - 223375.87972827756, - 6757641.583527747, - 0.05 - ], - [ - 223325.24118202133, - 6757589.440468719, - 0.05 - ], - [ - 223316.00956073712, - 6757582.751674833, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 199, - "lwd63": 86.53276061610428, - "lwd125": 76.52333875926946, - "lwd250": 75.0889760139392, - "lwd500": 75.41022651623061, - "lwd1000": 77.24477587816797, - "lwd2000": 74.53048683286607, - "lwd4000": 69.76751732659787, - "lwd8000": 62.2992121013954, - "lwe63": 82.02679751313504, - "lwe125": 72.01737629085146, - "lwe250": 70.58301382137853, - "lwe500": 70.90426425374177, - "lwe1000": 72.73881330186492, - "lwe2000": 70.0245247748945, - "lwe4000": 65.26155749294803, - "lwe8000": 57.79326757176041, - "lwn63": 77.36514659199398, - "lwn125": 67.35572726180995, - "lwn250": 65.9213656148857, - "lwn500": 66.24261583873798, - "lwn1000": 68.07716395113286, - "lwn2000": 65.36287696971813, - "lwn4000": 60.599916320224025, - "lwn8000": 53.131672031974055 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223710.93844933534, - 6758061.801271431, - 0.05 - ], - [ - 223776.89229742065, - 6758025.899689885, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 200, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223842.11491132347, - 6757960.820106648, - 0.05 - ], - [ - 223792.4032069845, - 6757987.662379493, - 0.05 - ], - [ - 223787.15772566485, - 6757987.684649524, - 0.05 - ], - [ - 223783.43388655555, - 6757985.510764277, - 0.05 - ], - [ - 223781.69428214274, - 6757980.445710687, - 0.05 - ], - [ - 223784.77527398244, - 6757974.099669747, - 0.05 - ], - [ - 223834.27694535744, - 6757946.237654299, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 201, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223752.9121375975, - 6757992.76848323, - 0.05 - ], - [ - 223759.45122549374, - 6757994.336025243, - 0.05 - ], - [ - 223776.89229742065, - 6758025.899689885, - 0.05 - ], - [ - 223798.60120698542, - 6758065.16672637, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 202, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224070.53196957114, - 6757547.300331295, - 0.05 - ], - [ - 224086.9904165056, - 6757535.204614536, - 0.05 - ], - [ - 224126.7593228537, - 6757508.532125615, - 0.05 - ], - [ - 224128.82808519842, - 6757507.150228949, - 0.05 - ], - [ - 224131.01757550414, - 6757505.680566048, - 0.05 - ], - [ - 224174.78787828743, - 6757476.322511546, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 203, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224128.82808519842, - 6757507.150228949, - 0.05 - ], - [ - 224114.50368351454, - 6757488.019072258, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 204, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223533.7286703947, - 6757933.960794108, - 0.05 - ], - [ - 223543.94751751085, - 6757928.2195138335, - 0.05 - ], - [ - 223603.10634751827, - 6757893.901663956, - 0.05 - ], - [ - 223611.65155323996, - 6757889.031388534, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 205, - "lwd63": 72.90398384473386, - "lwd125": 63.505822900955735, - "lwd250": 62.08037675522438, - "lwd500": 64.03774968159404, - "lwd1000": 65.69800254000175, - "lwd2000": 60.989781620817006, - "lwd4000": 56.84180030533177, - "lwd8000": 49.465034898738985, - "lwe63": 67.42548586626533, - "lwe125": 58.02734228036127, - "lwe250": 56.601903753170085, - "lwe500": 58.55926680037521, - "lwe1000": 60.21951414674617, - "lwe2000": 55.51131639158329, - "lwe4000": 51.363391041634046, - "lwe8000": 43.98703187968516, - "lwn63": 64.50292816964144, - "lwn125": 55.104807831953096, - "lwn250": 53.67937950856182, - "lwn500": 55.63672932421901, - "lwn1000": 57.29696928807486, - "lwn2000": 52.58880255736542, - "lwn4000": 48.44095216258455, - "lwn8000": 41.065137020184075 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223920.97932381416, - 6757896.992114747, - 0.05 - ], - [ - 223937.10926192428, - 6757899.1901496425, - 0.05 - ], - [ - 223972.1687383518, - 6757911.820721924, - 0.05 - ], - [ - 223975.24204238743, - 6757914.5042443415, - 0.05 - ], - [ - 223974.4765000675, - 6757919.269939459, - 0.05 - ], - [ - 223957.40025950782, - 6757964.4882221855, - 0.05 - ], - [ - 223952.4836955387, - 6757970.168613005, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 206, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224056.1779860112, - 6757553.797856783, - 0.05 - ], - [ - 224059.78344919794, - 6757551.801476359, - 0.05 - ], - [ - 224067.1701257293, - 6757548.775446686, - 0.05 - ], - [ - 224070.53196957114, - 6757547.300331295, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 207, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223947.8209659803, - 6757959.342546573, - 0.05 - ], - [ - 223960.1078305915, - 6757928.087489136, - 0.05 - ], - [ - 223960.02008787065, - 6757922.064207901, - 0.05 - ], - [ - 223956.66357306135, - 6757917.921042075, - 0.05 - ], - [ - 223939.9006641634, - 6757911.326518206, - 0.05 - ], - [ - 223927.4741077844, - 6757912.073224023, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 208, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223851.83412153396, - 6758325.793016437, - 0.05 - ], - [ - 223851.32811252197, - 6758327.160333905, - 0.05 - ], - [ - 223845.51184355112, - 6758343.012448697, - 0.05 - ], - [ - 223843.35092217074, - 6758348.9274980435, - 0.05 - ], - [ - 223806.28229721705, - 6758449.911711172, - 0.05 - ], - [ - 223798.64625922055, - 6758468.730978768, - 0.05 - ], - [ - 223776.53603333357, - 6758530.876173139, - 0.05 - ], - [ - 223773.73841440765, - 6758538.492403892, - 0.05 - ], - [ - 223758.79979944864, - 6758579.136084619, - 0.05 - ], - [ - 223755.70435918478, - 6758587.0661976915, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 209, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223630.42615551996, - 6757590.376419465, - 0.05 - ], - [ - 223633.92237271433, - 6757595.778868051, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 210, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224136.23860023415, - 6757590.798692313, - 0.05 - ], - [ - 224127.11699914973, - 6757597.386639564, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 211, - "lwd63": 77.79975096543228, - "lwd125": 66.46453966028731, - "lwd250": 64.92716178574344, - "lwd500": 64.0808949889723, - "lwd1000": 64.08234880057039, - "lwd2000": 63.04688132914265, - "lwd4000": 59.317138877987375, - "lwd8000": 52.03375993647369, - "lwe63": 72.3338214982992, - "lwe125": 60.99861934884065, - "lwe250": 59.46124567179439, - "lwe500": 58.614981904172375, - "lwe1000": 58.61643571004414, - "lwe2000": 57.5809728436422, - "lwe4000": 53.85125992295367, - "lwe8000": 46.56810385304543, - "lwn63": 69.32352255665018, - "lwn125": 57.988333195461124, - "lwn250": 56.450965381277626, - "lwn500": 55.60470584461696, - "lwn1000": 55.60615964249051, - "lwn2000": 54.570703208140756, - "lwn4000": 50.841031533630165, - "lwn8000": 43.55818673417338 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224127.11699914973, - 6757597.386639564, - 0.05 - ], - [ - 224120.17572303605, - 6757603.230203833, - 0.05 - ], - [ - 224112.42552223318, - 6757609.763259148, - 0.05 - ], - [ - 224095.72125550406, - 6757623.561903237, - 0.05 - ], - [ - 224094.82147458382, - 6757624.336745389, - 0.05 - ], - [ - 224082.09247915464, - 6757635.317821755, - 0.05 - ], - [ - 224075.62403565028, - 6757640.7777462015, - 0.05 - ], - [ - 224065.3856677289, - 6757656.62962134, - 0.05 - ], - [ - 224064.11573941994, - 6757658.593591112, - 0.05 - ], - [ - 224051.51767379802, - 6757691.411649082, - 0.05 - ], - [ - 224046.29076901329, - 6757693.995904348, - 0.05 - ], - [ - 224040.70202359313, - 6757696.754271708, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 212, - "lwd63": 77.79975096543228, - "lwd125": 66.46453966028731, - "lwd250": 64.92716178574344, - "lwd500": 64.0808949889723, - "lwd1000": 64.08234880057039, - "lwd2000": 63.04688132914265, - "lwd4000": 59.317138877987375, - "lwd8000": 52.03375993647369, - "lwe63": 72.3338214982992, - "lwe125": 60.99861934884065, - "lwe250": 59.46124567179439, - "lwe500": 58.614981904172375, - "lwe1000": 58.61643571004414, - "lwe2000": 57.5809728436422, - "lwe4000": 53.85125992295367, - "lwe8000": 46.56810385304543, - "lwn63": 69.32352255665018, - "lwn125": 57.988333195461124, - "lwn250": 56.450965381277626, - "lwn500": 55.60470584461696, - "lwn1000": 55.60615964249051, - "lwn2000": 54.570703208140756, - "lwn4000": 50.841031533630165, - "lwn8000": 43.55818673417338 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223625.03415600897, - 6757581.794221371, - 0.05 - ], - [ - 223630.42615551996, - 6757590.376419465, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 213, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223832.9936290573, - 6757705.003853305, - 0.05 - ], - [ - 223829.2748104229, - 6757696.375584754, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 214, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223837.18152941955, - 6757713.482785762, - 0.05 - ], - [ - 223832.9936290573, - 6757705.003853305, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 215, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223254.66425437853, - 6758256.674120776, - 0.05 - ], - [ - 223251.6958483726, - 6758254.6401368575, - 0.05 - ], - [ - 223248.9517796943, - 6758252.777514554, - 0.05 - ], - [ - 223244.66800751054, - 6758250.838723287, - 0.05 - ], - [ - 223239.97965809156, - 6758249.846681812, - 0.05 - ], - [ - 223211.7051255203, - 6758248.989139947, - 0.05 - ], - [ - 223202.08478428505, - 6758248.919771219, - 0.05 - ], - [ - 223178.02005621797, - 6758248.435428011, - 0.05 - ], - [ - 223158.33810552052, - 6758248.510844036, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 216, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224388.23639404762, - 6758628.010539167, - 0.05 - ], - [ - 224394.5443309982, - 6758590.283021043, - 0.05 - ], - [ - 224397.18477268697, - 6758574.464716108, - 0.05 - ], - [ - 224404.20484750095, - 6758547.336015645, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 217, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223463.14877331565, - 6757610.956453654, - 0.05 - ], - [ - 223497.54115103, - 6757609.615706679, - 0.05 - ], - [ - 223510.8260495058, - 6757599.290632331, - 0.05 - ], - [ - 223518.44569321861, - 6757588.821342296, - 0.05 - ], - [ - 223516.4481719096, - 6757576.286578864, - 0.05 - ], - [ - 223508.17520217114, - 6757577.924698073, - 0.05 - ], - [ - 223496.25470944482, - 6757580.292235467, - 0.05 - ], - [ - 223493.84978529526, - 6757589.23672411, - 0.05 - ], - [ - 223497.54115103, - 6757609.615706679, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 218, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223319.29755586322, - 6757822.030176497, - 0.05 - ], - [ - 223305.23514932883, - 6757816.400668124, - 0.05 - ], - [ - 223286.40734800405, - 6757814.689903764, - 0.05 - ], - [ - 223278.53130883322, - 6757821.23432132, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 219, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223463.49464752147, - 6758271.5419497555, - 0.05 - ], - [ - 223470.39446613909, - 6758265.38872163, - 0.05 - ], - [ - 223473.28692264593, - 6758259.971741693, - 0.05 - ], - [ - 223472.54598238872, - 6758253.220922421, - 0.05 - ], - [ - 223470.71480365953, - 6758247.583703474, - 0.05 - ], - [ - 223465.95945289911, - 6758242.784697318, - 0.05 - ], - [ - 223446.18299647514, - 6758224.106738702, - 0.05 - ], - [ - 223520.56286846445, - 6758149.989925547, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 220, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223391.83918640448, - 6758200.843170759, - 0.05 - ], - [ - 223463.49464752147, - 6758271.5419497555, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 221, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223879.5553347402, - 6758096.339943541, - 0.05 - ], - [ - 223934.26536970236, - 6758066.3304771995, - 0.05 - ], - [ - 223945.52312366676, - 6758070.292843957, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 222, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223770.57648584415, - 6758592.6981125865, - 0.05 - ], - [ - 223772.26956401044, - 6758591.324092289, - 0.05 - ], - [ - 223790.92319821648, - 6758541.48532665, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 223, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223770.57648584415, - 6758592.6981125865, - 0.05 - ], - [ - 223770.8691217688, - 6758595.20479699, - 0.05 - ], - [ - 223770.1993954772, - 6758598.825849317, - 0.05 - ], - [ - 223767.80198018346, - 6758605.44000039, - 0.05 - ], - [ - 223749.27077212016, - 6758656.69578926, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 224, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223096.88228060154, - 6758253.703221687, - 0.05 - ], - [ - 223089.31828941806, - 6758246.43408416, - 0.05 - ], - [ - 223085.9651955358, - 6758241.689162916, - 0.05 - ], - [ - 223077.17364226776, - 6758229.280291983, - 0.05 - ], - [ - 223062.9654436987, - 6758207.990721208, - 0.05 - ], - [ - 223055.34148888488, - 6758197.471590499, - 0.05 - ], - [ - 223049.10537301423, - 6758188.868953934, - 0.05 - ], - [ - 223006.33932329604, - 6758129.860820169, - 0.05 - ], - [ - 222991.0241082005, - 6758108.738960103, - 0.05 - ], - [ - 222929.04797703, - 6758023.228471528, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 225, - "lwd63": 87.48932519690518, - "lwd125": 80.43984632232119, - "lwd250": 79.18232720239534, - "lwd500": 80.82779949382632, - "lwd1000": 84.9101947637985, - "lwd2000": 81.33164727611987, - "lwd4000": 74.72880130216963, - "lwd8000": 66.72221037959075, - "lwe63": 81.99131573285712, - "lwe125": 74.94183717917808, - "lwe250": 73.68431819350617, - "lwe500": 75.32979031652093, - "lwe1000": 79.41218536370415, - "lwe2000": 75.833638058767, - "lwe4000": 69.23079324831113, - "lwe8000": 61.22421024621101, - "lwn63": 76.32443288484068, - "lwn125": 69.27495553209985, - "lwn250": 68.0174370488529, - "lwn500": 69.66290854159568, - "lwn1000": 73.74530275502477, - "lwn2000": 70.16675613397, - "lwn4000": 63.5639156777129, - "lwn8000": 55.557362316638915 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224107.9093224483, - 6758143.54053619, - 0.05 - ], - [ - 224127.66903384798, - 6758193.1539651295, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 226, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224127.66903384798, - 6758193.1539651295, - 0.05 - ], - [ - 224149.54241806938, - 6758200.863691985, - 0.05 - ], - [ - 224152.69871247665, - 6758200.386083913, - 0.05 - ], - [ - 224155.306356175, - 6758199.350825402, - 0.05 - ], - [ - 224206.37574127945, - 6758179.190339654, - 0.05 - ], - [ - 224211.1620284323, - 6758177.299391573, - 0.05 - ], - [ - 224215.05947864352, - 6758175.758822791, - 0.05 - ], - [ - 224269.9797947363, - 6758154.128988221, - 0.05 - ], - [ - 224277.3672268638, - 6758151.214564534, - 0.05 - ], - [ - 224338.31931847276, - 6758127.192771023, - 0.05 - ], - [ - 224345.23434651998, - 6758129.232214053, - 0.05 - ], - [ - 224350.8145588016, - 6758134.667584509, - 0.05 - ], - [ - 224372.79672799975, - 6758189.30790917, - 0.05 - ], - [ - 224398.1638983676, - 6758252.369703423, - 0.05 - ], - [ - 224403.71104648104, - 6758261.218657813, - 0.05 - ], - [ - 224412.1607923588, - 6758265.41946232, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 227, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223701.44432694733, - 6757571.409728655, - 0.05 - ], - [ - 223708.4789131586, - 6757566.539021788, - 0.05 - ], - [ - 223736.49491865124, - 6757548.426065005, - 0.05 - ], - [ - 223816.87991024653, - 6757496.289896656, - 0.05 - ], - [ - 223819.7446495882, - 6757494.431196577, - 0.05 - ], - [ - 223825.19077811763, - 6757489.811501708, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 228, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223626.39422536298, - 6757601.146551561, - 0.05 - ], - [ - 223636.91435029305, - 6757616.62681673, - 0.05 - ], - [ - 223595.9864391472, - 6757645.859879937, - 0.05 - ], - [ - 223581.27278439066, - 6757656.367053919, - 0.05 - ], - [ - 223569.98375736125, - 6757641.327977626, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 229, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223558.5387276144, - 6757649.486735661, - 0.05 - ], - [ - 223570.08199884876, - 6757664.694748939, - 0.05 - ], - [ - 223506.82189604786, - 6757708.4843918355, - 0.05 - ], - [ - 223497.50169407384, - 6757701.34548108, - 0.05 - ], - [ - 223493.86328427022, - 6757695.207760294, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 230, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223681.80256293662, - 6757562.139039793, - 0.05 - ], - [ - 223685.60141746904, - 6757572.499656217, - 0.05 - ], - [ - 223686.9963028283, - 6757581.39355341, - 0.05 - ], - [ - 223647.6422185555, - 6757608.336652096, - 0.05 - ], - [ - 223636.39649825334, - 6757594.018499219, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 231, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223551.19494625996, - 6757802.500560954, - 0.05 - ], - [ - 223558.57390425, - 6757809.528839857, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 232, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224378.0296348394, - 6758698.01009278, - 0.05 - ], - [ - 224379.74992296565, - 6758685.509664422, - 0.05 - ], - [ - 224383.70983354142, - 6758655.484358805, - 0.05 - ], - [ - 224388.23639404762, - 6758628.010539167, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 233, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224378.0296348394, - 6758698.01009278, - 0.05 - ], - [ - 224378.67686683172, - 6758707.432575128, - 0.05 - ], - [ - 224378.47961685428, - 6758715.797354955, - 0.05 - ], - [ - 224376.46343614452, - 6758732.457074979, - 0.05 - ], - [ - 224376.0015140224, - 6758736.328793998, - 0.05 - ], - [ - 224375.09026015288, - 6758741.618944798, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 234, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224224.01368906104, - 6758666.416079432, - 0.05 - ], - [ - 224217.57110652508, - 6758662.120503218, - 0.05 - ], - [ - 224201.56164587883, - 6758654.773511456, - 0.05 - ], - [ - 224196.98451024533, - 6758651.798807666, - 0.05 - ], - [ - 224147.3025233975, - 6758612.157118062, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 235, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224243.23906010092, - 6758662.568752634, - 0.05 - ], - [ - 224257.22348975687, - 6758631.678830471, - 0.05 - ], - [ - 224257.19033460383, - 6758629.218084186, - 0.05 - ], - [ - 224256.14145193074, - 6758627.117949999, - 0.05 - ], - [ - 224249.53096787917, - 6758624.095461551, - 0.05 - ], - [ - 224246.79171310202, - 6758624.1492561195, - 0.05 - ], - [ - 224244.18022531847, - 6758625.786722577, - 0.05 - ], - [ - 224224.01368906104, - 6758666.416079432, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 236, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223263.8768093658, - 6758253.187261838, - 0.05 - ], - [ - 223266.96006265597, - 6758250.318512635, - 0.05 - ], - [ - 223270.94082362571, - 6758246.463173523, - 0.05 - ], - [ - 223295.76713271893, - 6758223.355402562, - 0.05 - ], - [ - 223300.08616912516, - 6758218.848521059, - 0.05 - ], - [ - 223319.17158071068, - 6758200.697085363, - 0.05 - ], - [ - 223336.27338808222, - 6758183.207654336, - 0.05 - ], - [ - 223355.38815881347, - 6758163.649486559, - 0.05 - ], - [ - 223415.65680603817, - 6758104.872867695, - 0.05 - ], - [ - 223424.18339841097, - 6758096.893830456, - 0.05 - ], - [ - 223432.92798131588, - 6758087.425816461, - 0.05 - ], - [ - 223442.22676327854, - 6758078.024503141, - 0.05 - ], - [ - 223447.56880090793, - 6758074.638937788, - 0.05 - ], - [ - 223453.35490889498, - 6758072.655429898, - 0.05 - ], - [ - 223458.1321137651, - 6758070.931799279, - 0.05 - ], - [ - 223461.74239984632, - 6758069.280169426, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 237, - "lwd63": 84.76340448114351, - "lwd125": 77.71392571660246, - "lwd250": 76.45640664271421, - "lwd500": 78.10187887639283, - "lwd1000": 82.1842740699675, - "lwd2000": 78.60572664495353, - "lwd4000": 72.00288106998227, - "lwd8000": 63.996292863451515, - "lwe63": 78.5957436509043, - "lwe125": 71.54626562706629, - "lwe250": 70.2887468630589, - "lwe500": 71.93421870800442, - "lwe1000": 76.01661338734425, - "lwe2000": 72.43806638412865, - "lwe4000": 65.83522349469918, - "lwe8000": 57.82865356993433, - "lwn63": 6.020599913279624, - "lwn125": 6.020599913279624, - "lwn250": 6.020599913279624, - "lwn500": 6.020599913279624, - "lwn1000": 6.020599913279624, - "lwn2000": 6.020599913279624, - "lwn4000": 6.020599913279624, - "lwn8000": 6.020599913279624 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224338.48295183375, - 6758741.316865574, - 0.05 - ], - [ - 224279.99829916068, - 6758736.02498524, - 0.05 - ], - [ - 224245.6692951616, - 6758732.753000091, - 0.05 - ], - [ - 224239.45891676092, - 6758730.868654292, - 0.05 - ], - [ - 224234.5307281015, - 6758728.479584798, - 0.05 - ], - [ - 224230.91281464102, - 6758725.561229064, - 0.05 - ], - [ - 224227.92981604254, - 6758720.7301482055, - 0.05 - ], - [ - 224225.13134904805, - 6758714.925562924, - 0.05 - ], - [ - 224221.5282141997, - 6758705.017031141, - 0.05 - ], - [ - 224219.19192366808, - 6758698.885344034, - 0.05 - ], - [ - 224216.6439757516, - 6758692.17995919, - 0.05 - ], - [ - 224210.40410070738, - 6758682.105186451, - 0.05 - ], - [ - 224199.7477212099, - 6758674.493496266, - 0.05 - ], - [ - 224122.70078362944, - 6758611.511757277, - 0.05 - ], - [ - 224084.54521648987, - 6758580.582309054, - 0.05 - ], - [ - 224040.34984152397, - 6758558.924180672, - 0.05 - ], - [ - 224036.08295542002, - 6758555.79078918, - 0.05 - ], - [ - 224028.29924439872, - 6758552.484238374, - 0.05 - ], - [ - 224006.88222938607, - 6758541.38302782, - 0.05 - ], - [ - 224001.59375400434, - 6758537.886249308, - 0.05 - ], - [ - 223992.9577294938, - 6758534.637391972, - 0.05 - ], - [ - 223897.07810111425, - 6758485.919225039, - 0.05 - ], - [ - 223871.06618105882, - 6758476.382142789, - 0.05 - ], - [ - 223822.47183111892, - 6758458.636512909, - 0.05 - ], - [ - 223806.28229721705, - 6758449.911711172, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 238, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223558.57390425, - 6757809.528839857, - 0.05 - ], - [ - 223566.52725882875, - 6757817.246411543, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 239, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223269.24892600207, - 6758268.124455955, - 0.05 - ], - [ - 223272.1972680402, - 6758270.5613553515, - 0.05 - ], - [ - 223273.827664055, - 6758271.945525857, - 0.05 - ], - [ - 223291.73488560587, - 6758289.347251279, - 0.05 - ], - [ - 223296.23410012992, - 6758293.486875775, - 0.05 - ], - [ - 223314.39924109064, - 6758311.5700625, - 0.05 - ], - [ - 223339.43871771474, - 6758336.488000633, - 0.05 - ], - [ - 223372.24445729784, - 6758370.442629317, - 0.05 - ], - [ - 223406.03353753604, - 6758404.663497458, - 0.05 - ], - [ - 223421.72409694927, - 6758418.644292169, - 0.05 - ], - [ - 223449.1205658656, - 6758435.903798045, - 0.05 - ], - [ - 223475.685997001, - 6758446.50904912, - 0.05 - ], - [ - 223509.07315608143, - 6758454.278117873, - 0.05 - ], - [ - 223541.99898291932, - 6758459.688080074, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 240, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223144.97510712518, - 6758324.408953248, - 0.05 - ], - [ - 223151.7363928457, - 6758320.451305031, - 0.05 - ], - [ - 223159.01868998556, - 6758316.429243896, - 0.05 - ], - [ - 223165.6470468085, - 6758312.593829876, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 241, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223165.6470468085, - 6758312.593829876, - 0.05 - ], - [ - 223173.62015154288, - 6758311.258054762, - 0.05 - ], - [ - 223194.7244437962, - 6758311.6696037175, - 0.05 - ], - [ - 223197.5543889323, - 6758311.6191486195, - 0.05 - ], - [ - 223201.91476253507, - 6758311.623308554, - 0.05 - ], - [ - 223207.19653137244, - 6758310.471734462, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 242, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223124.83277724416, - 6758338.310377822, - 0.05 - ], - [ - 223132.31765005027, - 6758333.168361459, - 0.05 - ], - [ - 223139.85003296536, - 6758328.055954537, - 0.05 - ], - [ - 223143.39680491743, - 6758325.5286442805, - 0.05 - ], - [ - 223144.97510712518, - 6758324.408953248, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 243, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223162.45537573955, - 6758311.982444121, - 0.05 - ], - [ - 223162.31024090044, - 6758306.933513357, - 0.05 - ], - [ - 223162.29436697444, - 6758294.650978476, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 244, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223107.67324043193, - 6758365.391480312, - 0.05 - ], - [ - 223119.87930473936, - 6758369.643446035, - 0.05 - ], - [ - 223124.51845698932, - 6758368.075590091, - 0.05 - ], - [ - 223127.75549458252, - 6758354.560226324, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 245, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223226.10306364356, - 6758302.667518565, - 0.05 - ], - [ - 223231.56649175973, - 6758308.690986624, - 0.05 - ], - [ - 223247.16052852053, - 6758323.7938501695, - 0.05 - ], - [ - 223254.58051345515, - 6758327.797643349, - 0.05 - ], - [ - 223254.1904607247, - 6758337.292833858, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 246, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223215.52000802296, - 6758302.218946423, - 0.05 - ], - [ - 223209.1546593107, - 6758296.290704417, - 0.05 - ], - [ - 223207.65032185853, - 6758294.885212268, - 0.05 - ], - [ - 223162.29436697444, - 6758294.650978476, - 0.05 - ], - [ - 223148.98287765263, - 6758294.579192131, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 247, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223165.6470468085, - 6758312.593829876, - 0.05 - ], - [ - 223180.72376427602, - 6758316.368584099, - 0.05 - ], - [ - 223187.08159672364, - 6758319.042527788, - 0.05 - ], - [ - 223192.13543193543, - 6758321.7661743695, - 0.05 - ], - [ - 223196.57049696322, - 6758325.576509145, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 248, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223690.91558466933, - 6757794.882304627, - 0.05 - ], - [ - 223697.6893928583, - 6757789.765095977, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 249, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223697.6893928583, - 6757789.765095977, - 0.05 - ], - [ - 223732.31190165982, - 6757765.221865437, - 0.05 - ], - [ - 223759.7398134804, - 6757745.796519632, - 0.05 - ], - [ - 223805.39923619042, - 6757713.340144078, - 0.05 - ], - [ - 223829.2748104229, - 6757696.375584754, - 0.05 - ], - [ - 223836.43421433627, - 6757689.97899405, - 0.05 - ], - [ - 223861.40723360766, - 6757672.078830977, - 0.05 - ], - [ - 223876.0892994798, - 6757661.641816496, - 0.05 - ], - [ - 223887.10778322676, - 6757653.317495065, - 0.05 - ], - [ - 223926.83800349396, - 6757626.557464667, - 0.05 - ], - [ - 223933.58399577602, - 6757622.022434104, - 0.05 - ], - [ - 223940.7418426099, - 6757618.2121433355, - 0.05 - ], - [ - 223981.8439800819, - 6757596.335499136, - 0.05 - ], - [ - 223987.51771235053, - 6757593.3249974735, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 250, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223785.6701732289, - 6757861.635001898, - 0.05 - ], - [ - 223789.06824008975, - 6757868.05980375, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 251, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223789.06824008975, - 6757868.05980375, - 0.05 - ], - [ - 223757.22211904556, - 6757889.926272656, - 0.05 - ], - [ - 223754.8377771817, - 6757891.400682893, - 0.05 - ], - [ - 223723.7975416573, - 6757912.165631838, - 0.05 - ], - [ - 223719.1262557106, - 6757915.2961122235, - 0.05 - ], - [ - 223713.00289861712, - 6757919.156933529, - 0.05 - ], - [ - 223687.99235441012, - 6757934.898427681, - 0.05 - ], - [ - 223655.69220275705, - 6757955.230485398, - 0.05 - ], - [ - 223650.7126124447, - 6757958.731476305, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 252, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223789.06824008975, - 6757868.05980375, - 0.05 - ], - [ - 223834.27694535744, - 6757946.237654299, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 253, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224044.44048763858, - 6758278.599591945, - 0.05 - ], - [ - 224017.95687655755, - 6758359.1542090485, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 254, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222685.8222643995, - 6758412.261394682, - 0.05 - ], - [ - 222709.77160051465, - 6758421.168953815, - 0.05 - ], - [ - 222812.86199503555, - 6758459.520590412, - 0.05 - ], - [ - 222837.34364963952, - 6758460.148003855, - 0.05 - ], - [ - 222942.66103584162, - 6758462.86334908, - 0.05 - ], - [ - 222996.62613486068, - 6758464.249810686, - 0.05 - ], - [ - 223026.5624853043, - 6758465.495742414, - 0.05 - ], - [ - 223066.33865536627, - 6758467.484284725, - 0.05 - ], - [ - 223075.16969871277, - 6758467.929351549, - 0.05 - ], - [ - 223123.9593577549, - 6758470.482364419, - 0.05 - ], - [ - 223148.24662159017, - 6758471.684116569, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 255, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223955.9075571851, - 6757396.261692507, - 0.05 - ], - [ - 223945.79769551422, - 6757381.851323904, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 256, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223945.79769551422, - 6757381.851323904, - 0.05 - ], - [ - 223890.23122332006, - 6757302.513482887, - 0.05 - ], - [ - 223843.98636463116, - 6757237.98432417, - 0.05 - ], - [ - 223834.00588222675, - 6757224.065273133, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 257, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222917.3184771689, - 6757582.673149023, - 0.05 - ], - [ - 222958.47240812733, - 6757581.729834185, - 0.05 - ], - [ - 222991.14648654166, - 6757580.982155792, - 0.05 - ], - [ - 223029.6436898152, - 6757580.098146734, - 0.05 - ], - [ - 223056.11936290492, - 6757579.495393955, - 0.05 - ], - [ - 223064.14924652426, - 6757579.314229496, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 258, - "lwd63": 74.80202133263722, - "lwd125": 63.46681363911763, - "lwd250": 61.92943742035383, - "lwd500": 61.083171818486825, - "lwd1000": 61.08462562782606, - "lwd2000": 60.04915997293725, - "lwd4000": 56.319429170657, - "lwd8000": 49.03613814679069, - "lwe63": 69.32352255665018, - "lwe125": 57.988333195461124, - "lwe250": 56.450965381277626, - "lwe500": 55.60470584461696, - "lwe1000": 55.60615964249051, - "lwe2000": 54.570703208140756, - "lwe4000": 50.841031533630165, - "lwe8000": 43.55818673417338, - "lwn63": 66.40096379186707, - "lwn125": 55.06579898403314, - "lwn250": 53.528442426419474, - "lwn500": 52.682191013085635, - "lwn1000": 52.68364479560286, - "lwn2000": 51.64820071056823, - "lwn4000": 47.918608226006825, - "lwn8000": 40.63636097453439 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222818.7052075978, - 6757566.183337854, - 0.05 - ], - [ - 223021.71961308754, - 6757561.5998911485, - 0.05 - ], - [ - 223029.44895495905, - 6757561.420692926, - 0.05 - ], - [ - 223056.11323811085, - 6757560.824987608, - 0.05 - ], - [ - 223117.80035302992, - 6757559.426273579, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 259, - "lwd63": 74.80202133263722, - "lwd125": 63.46681363911763, - "lwd250": 61.92943742035383, - "lwd500": 61.083171818486825, - "lwd1000": 61.08462562782606, - "lwd2000": 60.04915997293725, - "lwd4000": 56.319429170657, - "lwd8000": 49.03613814679069, - "lwe63": 69.32352255665018, - "lwe125": 57.988333195461124, - "lwe250": 56.450965381277626, - "lwe500": 55.60470584461696, - "lwe1000": 55.60615964249051, - "lwe2000": 54.570703208140756, - "lwe4000": 50.841031533630165, - "lwe8000": 43.55818673417338, - "lwn63": 66.40096379186707, - "lwn125": 55.06579898403314, - "lwn250": 53.528442426419474, - "lwn500": 52.682191013085635, - "lwn1000": 52.68364479560286, - "lwn2000": 51.64820071056823, - "lwn4000": 47.918608226006825, - "lwn8000": 40.63636097453439 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223567.54793632327, - 6758095.008041046, - 0.05 - ], - [ - 223517.12445619196, - 6758122.133263785, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 260, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223117.55788298085, - 6757314.562072731, - 0.05 - ], - [ - 223268.662971579, - 6757362.617573276, - 0.05 - ], - [ - 223280.28063623933, - 6757365.056044828, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 261, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224433.59354907763, - 6757124.518408633, - 0.05 - ], - [ - 224396.21874700824, - 6757143.259701615, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 262, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224003.48647039902, - 6757462.723769945, - 0.05 - ], - [ - 224015.46380297258, - 6757453.976811856, - 0.05 - ], - [ - 224013.24261815974, - 6757450.488812578, - 0.05 - ], - [ - 224006.64934238064, - 6757439.684747584, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 263, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223983.03549263562, - 6757405.787402392, - 0.05 - ], - [ - 223973.61157874012, - 6757391.956992118, - 0.05 - ], - [ - 223959.69097099104, - 6757401.685719432, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 264, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224098.51419623924, - 6757272.886016517, - 0.05 - ], - [ - 224096.33833247132, - 6757269.773317335, - 0.05 - ], - [ - 224043.31951489026, - 6757193.851276481, - 0.05 - ], - [ - 223998.90849957697, - 6757130.7893046, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 265, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223188.96104832, - 6757567.149531239, - 0.05 - ], - [ - 223118.69470091572, - 6757568.906767183, - 0.05 - ], - [ - 223063.5248695843, - 6757570.291218644, - 0.05 - ], - [ - 223056.1567607132, - 6757570.474602709, - 0.05 - ], - [ - 223029.41573059477, - 6757571.143398612, - 0.05 - ], - [ - 223022.0177427327, - 6757571.329241517, - 0.05 - ], - [ - 222990.48972110922, - 6757572.117818717, - 0.05 - ], - [ - 222958.06925043027, - 6757572.934159269, - 0.05 - ], - [ - 222917.05777016637, - 6757573.966270908, - 0.05 - ], - [ - 222816.05114742473, - 6757576.497104376, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 266, - "lwd63": 84.4069283564305, - "lwd125": 77.3574496120831, - "lwd250": 76.0999305466431, - "lwd500": 77.74540276972375, - "lwd1000": 81.82779794927889, - "lwd2000": 78.24925053576436, - "lwd4000": 71.64640503400864, - "lwd8000": 63.639817325892125, - "lwe63": 78.9811799437423, - "lwe125": 71.931701836952, - "lwe250": 70.67418303824067, - "lwe500": 72.3196549267209, - "lwe1000": 76.40204966365056, - "lwe2000": 72.82350261319722, - "lwe4000": 66.22065942301052, - "lwe8000": 58.21408745085194, - "lwn63": 75.52743366049893, - "lwn125": 68.47795663969323, - "lwn250": 67.22043829531475, - "lwn500": 68.86590961385261, - "lwn1000": 72.94830359683493, - "lwn2000": 69.36975716480289, - "lwn4000": 62.76691791203027, - "lwn8000": 54.76037274358561 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223589.14998950285, - 6757950.629026137, - 0.05 - ], - [ - 223562.72059681342, - 6758037.858415664, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 267, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223766.93437458255, - 6758178.422042555, - 0.05 - ], - [ - 223805.93485619687, - 6758161.762937129, - 0.05 - ], - [ - 223782.4657633499, - 6758110.655273295, - 0.05 - ], - [ - 223799.38972204062, - 6758102.210528573, - 0.05 - ], - [ - 223801.24242072582, - 6758106.162928611, - 0.05 - ], - [ - 223811.58784590155, - 6758134.576615131, - 0.05 - ], - [ - 223818.79903383227, - 6758153.501139737, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 268, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223811.58784590155, - 6758134.576615131, - 0.05 - ], - [ - 223820.4595533457, - 6758130.215299485, - 0.05 - ], - [ - 223827.7627528957, - 6758147.393513135, - 0.05 - ], - [ - 223841.61314913776, - 6758207.860918506, - 0.05 - ], - [ - 223822.93325984693, - 6758202.748007038, - 0.05 - ], - [ - 223810.21453524707, - 6758172.218560142, - 0.05 - ], - [ - 223805.93485619687, - 6758161.762937129, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 269, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223810.21453524707, - 6758172.218560142, - 0.05 - ], - [ - 223816.89586968796, - 6758169.126476044, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 270, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223841.61314913776, - 6758207.860918506, - 0.05 - ], - [ - 223842.05440403934, - 6758217.4226299375, - 0.05 - ], - [ - 223832.45087734074, - 6758238.228716796, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 271, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223801.24242072582, - 6758106.162928611, - 0.05 - ], - [ - 223827.81719401968, - 6758090.8083141325, - 0.05 - ], - [ - 223833.72793026472, - 6758087.388341892, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 272, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223900.57712989382, - 6758223.855647548, - 0.05 - ], - [ - 223888.9013713288, - 6758257.079178608, - 0.05 - ], - [ - 223879.3071279502, - 6758253.885521812, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 273, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224111.99562055228, - 6758393.064046533, - 0.05 - ], - [ - 224094.45686969004, - 6758434.774758432, - 0.05 - ], - [ - 224120.35312274046, - 6758481.8196719345, - 0.05 - ], - [ - 224136.16525973758, - 6758493.607648115, - 0.05 - ], - [ - 224150.02723268076, - 6758499.021053481, - 0.05 - ], - [ - 224164.27031384758, - 6758504.593231925, - 0.05 - ], - [ - 224178.62149616203, - 6758510.201307078, - 0.05 - ], - [ - 224188.65762163902, - 6758514.4075442795, - 0.05 - ], - [ - 224192.32681709074, - 6758514.512775218, - 0.05 - ], - [ - 224196.10856355022, - 6758512.379586728, - 0.05 - ], - [ - 224202.15813532204, - 6758499.3180046175, - 0.05 - ], - [ - 224205.40099319763, - 6758494.698001566, - 0.05 - ], - [ - 224209.88776029414, - 6758493.756370997, - 0.05 - ], - [ - 224214.87059057306, - 6758495.795476447, - 0.05 - ], - [ - 224229.29635018966, - 6758501.6763222255, - 0.05 - ], - [ - 224243.87023026857, - 6758507.623278108, - 0.05 - ], - [ - 224255.51419693022, - 6758512.379858956, - 0.05 - ], - [ - 224265.33855033352, - 6758495.792431603, - 0.05 - ], - [ - 224270.91680158477, - 6758490.304119122, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 274, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224273.48676989274, - 6758427.118010831, - 0.05 - ], - [ - 224263.51833326486, - 6758451.798379744, - 0.05 - ], - [ - 224261.5162947392, - 6758462.482363627, - 0.05 - ], - [ - 224262.00689407252, - 6758469.3091467265, - 0.05 - ], - [ - 224263.86068406602, - 6758475.702704013, - 0.05 - ], - [ - 224266.80045729585, - 6758484.003910869, - 0.05 - ], - [ - 224270.91680158477, - 6758490.304119122, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 275, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224273.48676989274, - 6758427.118010831, - 0.05 - ], - [ - 224231.55189153727, - 6758409.255458191, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 276, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224489.36637236405, - 6757449.7154312525, - 0.05 - ], - [ - 224474.02874575782, - 6757493.721445167, - 0.05 - ], - [ - 224472.0000071844, - 6757499.703531072, - 0.05 - ], - [ - 224469.421122331, - 6757506.042077978, - 0.05 - ], - [ - 224465.11754747038, - 6757511.037182509, - 0.05 - ], - [ - 224459.4221825606, - 6757513.502761922, - 0.05 - ], - [ - 224450.7080988788, - 6757515.732434752, - 0.05 - ], - [ - 224429.28622216883, - 6757519.332297234, - 0.05 - ], - [ - 224389.7234990105, - 6757526.0113116205, - 0.05 - ], - [ - 224346.8072955741, - 6757533.150531341, - 0.05 - ], - [ - 224318.40685170074, - 6757538.684632683, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 277, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224188.0905461965, - 6757562.750448867, - 0.05 - ], - [ - 224174.78787828743, - 6757476.322511546, - 0.05 - ], - [ - 224159.83531708264, - 6757388.177383134, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 278, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224135.76548024185, - 6758213.467580552, - 0.05 - ], - [ - 224141.46980411862, - 6758227.798957447, - 0.05 - ], - [ - 224160.36981898715, - 6758275.241360914, - 0.05 - ], - [ - 224157.89384599397, - 6758283.032038464, - 0.05 - ], - [ - 224156.89144545444, - 6758286.167113899, - 0.05 - ], - [ - 224147.7615390538, - 6758308.940811181, - 0.05 - ], - [ - 224132.9716218121, - 6758343.362536634, - 0.05 - ], - [ - 224111.99562055228, - 6758393.064046533, - 0.05 - ], - [ - 224117.67542728904, - 6758395.448115912, - 0.05 - ], - [ - 224179.52685614838, - 6758421.645734969, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 279, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224409.85966087593, - 6758445.489847303, - 0.05 - ], - [ - 224417.75579678483, - 6758445.81166439, - 0.05 - ], - [ - 224423.1865710264, - 6758446.042497155, - 0.05 - ], - [ - 224439.7309475171, - 6758446.971072145, - 0.05 - ], - [ - 224456.69800597877, - 6758447.921341357, - 0.05 - ], - [ - 224461.14173390827, - 6758369.447233011, - 0.05 - ], - [ - 224444.427489385, - 6758368.465400391, - 0.05 - ], - [ - 224427.8867953511, - 6758367.491912084, - 0.05 - ], - [ - 224421.78444054985, - 6758367.136881955, - 0.05 - ], - [ - 224412.305298561, - 6758366.574874151, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 280, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224004.58710597706, - 6757464.251211512, - 0.05 - ], - [ - 224003.48647039902, - 6757462.723769945, - 0.05 - ], - [ - 223985.611923559, - 6757437.804465437, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 281, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224131.01757550414, - 6757505.680566048, - 0.05 - ], - [ - 224118.21982411016, - 6757486.9278277615, - 0.05 - ], - [ - 224114.01758531213, - 6757479.66486875, - 0.05 - ], - [ - 224144.05125662574, - 6757459.23988006, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 282, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224020.22678229434, - 6757657.76588376, - 0.05 - ], - [ - 224017.70573705452, - 6757652.797283604, - 0.05 - ], - [ - 224010.66160220403, - 6757638.919683498, - 0.05 - ], - [ - 223989.7792864304, - 6757597.779487846, - 0.05 - ], - [ - 223987.51771235053, - 6757593.3249974735, - 0.05 - ], - [ - 223984.2226736985, - 6757587.616315672, - 0.05 - ], - [ - 223964.76124815783, - 6757552.068612466, - 0.05 - ], - [ - 223950.56532849482, - 6757532.113736383, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 283, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224055.30025435, - 6757720.957184447, - 0.05 - ], - [ - 224050.0489667764, - 6757715.506656838, - 0.05 - ], - [ - 224040.70202359313, - 6757696.754271708, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 284, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223631.35828888224, - 6757925.829000383, - 0.05 - ], - [ - 223646.8530513179, - 6757952.9236480575, - 0.05 - ], - [ - 223650.7126124447, - 6757958.731476305, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 285, - "lwd63": 75.85623196538906, - "lwd125": 65.2694208041789, - "lwd250": 64.39473946885698, - "lwd500": 64.33624093245956, - "lwd1000": 66.03868289781607, - "lwd2000": 64.96469263230671, - "lwd4000": 59.705276590813476, - "lwd8000": 51.877749519418906, - "lwe63": 70.39030290840185, - "lwe125": 59.80350362322187, - "lwe250": 58.92882519128766, - "lwe500": 58.87032687072855, - "lwe1000": 60.572763604506434, - "lwe2000": 59.49877639720681, - "lwe4000": 54.23939325515999, - "lwe8000": 46.41210346145351, - "lwn63": 67.38000453962833, - "lwn125": 56.79322184236098, - "lwn250": 55.9185474657335, - "lwn500": 55.860049446646286, - "lwn1000": 57.562478873212974, - "lwn2000": 56.488495937472564, - "lwn4000": 51.22915874732265, - "lwn8000": 43.40220034360154 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223650.7126124447, - 6757958.731476305, - 0.05 - ], - [ - 223657.27295959415, - 6757969.682752706, - 0.05 - ], - [ - 223690.56771576055, - 6758025.6144030085, - 0.05 - ], - [ - 223710.93844933534, - 6758061.801271431, - 0.05 - ], - [ - 223733.7325538108, - 6758102.306924174, - 0.05 - ], - [ - 223766.93437458255, - 6758178.422042555, - 0.05 - ], - [ - 223776.48632921802, - 6758198.963277064, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 286, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223908.34556611266, - 6757869.376079396, - 0.05 - ], - [ - 223900.96831709403, - 6757872.513056188, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 287, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223891.53518865386, - 6757876.351049922, - 0.05 - ], - [ - 223855.47861423396, - 6757894.209650804, - 0.05 - ], - [ - 223843.63751688763, - 6757899.880697873, - 0.05 - ], - [ - 223830.9851255988, - 6757875.576877256, - 0.05 - ], - [ - 223864.59373046277, - 6757854.772389351, - 0.05 - ], - [ - 223857.12836481293, - 6757842.75701181, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 288, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223900.96831709403, - 6757872.513056188, - 0.05 - ], - [ - 223891.53518865386, - 6757876.351049922, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 289, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223759.85951373784, - 6757895.030290708, - 0.05 - ], - [ - 223757.22211904556, - 6757889.926272656, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 290, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223766.58480169502, - 6757904.9540025005, - 0.05 - ], - [ - 223759.85951373784, - 6757895.030290708, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 291, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223766.58480169502, - 6757904.9540025005, - 0.05 - ], - [ - 223769.46413092088, - 6757916.871430632, - 0.05 - ], - [ - 223769.6003831401, - 6757920.048391916, - 0.05 - ], - [ - 223781.8145411819, - 6757940.318931739, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 292, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223763.9587231999, - 6757906.693157437, - 0.05 - ], - [ - 223769.46413092088, - 6757916.871430632, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 293, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223754.8377771817, - 6757891.400682893, - 0.05 - ], - [ - 223757.94335330353, - 6757896.344280269, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 294, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223757.94335330353, - 6757896.344280269, - 0.05 - ], - [ - 223763.9587231999, - 6757906.693157437, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 295, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224107.67358354427, - 6757826.659442504, - 0.05 - ], - [ - 224114.19124160026, - 6757825.631936194, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 296, - "lwd63": 74.80202133263722, - "lwd125": 63.46681363911763, - "lwd250": 61.92943742035383, - "lwd500": 61.083171818486825, - "lwd1000": 61.08462562782606, - "lwd2000": 60.04915997293725, - "lwd4000": 56.319429170657, - "lwd8000": 49.03613814679069, - "lwe63": 69.32352255665018, - "lwe125": 57.988333195461124, - "lwe250": 56.450965381277626, - "lwe500": 55.60470584461696, - "lwe1000": 55.60615964249051, - "lwe2000": 54.570703208140756, - "lwe4000": 50.841031533630165, - "lwe8000": 43.55818673417338, - "lwn63": 66.40096379186707, - "lwn125": 55.06579898403314, - "lwn250": 53.528442426419474, - "lwn500": 52.682191013085635, - "lwn1000": 52.68364479560286, - "lwn2000": 51.64820071056823, - "lwn4000": 47.918608226006825, - "lwn8000": 40.63636097453439 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224147.43301214714, - 6757803.3428094275, - 0.05 - ], - [ - 224149.16134557803, - 6757798.488324797, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 297, - "lwd63": 74.80202133263722, - "lwd125": 63.46681363911763, - "lwd250": 61.92943742035383, - "lwd500": 61.083171818486825, - "lwd1000": 61.08462562782606, - "lwd2000": 60.04915997293725, - "lwd4000": 56.319429170657, - "lwd8000": 49.03613814679069, - "lwe63": 69.32352255665018, - "lwe125": 57.988333195461124, - "lwe250": 56.450965381277626, - "lwe500": 55.60470584461696, - "lwe1000": 55.60615964249051, - "lwe2000": 54.570703208140756, - "lwe4000": 50.841031533630165, - "lwe8000": 43.55818673417338, - "lwn63": 66.40096379186707, - "lwn125": 55.06579898403314, - "lwn250": 53.528442426419474, - "lwn500": 52.682191013085635, - "lwn1000": 52.68364479560286, - "lwn2000": 51.64820071056823, - "lwn4000": 47.918608226006825, - "lwn8000": 40.63636097453439 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224144.63201269624, - 6757811.115093629, - 0.05 - ], - [ - 224124.24285609857, - 6757804.021212156, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 298, - "lwd63": 74.80202133263722, - "lwd125": 63.46681363911763, - "lwd250": 61.92943742035383, - "lwd500": 61.083171818486825, - "lwd1000": 61.08462562782606, - "lwd2000": 60.04915997293725, - "lwd4000": 56.319429170657, - "lwd8000": 49.03613814679069, - "lwe63": 69.32352255665018, - "lwe125": 57.988333195461124, - "lwe250": 56.450965381277626, - "lwe500": 55.60470584461696, - "lwe1000": 55.60615964249051, - "lwe2000": 54.570703208140756, - "lwe4000": 50.841031533630165, - "lwe8000": 43.55818673417338, - "lwn63": 66.40096379186707, - "lwn125": 55.06579898403314, - "lwn250": 53.528442426419474, - "lwn500": 52.682191013085635, - "lwn1000": 52.68364479560286, - "lwn2000": 51.64820071056823, - "lwn4000": 47.918608226006825, - "lwn8000": 40.63636097453439 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224114.19124160026, - 6757825.631936194, - 0.05 - ], - [ - 224137.01933669526, - 6757822.051127406, - 0.05 - ], - [ - 224138.23176032334, - 6757821.7972498685, - 0.05 - ], - [ - 224139.47202128975, - 6757821.329339921, - 0.05 - ], - [ - 224140.60689010756, - 6757820.580120472, - 0.05 - ], - [ - 224141.5670370871, - 6757819.622065273, - 0.05 - ], - [ - 224144.63201269624, - 6757811.115093629, - 0.05 - ], - [ - 224147.43301214714, - 6757803.3428094275, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 299, - "lwd63": 74.80202133263722, - "lwd125": 63.46681363911763, - "lwd250": 61.92943742035383, - "lwd500": 61.083171818486825, - "lwd1000": 61.08462562782606, - "lwd2000": 60.04915997293725, - "lwd4000": 56.319429170657, - "lwd8000": 49.03613814679069, - "lwe63": 69.32352255665018, - "lwe125": 57.988333195461124, - "lwe250": 56.450965381277626, - "lwe500": 55.60470584461696, - "lwe1000": 55.60615964249051, - "lwe2000": 54.570703208140756, - "lwe4000": 50.841031533630165, - "lwe8000": 43.55818673417338, - "lwn63": 66.40096379186707, - "lwn125": 55.06579898403314, - "lwn250": 53.528442426419474, - "lwn500": 52.682191013085635, - "lwn1000": 52.68364479560286, - "lwn2000": 51.64820071056823, - "lwn4000": 47.918608226006825, - "lwn8000": 40.63636097453439 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223537.48291383544, - 6758715.459694352, - 0.05 - ], - [ - 223541.30068582774, - 6758706.612765532, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 300, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223151.3357015297, - 6758650.441752438, - 0.05 - ], - [ - 223155.73312174546, - 6758651.278878102, - 0.05 - ], - [ - 223182.44419905922, - 6758654.948817268, - 0.05 - ], - [ - 223243.88002635504, - 6758661.741476261, - 0.05 - ], - [ - 223279.11278819502, - 6758666.127391277, - 0.05 - ], - [ - 223283.90608896606, - 6758665.539249974, - 0.05 - ], - [ - 223288.40106476238, - 6758663.771369883, - 0.05 - ], - [ - 223300.07784457557, - 6758658.602771938, - 0.05 - ], - [ - 223305.24219837325, - 6758657.583366867, - 0.05 - ], - [ - 223314.16013025853, - 6758658.177798195, - 0.05 - ], - [ - 223381.59042984503, - 6758664.275512769, - 0.05 - ], - [ - 223384.81886566634, - 6758665.530545865, - 0.05 - ], - [ - 223386.86839048914, - 6758668.474861525, - 0.05 - ], - [ - 223391.9360017702, - 6758670.071710053, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 301, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223391.9360017702, - 6758670.071710053, - 0.05 - ], - [ - 223428.58953024162, - 6758674.555459631, - 0.05 - ], - [ - 223427.08627616597, - 6758692.879717379, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 302, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223428.58953024162, - 6758674.555459631, - 0.05 - ], - [ - 223456.60772993322, - 6758678.221296022, - 0.05 - ], - [ - 223459.93976205523, - 6758677.037989146, - 0.05 - ], - [ - 223460.8441815948, - 6758667.021936685, - 0.05 - ], - [ - 223459.7382916925, - 6758664.592123402, - 0.05 - ], - [ - 223427.75786085683, - 6758660.544230808, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 303, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223012.1496092782, - 6757702.634236161, - 0.05 - ], - [ - 223019.26297126373, - 6757664.906602924, - 0.05 - ], - [ - 223020.2216266361, - 6757624.421861754, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 304, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223062.88310950896, - 6757294.482189977, - 0.05 - ], - [ - 223060.31414353807, - 6757305.390833351, - 0.05 - ], - [ - 223090.2462087256, - 6757368.814655371, - 0.05 - ], - [ - 223051.25396718702, - 6757402.364861867, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 305, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224186.5159086982, - 6757609.024575711, - 0.05 - ], - [ - 224180.29943037964, - 6757606.705984122, - 0.05 - ], - [ - 224173.35516487987, - 6757604.312353747, - 0.05 - ], - [ - 224167.47880035313, - 6757602.668574588, - 0.05 - ], - [ - 224160.46269091364, - 6757603.112002932, - 0.05 - ], - [ - 224155.2673650232, - 6757606.7413881915, - 0.05 - ], - [ - 224153.1310282778, - 6757613.155868898, - 0.05 - ], - [ - 224156.478290345, - 6757624.266542682, - 0.05 - ], - [ - 224157.87391279818, - 6757641.565011199, - 0.05 - ], - [ - 224155.69284040463, - 6757658.327194153, - 0.05 - ], - [ - 224151.01500658726, - 6757675.079033808, - 0.05 - ], - [ - 224125.39703106426, - 6757742.855517578, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 306, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223300.27965465287, - 6757849.68422937, - 0.05 - ], - [ - 223290.40748123766, - 6757831.811303554, - 0.05 - ], - [ - 223278.53130883322, - 6757821.23432132, - 0.05 - ], - [ - 223258.7665824396, - 6757807.560840408, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 307, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223459.56685275928, - 6757713.0826027375, - 0.05 - ], - [ - 223473.1391158037, - 6757724.648716417, - 0.05 - ], - [ - 223477.66294719442, - 6757729.555625114, - 0.05 - ], - [ - 223542.24443166796, - 6757793.793475272, - 0.05 - ], - [ - 223551.19494625996, - 6757802.500560954, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 308, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223690.18168001558, - 6757555.298227939, - 0.05 - ], - [ - 223698.00786875607, - 6757566.281086695, - 0.05 - ], - [ - 223701.44432694733, - 6757571.409728655, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 309, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223825.19077811763, - 6757489.811501708, - 0.05 - ], - [ - 223833.86614331097, - 6757483.47089386, - 0.05 - ], - [ - 223839.79386256804, - 6757479.135588622, - 0.05 - ], - [ - 223846.23257653828, - 6757474.424637192, - 0.05 - ], - [ - 223950.89798788208, - 6757399.865108676, - 0.05 - ], - [ - 223955.9075571851, - 6757396.261692507, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 310, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223901.03036344144, - 6757566.04088129, - 0.05 - ], - [ - 223889.9868269902, - 6757573.2190721035, - 0.05 - ], - [ - 223884.44937743508, - 6757577.545123223, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 311, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223182.9774905509, - 6757557.489681543, - 0.05 - ], - [ - 223117.80035302992, - 6757559.426273579, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 312, - "lwd63": 74.80202133263722, - "lwd125": 63.46681363911763, - "lwd250": 61.92943742035383, - "lwd500": 61.083171818486825, - "lwd1000": 61.08462562782606, - "lwd2000": 60.04915997293725, - "lwd4000": 56.319429170657, - "lwd8000": 49.03613814679069, - "lwe63": 69.32352255665018, - "lwe125": 57.988333195461124, - "lwe250": 56.450965381277626, - "lwe500": 55.60470584461696, - "lwe1000": 55.60615964249051, - "lwe2000": 54.570703208140756, - "lwe4000": 50.841031533630165, - "lwe8000": 43.55818673417338, - "lwn63": 66.40096379186707, - "lwn125": 55.06579898403314, - "lwn250": 53.528442426419474, - "lwn500": 52.682191013085635, - "lwn1000": 52.68364479560286, - "lwn2000": 51.64820071056823, - "lwn4000": 47.918608226006825, - "lwn8000": 40.63636097453439 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223825.30520088575, - 6757105.29769928, - 0.05 - ], - [ - 223890.11320811423, - 6757187.322254927, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 313, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223673.77329232072, - 6757209.671055205, - 0.05 - ], - [ - 223734.27338774566, - 6757293.9145715665, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 314, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223847.98823641991, - 6757297.429712066, - 0.05 - ], - [ - 223797.2505354486, - 6757334.174451559, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 315, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223766.75578997255, - 6757299.161395559, - 0.05 - ], - [ - 223824.7542064595, - 6757259.500593367, - 0.05 - ], - [ - 223843.98636463116, - 6757237.98432417, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 316, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223824.7542064595, - 6757259.500593367, - 0.05 - ], - [ - 223847.98823641991, - 6757297.429712066, - 0.05 - ], - [ - 223860.45875959418, - 6757298.329100608, - 0.05 - ], - [ - 223872.5634653757, - 6757314.907968064, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 317, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223637.6020078861, - 6757410.947779099, - 0.05 - ], - [ - 223726.61049151805, - 6757345.105863517, - 0.05 - ], - [ - 223740.02660013788, - 6757335.183228927, - 0.05 - ], - [ - 223754.55648556276, - 6757324.43501759, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 318, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223748.14292725245, - 6757283.832742263, - 0.05 - ], - [ - 223756.9576402817, - 6757296.441306205, - 0.05 - ], - [ - 223766.75578997255, - 6757299.161395559, - 0.05 - ], - [ - 223774.16579990851, - 6757298.563111694, - 0.05 - ], - [ - 223797.2505354486, - 6757334.174451559, - 0.05 - ], - [ - 223798.93455145299, - 6757336.780574968, - 0.05 - ], - [ - 223774.03441687406, - 6757353.738662426, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 319, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223235.95128467557, - 6758773.605853442, - 0.05 - ], - [ - 223248.5325221559, - 6758727.934349282, - 0.05 - ], - [ - 223345.94164390233, - 6758757.312573547, - 0.05 - ], - [ - 223359.12386482296, - 6758761.285417107, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 320, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223796.23549380386, - 6758738.421056429, - 0.05 - ], - [ - 223766.86262514855, - 6758731.095445173, - 0.05 - ], - [ - 223755.88137451123, - 6758730.54436826, - 0.05 - ], - [ - 223745.99518312066, - 6758730.150099615, - 0.05 - ], - [ - 223743.51178961183, - 6758737.094472732, - 0.05 - ], - [ - 223733.42079250526, - 6758765.341715863, - 0.05 - ], - [ - 223730.29462911043, - 6758774.099205218, - 0.05 - ], - [ - 223725.43910357787, - 6758787.689172929, - 0.05 - ], - [ - 223723.9041881609, - 6758794.556953781, - 0.05 - ], - [ - 223721.5882300224, - 6758804.876444302, - 0.05 - ], - [ - 223727.21297665784, - 6758814.677191161, - 0.05 - ], - [ - 223736.20960786176, - 6758816.1576223755, - 0.05 - ], - [ - 223747.26531648065, - 6758813.258279427, - 0.05 - ], - [ - 223766.61674388516, - 6758820.378747352, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 321, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223678.7166458881, - 6758296.233849301, - 0.05 - ], - [ - 223664.8107725485, - 6758344.920290725, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 322, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224010.66160220403, - 6757638.919683498, - 0.05 - ], - [ - 224064.11573941994, - 6757658.593591112, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 323, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224075.62403565028, - 6757640.7777462015, - 0.05 - ], - [ - 224028.66692508094, - 6757620.657436734, - 0.05 - ], - [ - 224033.7136226638, - 6757603.262648765, - 0.05 - ], - [ - 224029.20266972098, - 6757594.876549561, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 324, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224076.50330912613, - 6757912.997666218, - 0.05 - ], - [ - 224041.5275444899, - 6757900.00304583, - 0.05 - ], - [ - 224060.23410505697, - 6757844.420872681, - 0.05 - ], - [ - 224031.6215927513, - 6757834.825267442, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 325, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223691.59586096165, - 6758653.919115516, - 0.05 - ], - [ - 223682.33748671628, - 6758651.155700955, - 0.05 - ], - [ - 223656.03102424595, - 6758643.460299516, - 0.05 - ], - [ - 223553.86122842768, - 6758607.996468405, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 326, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223458.1947734169, - 6758586.332425885, - 0.05 - ], - [ - 223457.2531062577, - 6758533.750969713, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 327, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223457.2531062577, - 6758533.750969713, - 0.05 - ], - [ - 223357.21867926454, - 6758516.844416173, - 0.05 - ], - [ - 223325.40536908223, - 6758511.434736519, - 0.05 - ], - [ - 223232.67832964315, - 6758495.667320878, - 0.05 - ], - [ - 223223.3724638371, - 6758494.089994011, - 0.05 - ], - [ - 223224.1328801131, - 6758484.063236308, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 328, - "lwd63": 72.90398384473386, - "lwd125": 63.505822900955735, - "lwd250": 62.08037675522438, - "lwd500": 64.03774968159404, - "lwd1000": 65.69800254000175, - "lwd2000": 60.989781620817006, - "lwd4000": 56.84180030533177, - "lwd8000": 49.465034898738985, - "lwe63": 67.42548586626533, - "lwe125": 58.02734228036127, - "lwe250": 56.601903753170085, - "lwe500": 58.55926680037521, - "lwe1000": 60.21951414674617, - "lwe2000": 55.51131639158329, - "lwe4000": 51.363391041634046, - "lwe8000": 43.98703187968516, - "lwn63": 64.50292816964144, - "lwn125": 55.104807831953096, - "lwn250": 53.67937950856182, - "lwn500": 55.63672932421901, - "lwn1000": 57.29696928807486, - "lwn2000": 52.58880255736542, - "lwn4000": 48.44095216258455, - "lwn8000": 41.065137020184075 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223457.2531062577, - 6758533.750969713, - 0.05 - ], - [ - 223457.56145479577, - 6758522.5903863525, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 329, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223755.70435918478, - 6758587.0661976915, - 0.05 - ], - [ - 223770.57648584415, - 6758592.6981125865, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 330, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224500.99215826945, - 6757416.36390103, - 0.05 - ], - [ - 224479.04574018007, - 6757408.892691393, - 0.05 - ], - [ - 224503.0399509347, - 6757338.808100835, - 0.05 - ], - [ - 224526.62992160185, - 6757343.349132571, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 331, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223157.82130392786, - 6758565.178862319, - 0.05 - ], - [ - 223154.84589878272, - 6758566.868549614, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 332, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223127.6040642546, - 6758794.505764728, - 0.05 - ], - [ - 223126.91088051716, - 6758815.863509894, - 0.05 - ], - [ - 223127.0491927627, - 6758839.974176275, - 0.05 - ], - [ - 223128.6320630773, - 6758858.338847984, - 0.05 - ], - [ - 223133.7078672048, - 6758880.300164038, - 0.05 - ], - [ - 223139.6995892694, - 6758906.244881184, - 0.05 - ], - [ - 223143.10353736492, - 6758920.917581286, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 333, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223365.79406286438, - 6758589.553163047, - 0.05 - ], - [ - 223171.04516688228, - 6758562.036264637, - 0.05 - ], - [ - 223163.42222775926, - 6758563.1431138, - 0.05 - ], - [ - 223157.82130392786, - 6758565.178862319, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 334, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223458.1947734169, - 6758586.332425885, - 0.05 - ], - [ - 223431.43202588503, - 6758587.882123838, - 0.05 - ], - [ - 223410.99126960116, - 6758588.319077396, - 0.05 - ], - [ - 223365.79406286438, - 6758589.553163047, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 335, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223920.97932381416, - 6757896.992114747, - 0.05 - ], - [ - 223908.34556611266, - 6757869.376079396, - 0.05 - ], - [ - 223880.47611838486, - 6757808.457519478, - 0.05 - ], - [ - 223856.91066571831, - 6757755.507037933, - 0.05 - ], - [ - 223854.4586297355, - 6757749.997883832, - 0.05 - ], - [ - 223837.18152941955, - 6757713.482785762, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 336, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223920.97932381416, - 6757896.992114747, - 0.05 - ], - [ - 223942.45248696784, - 6757873.834831183, - 0.05 - ], - [ - 223952.82601280883, - 6757855.19623171, - 0.05 - ], - [ - 223976.06672791712, - 6757815.187540999, - 0.05 - ], - [ - 223996.64234583278, - 6757780.064529885, - 0.05 - ], - [ - 224005.20082664466, - 6757772.652347919, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 337, - "lwd63": 75.90171332041136, - "lwd125": 66.50354895698379, - "lwd250": 65.07810131032979, - "lwd500": 67.03547618298532, - "lwd1000": 68.69573012731246, - "lwd2000": 63.98750464460184, - "lwd4000": 59.83951230326983, - "lwd8000": 52.46266685676584, - "lwe63": 70.43578425158094, - "lwe125": 61.037628557169114, - "lwe250": 59.612184715440435, - "lwe500": 61.569554654148824, - "lwe1000": 63.22980584560604, - "lwe2000": 58.52159193169619, - "lwe4000": 54.37362754144347, - "lwe8000": 46.99698499689735, - "lwn63": 67.42548586626533, - "lwn125": 58.02734228036127, - "lwn250": 56.601903753170085, - "lwn500": 58.55926680037521, - "lwn1000": 60.21951414674617, - "lwn2000": 55.51131639158329, - "lwn4000": 51.363391041634046, - "lwn8000": 43.98703187968516 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223667.19494155463, - 6758570.427655271, - 0.05 - ], - [ - 223662.84749875503, - 6758565.183134961, - 0.05 - ], - [ - 223657.37078431284, - 6758562.615889994, - 0.05 - ], - [ - 223648.30564446579, - 6758561.12993612, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 338, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223579.23882958264, - 6758560.08822163, - 0.05 - ], - [ - 223573.9861679941, - 6758559.364464525, - 0.05 - ], - [ - 223568.58472358662, - 6758554.194013108, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 339, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223564.45678315446, - 6758544.03837941, - 0.05 - ], - [ - 223569.95952527865, - 6758549.066882239, - 0.05 - ], - [ - 223575.54811770987, - 6758550.878176245, - 0.05 - ], - [ - 223580.18423244444, - 6758551.506837322, - 0.05 - ], - [ - 223614.3239165058, - 6758557.90032871, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 340, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223727.90645704512, - 6758662.445244192, - 0.05 - ], - [ - 223727.14714239357, - 6758664.212028575, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 341, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223755.1335154802, - 6758588.840048891, - 0.05 - ], - [ - 223757.8853633197, - 6758592.385418832, - 0.05 - ], - [ - 223759.1441643237, - 6758596.15168855, - 0.05 - ], - [ - 223759.32165221142, - 6758599.559413955, - 0.05 - ], - [ - 223758.9935448981, - 6758602.105082515, - 0.05 - ], - [ - 223745.2902106315, - 6758640.542330874, - 0.05 - ], - [ - 223739.8942414004, - 6758653.306463435, - 0.05 - ], - [ - 223738.99057100108, - 6758655.519628948, - 0.05 - ], - [ - 223736.69051541755, - 6758658.871076357, - 0.05 - ], - [ - 223732.40561284986, - 6758661.379620609, - 0.05 - ], - [ - 223727.90645704512, - 6758662.445244192, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 342, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223727.90645704512, - 6758662.445244192, - 0.05 - ], - [ - 223725.44131143385, - 6758659.378337115, - 0.05 - ], - [ - 223723.9683357202, - 6758655.473315647, - 0.05 - ], - [ - 223724.38459273905, - 6758650.668873502, - 0.05 - ], - [ - 223725.34808940324, - 6758647.893534465, - 0.05 - ], - [ - 223743.3878061521, - 6758596.231482549, - 0.05 - ], - [ - 223744.8076859311, - 6758593.987775967, - 0.05 - ], - [ - 223747.10818042525, - 6758591.851298297, - 0.05 - ], - [ - 223750.6465087263, - 6758590.149897994, - 0.05 - ], - [ - 223755.1335154802, - 6758588.840048891, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 343, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223755.70435918478, - 6758587.0661976915, - 0.05 - ], - [ - 223739.11484217487, - 6758581.483844908, - 0.05 - ], - [ - 223726.31657457672, - 6758578.448909786, - 0.05 - ], - [ - 223708.05052675394, - 6758575.097639576, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 344, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223321.86786006828, - 6757695.328770656, - 0.05 - ], - [ - 223296.6415064484, - 6757661.430440136, - 0.05 - ], - [ - 223295.1881650166, - 6757657.122636248, - 0.05 - ], - [ - 223294.7039182054, - 6757651.131369127, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 345, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223265.57240758004, - 6757670.306503196, - 0.05 - ], - [ - 223213.07385137415, - 6757707.789964144, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 346, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223274.64073252125, - 6757683.718777939, - 0.05 - ], - [ - 223222.057797499, - 6757720.25036344, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 347, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223300.72576869134, - 6757717.915462355, - 0.05 - ], - [ - 223297.27367400524, - 6757713.713474024, - 0.05 - ], - [ - 223288.6649301267, - 6757703.195626779, - 0.05 - ], - [ - 223283.83627665218, - 6757697.310276842, - 0.05 - ], - [ - 223274.64073252125, - 6757683.718777939, - 0.05 - ], - [ - 223269.76438850048, - 6757676.499678678, - 0.05 - ], - [ - 223265.57240758004, - 6757670.306503196, - 0.05 - ], - [ - 223256.32570613455, - 6757656.641135917, - 0.05 - ], - [ - 223226.65686013357, - 6757678.746925927, - 0.05 - ], - [ - 223213.07385137415, - 6757707.789964144, - 0.05 - ], - [ - 223222.057797499, - 6757720.25036344, - 0.05 - ], - [ - 223231.7021930709, - 6757733.627156277, - 0.05 - ], - [ - 223283.83627665218, - 6757697.310276842, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 348, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223610.60754482553, - 6758566.237389289, - 0.05 - ], - [ - 223579.23882958264, - 6758560.08822163, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 349, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223614.3239165058, - 6758557.90032871, - 0.05 - ], - [ - 223629.2557874773, - 6758560.91872956, - 0.05 - ], - [ - 223627.70574788522, - 6758569.181100484, - 0.05 - ], - [ - 223625.10632291215, - 6758568.733426006, - 0.05 - ], - [ - 223610.60754482553, - 6758566.237389289, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 350, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224005.8573738386, - 6757220.438303749, - 0.05 - ], - [ - 223964.54974478955, - 6757159.500361976, - 0.05 - ], - [ - 223965.8640464432, - 6757153.52000924, - 0.05 - ], - [ - 223981.09644631855, - 6757143.640906245, - 0.05 - ], - [ - 223988.68362269434, - 6757143.931487853, - 0.05 - ], - [ - 224030.12862243276, - 6757203.219939933, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 351, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224073.03461105307, - 6757264.597787146, - 0.05 - ], - [ - 224030.12862243276, - 6757203.219939933, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 352, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224005.8573738386, - 6757220.438303749, - 0.05 - ], - [ - 224060.55718502332, - 6757301.162362116, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 353, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223787.770420285, - 6757374.410255257, - 0.05 - ], - [ - 223780.53084517654, - 6757379.353123653, - 0.05 - ], - [ - 223773.42605225334, - 6757384.195946061, - 0.05 - ], - [ - 223769.35370082158, - 6757387.0216101, - 0.05 - ], - [ - 223759.6937183377, - 6757393.553270758, - 0.05 - ], - [ - 223753.38053289987, - 6757397.864042319, - 0.05 - ], - [ - 223706.70621913945, - 6757429.700300987, - 0.05 - ], - [ - 223694.33550021658, - 6757438.134132636, - 0.05 - ], - [ - 223692.5058693182, - 6757445.828203342, - 0.05 - ], - [ - 223683.91557540686, - 6757451.359590936, - 0.05 - ], - [ - 223672.48855093808, - 6757452.672545829, - 0.05 - ], - [ - 223667.45719102275, - 6757455.6314703105, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 354, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224118.4250536544, - 6758229.513571154, - 0.05 - ], - [ - 224111.39313549746, - 6758246.054223171, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 355, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224141.46980411862, - 6758227.798957447, - 0.05 - ], - [ - 224133.61053687282, - 6758230.640170302, - 0.05 - ], - [ - 224129.52764002653, - 6758232.117734737, - 0.05 - ], - [ - 224126.9782960462, - 6758233.036834982, - 0.05 - ], - [ - 224118.4250536544, - 6758229.513571154, - 0.05 - ], - [ - 224103.969888755, - 6758223.557290213, - 0.05 - ], - [ - 224089.1027705185, - 6758217.433645851, - 0.05 - ], - [ - 224079.6399045667, - 6758213.537972037, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 356, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224132.9716218121, - 6758343.362536634, - 0.05 - ], - [ - 224138.7927887396, - 6758345.634901522, - 0.05 - ], - [ - 224164.19581958954, - 6758355.5455449, - 0.05 - ], - [ - 224179.59489049617, - 6758361.559548492, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 357, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224147.7615390538, - 6758308.940811181, - 0.05 - ], - [ - 224153.16424118628, - 6758311.0574639365, - 0.05 - ], - [ - 224191.97085190786, - 6758326.284927754, - 0.05 - ], - [ - 224197.14481431415, - 6758322.958195511, - 0.05 - ], - [ - 224197.26694175007, - 6758317.018303205, - 0.05 - ], - [ - 224169.72408556752, - 6758305.463254761, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 358, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224372.79672799975, - 6758189.30790917, - 0.05 - ], - [ - 224361.8001134331, - 6758193.7951666955, - 0.05 - ], - [ - 224349.44260922092, - 6758198.838073548, - 0.05 - ], - [ - 224335.7821842963, - 6758204.4096699245, - 0.05 - ], - [ - 224320.6076152727, - 6758210.593882531, - 0.05 - ], - [ - 224305.17224548815, - 6758216.8994933115, - 0.05 - ], - [ - 224297.35853455612, - 6758220.026620574, - 0.05 - ], - [ - 224287.0184413083, - 6758224.17125587, - 0.05 - ], - [ - 224271.02656673559, - 6758230.566438788, - 0.05 - ], - [ - 224257.00210417045, - 6758236.189888574, - 0.05 - ], - [ - 224241.84862673393, - 6758242.261148296, - 0.05 - ], - [ - 224219.19497247954, - 6758186.393516927, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 359, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224335.7821842963, - 6758204.4096699245, - 0.05 - ], - [ - 224313.2292984579, - 6758149.03522253, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 360, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224349.44260922092, - 6758198.838073548, - 0.05 - ], - [ - 224327.74703038618, - 6758143.09347676, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 361, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224369.61605569697, - 6758213.251075806, - 0.05 - ], - [ - 224312.904566398, - 6758235.782461002, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 362, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224287.0184413083, - 6758224.17125587, - 0.05 - ], - [ - 224265.12723630754, - 6758168.431474178, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 363, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224089.1027705185, - 6758217.433645851, - 0.05 - ], - [ - 224082.1877272217, - 6758233.931464788, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 364, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224375.56164542428, - 6758228.06477473, - 0.05 - ], - [ - 224319.2029495458, - 6758251.147284824, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 365, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224156.89144545444, - 6758286.167113899, - 0.05 - ], - [ - 224162.7132272151, - 6758288.53977576, - 0.05 - ], - [ - 224167.9916562119, - 6758290.699910092, - 0.05 - ], - [ - 224204.62004118564, - 6758305.668494736, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 366, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224271.02656673559, - 6758230.566438788, - 0.05 - ], - [ - 224249.31600564806, - 6758174.644931247, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 367, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224381.65796899196, - 6758243.256455053, - 0.05 - ], - [ - 224325.18484698219, - 6758265.757374966, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 368, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224257.00210417045, - 6758236.189888574, - 0.05 - ], - [ - 224234.73663117224, - 6758180.380068296, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 369, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224103.969888755, - 6758223.557290213, - 0.05 - ], - [ - 224097.30217236798, - 6758240.046277812, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 370, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224398.1638983676, - 6758252.369703423, - 0.05 - ], - [ - 224387.13272902672, - 6758256.893150066, - 0.05 - ], - [ - 224330.97804659547, - 6758279.892236821, - 0.05 - ], - [ - 224325.18484698219, - 6758265.757374966, - 0.05 - ], - [ - 224319.2029495458, - 6758251.147284824, - 0.05 - ], - [ - 224312.904566398, - 6758235.782461002, - 0.05 - ], - [ - 224308.76643752767, - 6758225.671820103, - 0.05 - ], - [ - 224305.17224548815, - 6758216.8994933115, - 0.05 - ], - [ - 224282.51900000568, - 6758161.5889682425, - 0.05 - ], - [ - 224274.62127937766, - 6758164.700602936, - 0.05 - ], - [ - 224265.12723630754, - 6758168.431474178, - 0.05 - ], - [ - 224249.31600564806, - 6758174.644931247, - 0.05 - ], - [ - 224234.73663117224, - 6758180.380068296, - 0.05 - ], - [ - 224219.19497247954, - 6758186.393516927, - 0.05 - ], - [ - 224215.05947864352, - 6758175.758822791, - 0.05 - ], - [ - 224210.50689819793, - 6758164.05425939, - 0.05 - ], - [ - 224205.70650908875, - 6758151.700890945, - 0.05 - ], - [ - 224201.8578930148, - 6758149.001787282, - 0.05 - ], - [ - 224199.9612801636, - 6758149.812457344, - 0.05 - ], - [ - 224149.82489573956, - 6758171.2910308065, - 0.05 - ], - [ - 224155.86752488936, - 6758186.275069187, - 0.05 - ], - [ - 224206.4896211928, - 6758165.693671337, - 0.05 - ], - [ - 224210.50689819793, - 6758164.05425939, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 371, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224210.50689819793, - 6758164.05425939, - 0.05 - ], - [ - 224264.8177065092, - 6758141.949665572, - 0.05 - ], - [ - 224272.03069242794, - 6758139.015868609, - 0.05 - ], - [ - 224277.3672268638, - 6758151.214564534, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 372, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224403.17128197133, - 6758297.589141371, - 0.05 - ], - [ - 224389.40959213616, - 6758262.661839891, - 0.05 - ], - [ - 224387.13272902672, - 6758256.893150066, - 0.05 - ], - [ - 224381.65796899196, - 6758243.256455053, - 0.05 - ], - [ - 224375.56164542428, - 6758228.06477473, - 0.05 - ], - [ - 224369.61605569697, - 6758213.251075806, - 0.05 - ], - [ - 224365.43985657668, - 6758202.853660416, - 0.05 - ], - [ - 224361.8001134331, - 6758193.7951666955, - 0.05 - ], - [ - 224342.21833285404, - 6758144.311667, - 0.05 - ], - [ - 224337.553659036, - 6758141.466512284, - 0.05 - ], - [ - 224331.50919842464, - 6758141.552753696, - 0.05 - ], - [ - 224327.74703038618, - 6758143.09347676, - 0.05 - ], - [ - 224313.2292984579, - 6758149.03522253, - 0.05 - ], - [ - 224298.09941022337, - 6758155.215877432, - 0.05 - ], - [ - 224282.51900000568, - 6758161.5889682425, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 373, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224320.6076152727, - 6758210.593882531, - 0.05 - ], - [ - 224298.09941022337, - 6758155.215877432, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 374, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224198.7455936022, - 6757243.754991727, - 0.05 - ], - [ - 224115.17435245693, - 6757275.76640564, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 375, - "lwd63": 81.89725490106659, - "lwd125": 71.88783370853906, - "lwd250": 70.45347125200192, - "lwd500": 70.77472168108605, - "lwd1000": 72.60927071449348, - "lwd2000": 69.89498221182919, - "lwd4000": 65.13201503418793, - "lwd8000": 57.66372583065063, - "lwe63": 76.39340352366376, - "lwe125": 66.3839849143855, - "lwe250": 64.94962358085901, - "lwe500": 65.27087372526692, - "lwe1000": 67.10542148114162, - "lwe2000": 64.39113508859629, - "lwe4000": 59.62817696611757, - "lwe8000": 52.15995006422352, - "lwn63": 73.38310396559334, - "lwn125": 63.37368895209104, - "lwn250": 61.939329181747304, - "lwn500": 62.26057892989822, - "lwn1000": 64.09512490750173, - "lwn2000": 61.38084145215147, - "lwn4000": 56.617895934032056, - "lwn8000": 49.14975575138363 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223708.91363963438, - 6757723.204447144, - 0.05 - ], - [ - 223722.39406151744, - 6757747.418889239, - 0.05 - ], - [ - 223732.31190165982, - 6757765.221865437, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 376, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223759.7398134804, - 6757745.796519632, - 0.05 - ], - [ - 223771.8048263468, - 6757764.774925778, - 0.05 - ], - [ - 223819.91001656884, - 6757737.471586048, - 0.05 - ], - [ - 223805.39923619042, - 6757713.340144078, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 377, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223674.40549441735, - 6757769.831376128, - 0.05 - ], - [ - 223634.98396554706, - 6757795.921840168, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 378, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223102.92444410775, - 6758261.396396994, - 0.05 - ], - [ - 223075.31919657544, - 6758279.691409958, - 0.05 - ], - [ - 223061.04516711587, - 6758312.614323652, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 379, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223057.5081524746, - 6757268.9225027, - 0.05 - ], - [ - 223068.29965055134, - 6757271.460823767, - 0.05 - ], - [ - 223062.88310950896, - 6757294.482189977, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 380, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223660.26952825772, - 6757209.2010318125, - 0.05 - ], - [ - 223654.00639137364, - 6757200.354753363, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 381, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223664.77826831257, - 6757215.781309239, - 0.05 - ], - [ - 223660.26952825772, - 6757209.2010318125, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 382, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223654.00639137364, - 6757200.354753363, - 0.05 - ], - [ - 223652.31302160316, - 6757197.727127211, - 0.05 - ], - [ - 223653.68578586826, - 6757187.260986607, - 0.05 - ], - [ - 223637.52815550577, - 6757163.240579962, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 383, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223540.13552904583, - 6757404.730913384, - 0.05 - ], - [ - 223527.45181768073, - 6757413.290710314, - 0.05 - ], - [ - 223502.3467753167, - 6757375.491553484, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 384, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223548.52131113823, - 6757416.771923779, - 0.05 - ], - [ - 223542.57005765685, - 6757408.156936945, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 385, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223553.42621998844, - 6757423.509614314, - 0.05 - ], - [ - 223548.52131113823, - 6757416.771923779, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 386, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223542.57005765685, - 6757408.156936945, - 0.05 - ], - [ - 223540.13552904583, - 6757404.730913384, - 0.05 - ], - [ - 223519.01058920095, - 6757374.970224332, - 0.05 - ], - [ - 223502.3467753167, - 6757375.491553484, - 0.05 - ], - [ - 223484.41521811584, - 6757376.0484694885, - 0.05 - ], - [ - 223483.45553846535, - 6757357.934537763, - 0.05 - ], - [ - 223518.2764430978, - 6757355.924044596, - 0.05 - ], - [ - 223526.94517498533, - 6757353.317670939, - 0.05 - ], - [ - 223538.1082978128, - 6757347.990654054, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 387, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223403.24237504968, - 6758513.180387304, - 0.05 - ], - [ - 223408.99394712865, - 6758480.267168787, - 0.05 - ], - [ - 223468.88091780734, - 6758490.297405706, - 0.05 - ], - [ - 223502.08919504227, - 6758495.762338406, - 0.05 - ], - [ - 223509.07315608143, - 6758454.278117873, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 388, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223463.79065348755, - 6758523.770178057, - 0.05 - ], - [ - 223465.01784543286, - 6758515.701040592, - 0.05 - ], - [ - 223468.88091780734, - 6758490.297405706, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 389, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223185.15360718995, - 6758431.123855236, - 0.05 - ], - [ - 223178.11898350331, - 6758476.324624059, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 390, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223232.33726985502, - 6758428.50173569, - 0.05 - ], - [ - 223197.4765966839, - 6758422.692551541, - 0.05 - ], - [ - 223195.93501763075, - 6758416.084498661, - 0.05 - ], - [ - 223196.0623720971, - 6758377.773651979, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 391, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223237.20850113087, - 6758400.608667266, - 0.05 - ], - [ - 223245.55703128467, - 6758398.897076765, - 0.05 - ], - [ - 223316.09043537738, - 6758403.450375721, - 0.05 - ], - [ - 223349.9531974141, - 6758440.719215521, - 0.05 - ], - [ - 223347.42730544158, - 6758454.388738633, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 392, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223066.33865536627, - 6758467.484284725, - 0.05 - ], - [ - 223066.98466029565, - 6758458.369637093, - 0.05 - ], - [ - 223032.88507522218, - 6758439.20165142, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 393, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223026.5624853043, - 6758465.495742414, - 0.05 - ], - [ - 223027.59603898198, - 6758445.838241096, - 0.05 - ], - [ - 223029.6667721597, - 6758440.676959504, - 0.05 - ], - [ - 223032.88507522218, - 6758439.20165142, - 0.05 - ], - [ - 223052.50531567278, - 6758430.190974016, - 0.05 - ], - [ - 223082.7383850058, - 6758449.604882151, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 394, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222996.62613486068, - 6758464.249810686, - 0.05 - ], - [ - 222995.99438008195, - 6758486.828749954, - 0.05 - ], - [ - 222941.98765503813, - 6758485.668615124, - 0.05 - ], - [ - 222837.03780298412, - 6758483.402891128, - 0.05 - ], - [ - 222837.34364963952, - 6758460.148003855, - 0.05 - ], - [ - 222837.77671393438, - 6758442.088427732, - 0.05 - ], - [ - 222870.05713267694, - 6758442.943270245, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 395, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224006.06086767832, - 6758220.055895023, - 0.05 - ], - [ - 224038.61987650162, - 6758227.995140312, - 0.05 - ], - [ - 224034.90835005138, - 6758243.1086630495, - 0.05 - ], - [ - 224002.34941371263, - 6758235.169437648, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 396, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224002.34941371263, - 6758235.169437648, - 0.05 - ], - [ - 224005.10437400237, - 6758223.945271451, - 0.05 - ], - [ - 224006.06086767832, - 6758220.055895023, - 0.05 - ], - [ - 224010.8140622673, - 6758200.711701153, - 0.05 - ], - [ - 224071.2269383105, - 6758215.665976016, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 397, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223972.04818218952, - 6758205.936265913, - 0.05 - ], - [ - 223988.60586347774, - 6758218.566614567, - 0.05 - ], - [ - 224005.10437400237, - 6758223.945271451, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 398, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224075.87516436703, - 6758183.1883650655, - 0.05 - ], - [ - 224055.80392855767, - 6758178.064399547, - 0.05 - ], - [ - 224057.46409022482, - 6758169.759887441, - 0.05 - ], - [ - 224054.2555270256, - 6758154.034461945, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 399, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223865.16959553672, - 6758003.723998708, - 0.05 - ], - [ - 223815.9958443687, - 6758031.080006143, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 400, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223857.33172733, - 6757989.141513106, - 0.05 - ], - [ - 223807.86269827653, - 6758016.566005079, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 401, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223255.72745780658, - 6757157.459260596, - 0.05 - ], - [ - 223264.1425084339, - 6757156.7345307795, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 402, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223241.82073010656, - 6757159.263244189, - 0.05 - ], - [ - 223255.72745780658, - 6757157.459260596, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 403, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223264.1425084339, - 6757156.7345307795, - 0.05 - ], - [ - 223282.60247491673, - 6757155.822185098, - 0.05 - ], - [ - 223286.25979106897, - 6757174.933083709, - 0.05 - ], - [ - 223352.4082207636, - 6757179.942636285, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 404, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224123.26099785342, - 6757683.025397623, - 0.05 - ], - [ - 224105.8636981637, - 6757676.492709652, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 405, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224117.830766246, - 6757698.277450055, - 0.05 - ], - [ - 224100.75314507855, - 6757691.886185698, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 406, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224104.53770708613, - 6757735.621275789, - 0.05 - ], - [ - 224117.830766246, - 6757698.277450055, - 0.05 - ], - [ - 224123.26099785342, - 6757683.025397623, - 0.05 - ], - [ - 224129.1579598275, - 6757666.4761238955, - 0.05 - ], - [ - 224101.56386037671, - 6757656.931723664, - 0.05 - ], - [ - 224098.77152207, - 6757654.749356131, - 0.05 - ], - [ - 224082.09247915464, - 6757635.317821755, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 407, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224084.97343026433, - 6757694.965221155, - 0.05 - ], - [ - 224098.77152207, - 6757654.749356131, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 408, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224233.9998679413, - 6757652.366633356, - 0.05 - ], - [ - 224247.16632154532, - 6757650.814108325, - 0.05 - ], - [ - 224242.05442912533, - 6757617.452146741, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 409, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224469.7347346312, - 6758152.6208642945, - 0.05 - ], - [ - 224467.63788981055, - 6758195.604183946, - 0.05 - ], - [ - 224449.9406345372, - 6758194.556656424, - 0.05 - ], - [ - 224452.2670167596, - 6758151.811184546, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 410, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224463.95421264542, - 6758084.847257843, - 0.05 - ], - [ - 224465.80666784145, - 6758105.397189932, - 0.05 - ], - [ - 224488.9936648088, - 6758145.438938532, - 0.05 - ], - [ - 224486.30311302358, - 6758204.554709138, - 0.05 - ], - [ - 224414.1506553162, - 6758200.608410785, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 411, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224392.17033238715, - 6758214.776093142, - 0.05 - ], - [ - 224396.2935606435, - 6758213.518396086, - 0.05 - ], - [ - 224398.27166823432, - 6758211.854071124, - 0.05 - ], - [ - 224399.56240621576, - 6758209.030195214, - 0.05 - ], - [ - 224400.3220584162, - 6758205.95933647, - 0.05 - ], - [ - 224400.11281053635, - 6758202.1529097725, - 0.05 - ], - [ - 224398.93581199204, - 6758198.836954117, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 412, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224342.77396162244, - 6757713.672080744, - 0.05 - ], - [ - 224360.58113418508, - 6757696.953962786, - 0.05 - ], - [ - 224386.73354876757, - 6757686.206320648, - 0.05 - ], - [ - 224391.52867072634, - 6757678.173060379, - 0.05 - ], - [ - 224391.288120759, - 6757670.155747105, - 0.05 - ], - [ - 224390.17960146023, - 6757654.171716505, - 0.05 - ], - [ - 224385.15352670714, - 6757581.5889877705, - 0.05 - ], - [ - 224386.22939285036, - 6757572.462328398, - 0.05 - ], - [ - 224393.31595537526, - 6757565.247497671, - 0.05 - ], - [ - 224426.45007384743, - 6757558.562944709, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 413, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224376.07777548273, - 6758119.164931572, - 0.05 - ], - [ - 224391.04055537411, - 6758117.15566639, - 0.05 - ], - [ - 224399.0378090081, - 6758166.3585351575, - 0.05 - ], - [ - 224398.93581199204, - 6758198.836954117, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 414, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224474.5701771049, - 6758136.235545683, - 0.05 - ], - [ - 224410.30889499537, - 6758133.859989553, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 415, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224483.34973273316, - 6757820.624351751, - 0.05 - ], - [ - 224393.7911955539, - 6757849.983006418, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 416, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224279.6356322097, - 6758114.381348578, - 0.05 - ], - [ - 224281.10437632055, - 6758125.320363268, - 0.05 - ], - [ - 224282.29814374854, - 6758127.631747945, - 0.05 - ], - [ - 224284.83170966431, - 6758129.032499218, - 0.05 - ], - [ - 224287.58362434147, - 6758129.412438964, - 0.05 - ], - [ - 224290.763584261, - 6758128.854972784, - 0.05 - ], - [ - 224335.9911922344, - 6758119.57788738, - 0.05 - ], - [ - 224339.58251034003, - 6758119.087589859, - 0.05 - ], - [ - 224343.585749369, - 6758118.764711256, - 0.05 - ], - [ - 224347.07277190464, - 6758119.497815497, - 0.05 - ], - [ - 224350.32446149457, - 6758121.041314404, - 0.05 - ], - [ - 224353.31816410378, - 6758123.207541517, - 0.05 - ], - [ - 224354.51481136214, - 6758124.716147218, - 0.05 - ], - [ - 224356.0133800165, - 6758126.612828729, - 0.05 - ], - [ - 224357.98956327833, - 6758129.864321751, - 0.05 - ], - [ - 224392.17033238715, - 6758214.776093142, - 0.05 - ], - [ - 224398.5830712578, - 6758230.72253512, - 0.05 - ], - [ - 224400.52705265116, - 6758233.575357241, - 0.05 - ], - [ - 224403.57791024476, - 6758235.146223355, - 0.05 - ], - [ - 224407.2495396139, - 6758235.652683438, - 0.05 - ], - [ - 224413.07008781983, - 6758235.774061937, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 417, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224398.93581199204, - 6758198.836954117, - 0.05 - ], - [ - 224383.84127740993, - 6758162.857902577, - 0.05 - ], - [ - 224376.07777548273, - 6758119.164931572, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 418, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224370.45375120093, - 6757784.416767085, - 0.05 - ], - [ - 224380.40629419644, - 6757817.778567579, - 0.05 - ], - [ - 224381.86217206082, - 6757845.806399901, - 0.05 - ], - [ - 224381.4652845277, - 6757866.14756842, - 0.05 - ], - [ - 224377.19307018275, - 6757922.983242169, - 0.05 - ], - [ - 224379.70541366108, - 6757954.136123081, - 0.05 - ], - [ - 224388.79003553517, - 6758011.321429445, - 0.05 - ], - [ - 224400.19765282486, - 6758083.144455935, - 0.05 - ], - [ - 224404.23356085556, - 6758094.132829091, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 419, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224354.51481136214, - 6758124.716147218, - 0.05 - ], - [ - 224359.33111692657, - 6758121.518747013, - 0.05 - ], - [ - 224376.07777548273, - 6758119.164931572, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 420, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224408.12734182284, - 6758119.578717443, - 0.05 - ], - [ - 224439.79671403754, - 6758119.566321757, - 0.05 - ], - [ - 224455.41675034346, - 6758119.555202308, - 0.05 - ], - [ - 224466.03793155745, - 6758119.545916866, - 0.05 - ], - [ - 224474.5701771049, - 6758136.235545683, - 0.05 - ], - [ - 224478.96272386867, - 6758144.843262762, - 0.05 - ], - [ - 224478.41212862398, - 6758153.024702851, - 0.05 - ], - [ - 224469.7347346312, - 6758152.6208642945, - 0.05 - ], - [ - 224452.2670167596, - 6758151.811184546, - 0.05 - ], - [ - 224412.77491846704, - 6758149.990959017, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 421, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224388.79003553517, - 6758011.321429445, - 0.05 - ], - [ - 224344.5706863664, - 6758018.476880186, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 422, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224381.4652845277, - 6757866.14756842, - 0.05 - ], - [ - 224393.68286836165, - 6757866.16550155, - 0.05 - ], - [ - 224403.4644029754, - 6757866.179263972, - 0.05 - ], - [ - 224488.60800785408, - 6757836.7977068545, - 0.05 - ], - [ - 224483.34973273316, - 6757820.624351751, - 0.05 - ], - [ - 224478.42095797946, - 6757805.46106912, - 0.05 - ], - [ - 224396.7871454702, - 6757833.344718651, - 0.05 - ], - [ - 224393.87315460498, - 6757837.202360816, - 0.05 - ], - [ - 224393.7911955539, - 6757849.983006418, - 0.05 - ], - [ - 224393.68286836165, - 6757866.16550155, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 423, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224439.79671403754, - 6758119.566321757, - 0.05 - ], - [ - 224436.939860266, - 6758098.774129284, - 0.05 - ], - [ - 224452.0641717002, - 6758096.250399618, - 0.05 - ], - [ - 224455.41675034346, - 6758119.555202308, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 424, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224245.99176684505, - 6757898.787957762, - 0.05 - ], - [ - 224274.67700155027, - 6758091.863797233, - 0.05 - ], - [ - 224279.6356322097, - 6758114.381348578, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 425, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224332.6249838494, - 6757690.369287376, - 0.05 - ], - [ - 224336.39108299167, - 6757704.533874659, - 0.05 - ], - [ - 224342.77396162244, - 6757713.672080744, - 0.05 - ], - [ - 224349.59035702457, - 6757733.219720279, - 0.05 - ], - [ - 224370.45375120093, - 6757784.416767085, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 426, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224391.288120759, - 6757670.155747105, - 0.05 - ], - [ - 224361.37541084515, - 6757681.819673984, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 427, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224390.17960146023, - 6757654.171716505, - 0.05 - ], - [ - 224367.55229748442, - 6757663.420069122, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 428, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224444.427489385, - 6758368.465400391, - 0.05 - ], - [ - 224439.7309475171, - 6758446.971072145, - 0.05 - ], - [ - 224435.67364301777, - 6758514.757882726, - 0.05 - ], - [ - 224419.13334665057, - 6758513.78441768, - 0.05 - ], - [ - 224423.1865710264, - 6758446.042497155, - 0.05 - ], - [ - 224427.8867953511, - 6758367.491912084, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 429, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224227.7833610174, - 6758552.148028207, - 0.05 - ], - [ - 224232.15013892838, - 6758541.986624257, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 430, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224212.93087955686, - 6758546.100981902, - 0.05 - ], - [ - 224217.39804656146, - 6758535.786559132, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 431, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224228.6680042529, - 6758540.47294064, - 0.05 - ], - [ - 224243.87023026857, - 6758507.623278108, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 432, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224214.72176325123, - 6758534.664881034, - 0.05 - ], - [ - 224229.29635018966, - 6758501.6763222255, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 433, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224204.118374578, - 6758521.843384115, - 0.05 - ], - [ - 224214.87059057306, - 6758495.795476447, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 434, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224255.51419693022, - 6758512.379858956, - 0.05 - ], - [ - 224240.74834140507, - 6758540.390056359, - 0.05 - ], - [ - 224236.78647054895, - 6758542.526602263, - 0.05 - ], - [ - 224232.15013892838, - 6758541.986624257, - 0.05 - ], - [ - 224228.6680042529, - 6758540.47294064, - 0.05 - ], - [ - 224217.39804656146, - 6758535.786559132, - 0.05 - ], - [ - 224214.72176325123, - 6758534.664881034, - 0.05 - ], - [ - 224210.3503959803, - 6758532.843964383, - 0.05 - ], - [ - 224192.28397664265, - 6758525.161333984, - 0.05 - ], - [ - 224192.30763034837, - 6758519.864741065, - 0.05 - ], - [ - 224192.32681709074, - 6758514.512775218, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 435, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224140.68888999446, - 6758520.975634616, - 0.05 - ], - [ - 224150.02723268076, - 6758499.021053481, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 436, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224155.21017111617, - 6758527.294462545, - 0.05 - ], - [ - 224164.27031384758, - 6758504.593231925, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 437, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224169.2511578694, - 6758533.250796901, - 0.05 - ], - [ - 224178.62149616203, - 6758510.201307078, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 438, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224284.00830036832, - 6758496.604838618, - 0.05 - ], - [ - 224308.603960921, - 6758438.742453636, - 0.05 - ], - [ - 224324.25375371415, - 6758445.260476891, - 0.05 - ], - [ - 224299.5789057057, - 6758502.794776655, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 439, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224384.43284161808, - 6758381.028334269, - 0.05 - ], - [ - 224397.1343014688, - 6758350.242376, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 440, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224412.1413234127, - 6758389.148941787, - 0.05 - ], - [ - 224402.67139196023, - 6758388.88716911, - 0.05 - ], - [ - 224384.43284161808, - 6758381.028334269, - 0.05 - ], - [ - 224372.1131804427, - 6758375.724068659, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 441, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224206.37574127945, - 6758179.190339654, - 0.05 - ], - [ - 224210.61223675613, - 6758189.772293713, - 0.05 - ], - [ - 224159.39088358777, - 6758209.911572004, - 0.05 - ], - [ - 224155.306356175, - 6758199.350825402, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 442, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224274.7881778797, - 6758304.221185189, - 0.05 - ], - [ - 224313.05250424758, - 6758288.873257797, - 0.05 - ], - [ - 224412.00849821512, - 6758330.550511514, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 443, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224265.00215144467, - 6758299.950022486, - 0.05 - ], - [ - 224267.73645832064, - 6758307.008227941, - 0.05 - ], - [ - 224274.7881778797, - 6758304.221185189, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 444, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224135.76548024185, - 6758213.467580552, - 0.05 - ], - [ - 224162.38398399175, - 6758224.740391916, - 0.05 - ], - [ - 224233.45395254553, - 6758254.865324381, - 0.05 - ], - [ - 224247.9306556417, - 6758260.998515015, - 0.05 - ], - [ - 224249.45613664016, - 6758261.644572141, - 0.05 - ], - [ - 224265.00215144467, - 6758299.950022486, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 445, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224236.78647054895, - 6758542.526602263, - 0.05 - ], - [ - 224239.47713987104, - 6758545.876468855, - 0.05 - ], - [ - 224244.74893339822, - 6758548.516498077, - 0.05 - ], - [ - 224249.96536910033, - 6758547.86157527, - 0.05 - ], - [ - 224257.36459982523, - 6758544.634021237, - 0.05 - ], - [ - 224259.61589268682, - 6758541.699166075, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 446, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224127.66903384798, - 6758193.1539651295, - 0.05 - ], - [ - 224133.5779115185, - 6758207.970431031, - 0.05 - ], - [ - 224135.76548024185, - 6758213.467580552, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 447, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223755.31386726088, - 6757443.130714656, - 0.05 - ], - [ - 223727.45049734745, - 6757461.465283102, - 0.05 - ], - [ - 223712.97761313623, - 6757439.303931101, - 0.05 - ], - [ - 223706.70621913945, - 6757429.700300987, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 448, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223583.63134131004, - 6757515.705442069, - 0.05 - ], - [ - 223588.73413081229, - 6757512.0495716315, - 0.05 - ], - [ - 223636.65559910698, - 6757477.703851863, - 0.05 - ], - [ - 223667.45719102275, - 6757455.6314703105, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 449, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223733.38063914003, - 6758703.792407094, - 0.05 - ], - [ - 223684.8102559524, - 6758836.895633126, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 450, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224097.37211119966, - 6758292.5193006275, - 0.05 - ], - [ - 224094.57579313702, - 6758302.487177505, - 0.05 - ], - [ - 224112.36039841507, - 6758310.114277344, - 0.05 - ], - [ - 224122.7711461038, - 6758314.580011935, - 0.05 - ], - [ - 224124.76324335695, - 6758321.753790425, - 0.05 - ], - [ - 224104.31611197977, - 6758369.439676359, - 0.05 - ], - [ - 224097.74679061415, - 6758371.775577781, - 0.05 - ], - [ - 224092.63091564673, - 6758369.580096984, - 0.05 - ], - [ - 224090.45265758858, - 6758363.825833869, - 0.05 - ], - [ - 224112.36039841507, - 6758310.114277344, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 451, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224072.376614796, - 6758285.986920165, - 0.05 - ], - [ - 224097.37211119966, - 6758292.5193006275, - 0.05 - ], - [ - 224129.64039204596, - 6758300.961777331, - 0.05 - ], - [ - 224139.25775661157, - 6758305.190600384, - 0.05 - ], - [ - 224147.7615390538, - 6758308.940811181, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 452, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224394.5443309982, - 6758590.283021043, - 0.05 - ], - [ - 224347.47313420125, - 6758584.393117259, - 0.05 - ], - [ - 224337.14816023607, - 6758608.845767148, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 453, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223703.80393721198, - 6758657.558974676, - 0.05 - ], - [ - 223691.59586096165, - 6758653.919115516, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 454, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223727.14714239357, - 6758664.212028575, - 0.05 - ], - [ - 223711.3674402155, - 6758659.812799956, - 0.05 - ], - [ - 223703.80393721198, - 6758657.558974676, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 455, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224318.40685170074, - 6757538.684632683, - 0.05 - ], - [ - 224306.48202430567, - 6757540.627288779, - 0.05 - ], - [ - 224244.34848872205, - 6757550.732846088, - 0.05 - ], - [ - 224228.98767790187, - 6757553.2314857105, - 0.05 - ], - [ - 224188.0905461965, - 6757562.750448867, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 456, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224060.94783480687, - 6758499.153852338, - 0.05 - ], - [ - 224067.66205601516, - 6758494.610297968, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 457, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224056.0265195754, - 6758508.122869472, - 0.05 - ], - [ - 224060.94783480687, - 6758499.153852338, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 458, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224051.94565221347, - 6758515.117970808, - 0.05 - ], - [ - 224056.0265195754, - 6758508.122869472, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 459, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224135.2761982443, - 6758555.90033996, - 0.05 - ], - [ - 224147.08576106, - 6758562.894982104, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 460, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224126.33223471808, - 6758551.62835391, - 0.05 - ], - [ - 224135.2761982443, - 6758555.90033996, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 461, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224051.94565221347, - 6758515.117970808, - 0.05 - ], - [ - 224058.58248382673, - 6758514.7383774845, - 0.05 - ], - [ - 224116.23877715954, - 6758544.662463468, - 0.05 - ], - [ - 224126.33223471808, - 6758551.62835391, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 462, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224051.94565221347, - 6758515.117970808, - 0.05 - ], - [ - 224046.5036246488, - 6758508.880305112, - 0.05 - ], - [ - 224048.03490268264, - 6758463.868863587, - 0.05 - ], - [ - 224052.7782432062, - 6758460.331514126, - 0.05 - ], - [ - 224060.04088348674, - 6758460.3472884195, - 0.05 - ], - [ - 224063.97934805806, - 6758464.2540354915, - 0.05 - ], - [ - 224073.9850871039, - 6758481.214388037, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 463, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224036.08295542002, - 6758555.79078918, - 0.05 - ], - [ - 224036.5369454389, - 6758547.5390074905, - 0.05 - ], - [ - 224051.94565221347, - 6758515.117970808, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 464, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223619.2163916924, - 6758304.406262953, - 0.05 - ], - [ - 223626.72080996243, - 6758311.413311354, - 0.05 - ], - [ - 223629.4804388245, - 6758318.123686844, - 0.05 - ], - [ - 223630.4161148016, - 6758325.98460753, - 0.05 - ], - [ - 223628.9866355895, - 6758332.297684093, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 465, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223566.2639562867, - 6758319.095060915, - 0.05 - ], - [ - 223604.20364253485, - 6758323.565312729, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 466, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223691.79260544875, - 6758513.687855566, - 0.05 - ], - [ - 223761.17540278478, - 6758519.476218619, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 467, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223117.67984119622, - 6758777.283834469, - 0.05 - ], - [ - 223110.5542344012, - 6758772.453856023, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 468, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223140.00265769678, - 6758774.007223154, - 0.05 - ], - [ - 223117.67984119622, - 6758777.283834469, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 469, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223149.55096140614, - 6758765.109016291, - 0.05 - ], - [ - 223148.15942619368, - 6758772.812564901, - 0.05 - ], - [ - 223140.00265769678, - 6758774.007223154, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 470, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223153.59795058647, - 6758781.412892477, - 0.05 - ], - [ - 223155.28308555798, - 6758763.6757110525, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 471, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223152.21114180656, - 6758806.650094225, - 0.05 - ], - [ - 223153.59795058647, - 6758781.412892477, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 472, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223168.39006162592, - 6758474.8150274865, - 0.05 - ], - [ - 223178.11898350331, - 6758476.324624059, - 0.05 - ], - [ - 223224.1328801131, - 6758484.063236308, - 0.05 - ], - [ - 223234.01560789457, - 6758485.616221487, - 0.05 - ], - [ - 223327.60322766943, - 6758500.310892341, - 0.05 - ], - [ - 223365.40542410372, - 6758506.250893226, - 0.05 - ], - [ - 223403.24237504968, - 6758513.180387304, - 0.05 - ], - [ - 223457.56145479577, - 6758522.5903863525, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 473, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223148.24662159017, - 6758471.684116569, - 0.05 - ], - [ - 223168.39006162592, - 6758474.8150274865, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 474, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223131.16806814348, - 6758646.632939586, - 0.05 - ], - [ - 223151.3357015297, - 6758650.441752438, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 475, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223020.88556939492, - 6758621.0525653185, - 0.05 - ], - [ - 223022.16963382153, - 6758616.946972748, - 0.05 - ], - [ - 223023.29771340766, - 6758614.25850465, - 0.05 - ], - [ - 223026.48426140344, - 6758612.4847867135, - 0.05 - ], - [ - 223038.7671217654, - 6758613.508896729, - 0.05 - ], - [ - 223054.30150623532, - 6758616.165018824, - 0.05 - ], - [ - 223069.0373299736, - 6758620.100775138, - 0.05 - ], - [ - 223081.82810931065, - 6758624.896124594, - 0.05 - ], - [ - 223092.57412733574, - 6758629.410991108, - 0.05 - ], - [ - 223111.938029108, - 6758638.245034061, - 0.05 - ], - [ - 223124.01890043163, - 6758644.301741417, - 0.05 - ], - [ - 223131.16806814348, - 6758646.632939586, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 476, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223150.01549701858, - 6758668.695607958, - 0.05 - ], - [ - 223156.42657037906, - 6758669.615132684, - 0.05 - ], - [ - 223167.4698820397, - 6758670.650557055, - 0.05 - ], - [ - 223237.76741709263, - 6758676.971812797, - 0.05 - ], - [ - 223280.81793382583, - 6758680.525034467, - 0.05 - ], - [ - 223295.3164522861, - 6758681.71609606, - 0.05 - ], - [ - 223369.70637823176, - 6758687.618894205, - 0.05 - ], - [ - 223413.23014111986, - 6758691.079079268, - 0.05 - ], - [ - 223427.08627616597, - 6758692.879717379, - 0.05 - ], - [ - 223439.1055510856, - 6758695.0183292935, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 477, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223128.27482274675, - 6758665.604795869, - 0.05 - ], - [ - 223146.92048471345, - 6758668.254777814, - 0.05 - ], - [ - 223150.01549701858, - 6758668.695607958, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 478, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223118.82303475146, - 6758770.971424947, - 0.05 - ], - [ - 223139.856947298, - 6758767.185971479, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 479, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222858.6666969275, - 6758645.824431337, - 0.05 - ], - [ - 222864.89227869327, - 6758654.48346252, - 0.05 - ], - [ - 222898.9926593366, - 6758686.859471723, - 0.05 - ], - [ - 222917.5903622426, - 6758704.059325584, - 0.05 - ], - [ - 222949.13486215053, - 6758727.613379832, - 0.05 - ], - [ - 222957.21089078754, - 6758732.109912147, - 0.05 - ], - [ - 223028.16999995348, - 6758758.227740547, - 0.05 - ], - [ - 223061.77265930915, - 6758770.435539792, - 0.05 - ], - [ - 223082.69615823746, - 6758777.460142187, - 0.05 - ], - [ - 223110.5542344012, - 6758772.453856023, - 0.05 - ], - [ - 223118.82303475146, - 6758770.971424947, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 480, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223733.42079250526, - 6758765.341715863, - 0.05 - ], - [ - 223718.61288809282, - 6758760.12831018, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 481, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223761.98560129345, - 6758707.936168892, - 0.05 - ], - [ - 223763.76976742398, - 6758698.941535899, - 0.05 - ], - [ - 223954.06689877732, - 6758723.581871344, - 0.05 - ], - [ - 223953.77952721447, - 6758731.474677996, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 482, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223237.76741709263, - 6758676.971812797, - 0.05 - ], - [ - 223235.6803568019, - 6758688.253965364, - 0.05 - ], - [ - 223278.38549887243, - 6758691.534121796, - 0.05 - ], - [ - 223280.81793382583, - 6758680.525034467, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 483, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223282.12251247192, - 6758729.019837495, - 0.05 - ], - [ - 223295.3164522861, - 6758681.71609606, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 484, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223353.4217043933, - 6758731.192828229, - 0.05 - ], - [ - 223345.94164390233, - 6758757.312573547, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 485, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223380.7060105407, - 6758710.249660722, - 0.05 - ], - [ - 223387.27411970426, - 6758711.067561586, - 0.05 - ], - [ - 223399.99137266295, - 6758714.308949911, - 0.05 - ], - [ - 223405.40465895552, - 6758720.927384241, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 486, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223678.31018796685, - 6758155.594572566, - 0.05 - ], - [ - 223668.85454881104, - 6758146.861250655, - 0.05 - ], - [ - 223666.48316614586, - 6758144.678525839, - 0.05 - ], - [ - 223653.9730106386, - 6758155.832523873, - 0.05 - ], - [ - 223631.52262739156, - 6758121.262889955, - 0.05 - ], - [ - 223631.10757425975, - 6758117.9858282665, - 0.05 - ], - [ - 223631.17592994298, - 6758114.457930972, - 0.05 - ], - [ - 223633.35081921145, - 6758102.667333149, - 0.05 - ], - [ - 223634.44155742245, - 6758100.628547148, - 0.05 - ], - [ - 223635.85332383134, - 6758099.399837573, - 0.05 - ], - [ - 223637.71760254854, - 6758098.747649043, - 0.05 - ], - [ - 223647.4831568267, - 6758097.914273003, - 0.05 - ], - [ - 223649.67789502325, - 6758096.979021229, - 0.05 - ], - [ - 223651.54722375935, - 6758094.620975865, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 487, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223575.8447073321, - 6758122.148973071, - 0.05 - ], - [ - 223653.80735371547, - 6758078.766087504, - 0.05 - ], - [ - 223688.91516422457, - 6758059.232692875, - 0.05 - ], - [ - 223707.82219395717, - 6758092.282915532, - 0.05 - ], - [ - 223677.82342591375, - 6758115.316079474, - 0.05 - ], - [ - 223674.33677952545, - 6758117.102497548, - 0.05 - ], - [ - 223671.11659324827, - 6758117.1619431265, - 0.05 - ], - [ - 223668.13880446303, - 6758116.499566884, - 0.05 - ], - [ - 223653.02354085183, - 6758110.385858247, - 0.05 - ], - [ - 223651.54722375935, - 6758094.620975865, - 0.05 - ], - [ - 223654.24315711582, - 6758086.76769674, - 0.05 - ], - [ - 223653.80735371547, - 6758078.766087504, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 488, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223640.9567807928, - 6758053.598028247, - 0.05 - ], - [ - 223647.3862605334, - 6758066.187289666, - 0.05 - ], - [ - 223653.80735371547, - 6758078.766087504, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 489, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223590.24532880215, - 6757572.92239366, - 0.05 - ], - [ - 223610.54391918005, - 6757558.675879272, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 490, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223582.4581251826, - 6757578.4336721115, - 0.05 - ], - [ - 223590.24532880215, - 6757572.92239366, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 491, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223546.4969112039, - 6757603.910714009, - 0.05 - ], - [ - 223554.3981909856, - 6757598.323286723, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 492, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223518.7927909725, - 6757623.548840558, - 0.05 - ], - [ - 223546.4969112039, - 6757603.910714009, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 493, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223510.26558928814, - 6757629.577024713, - 0.05 - ], - [ - 223518.7927909725, - 6757623.548840558, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 494, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223510.75990368403, - 6757644.9084504265, - 0.05 - ], - [ - 223507.9119445514, - 6757633.200370159, - 0.05 - ], - [ - 223508.476280079, - 6757631.438179404, - 0.05 - ], - [ - 223510.26558928814, - 6757629.577024713, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 495, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223554.3981909856, - 6757598.323286723, - 0.05 - ], - [ - 223582.4581251826, - 6757578.4336721115, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 496, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223528.6860051829, - 6757637.407570033, - 0.05 - ], - [ - 223520.0892206637, - 6757643.31874847, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 497, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223556.66041320981, - 6757618.137787276, - 0.05 - ], - [ - 223528.6860051829, - 6757637.407570033, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 498, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223564.63785061135, - 6757612.655687706, - 0.05 - ], - [ - 223556.66041320981, - 6757618.137787276, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 499, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223592.9118920575, - 6757593.183545284, - 0.05 - ], - [ - 223564.63785061135, - 6757612.655687706, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 500, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223600.7668886151, - 6757587.767124033, - 0.05 - ], - [ - 223592.9118920575, - 6757593.183545284, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 501, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223620.3318273782, - 6757574.304435799, - 0.05 - ], - [ - 223600.7668886151, - 6757587.767124033, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 502, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223520.0892206637, - 6757643.31874847, - 0.05 - ], - [ - 223516.8705465148, - 6757645.54060373, - 0.05 - ], - [ - 223510.75990368403, - 6757644.9084504265, - 0.05 - ], - [ - 223502.1327583178, - 6757644.022594872, - 0.05 - ], - [ - 223497.54115103, - 6757609.615706679, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 503, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223716.87498731073, - 6757750.851901932, - 0.05 - ], - [ - 223708.24701633654, - 6757755.817857062, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 504, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223722.39406151744, - 6757747.418889239, - 0.05 - ], - [ - 223716.87498731073, - 6757750.851901932, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 505, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223708.24701633654, - 6757755.817857062, - 0.05 - ], - [ - 223695.8405224799, - 6757762.961624194, - 0.05 - ], - [ - 223691.1520255811, - 6757756.106038896, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 506, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223879.5553347402, - 6758096.339943541, - 0.05 - ], - [ - 223880.96072743018, - 6758103.505291994, - 0.05 - ], - [ - 223892.84384692, - 6758125.084621987, - 0.05 - ], - [ - 223883.4718848103, - 6758157.60939536, - 0.05 - ], - [ - 223870.72794518725, - 6758160.098481151, - 0.05 - ], - [ - 223865.45852903457, - 6758161.125831776, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 507, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223879.5553347402, - 6758096.339943541, - 0.05 - ], - [ - 223872.02474658715, - 6758083.047948442, - 0.05 - ], - [ - 223865.42530000705, - 6758071.419674653, - 0.05 - ], - [ - 223865.40932984947, - 6758067.497318035, - 0.05 - ], - [ - 223867.47578272584, - 6758064.320869961, - 0.05 - ], - [ - 223949.29920766718, - 6758017.609658455, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 508, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223698.51521025406, - 6757990.8189242035, - 0.05 - ], - [ - 223705.06836333004, - 6757987.068276815, - 0.05 - ], - [ - 223695.69159746676, - 6757968.329907533, - 0.05 - ], - [ - 223704.24637039, - 6757963.113439245, - 0.05 - ], - [ - 223695.55579529447, - 6757948.031516784, - 0.05 - ], - [ - 223687.99235441012, - 6757934.898427681, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 509, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223996.05218493292, - 6757826.125673408, - 0.05 - ], - [ - 224003.3750577878, - 6757830.138237653, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 510, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223977.60052129364, - 6757882.345166642, - 0.05 - ], - [ - 224003.3750577878, - 6757830.138237653, - 0.05 - ], - [ - 224012.69220529933, - 6757811.261772645, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 511, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223976.06672791712, - 6757815.187540999, - 0.05 - ], - [ - 223996.05218493292, - 6757826.125673408, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 512, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223916.26024203724, - 6757827.728471567, - 0.05 - ], - [ - 223931.37379522418, - 6757822.361917036, - 0.05 - ], - [ - 223939.70442826638, - 6757819.393256701, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 513, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223924.90217850741, - 6757850.3163297735, - 0.05 - ], - [ - 223916.26024203724, - 6757827.728471567, - 0.05 - ], - [ - 223912.25785814156, - 6757817.261551679, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 514, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223851.84023224795, - 6757834.244279719, - 0.05 - ], - [ - 223848.6950025402, - 6757829.181226255, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 515, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223857.12836481293, - 6757842.75701181, - 0.05 - ], - [ - 223851.84023224795, - 6757834.244279719, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 516, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223814.59083907487, - 6757657.90115229, - 0.05 - ], - [ - 223809.22932279878, - 6757661.6111599775, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 517, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223801.54916849948, - 6757638.74514562, - 0.05 - ], - [ - 223814.59083907487, - 6757657.90115229, - 0.05 - ], - [ - 223836.43421433627, - 6757689.97899405, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 518, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223513.6288142478, - 6757892.491286806, - 0.05 - ], - [ - 223528.7034938556, - 6757896.791044069, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 519, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223467.59803072544, - 6757956.603571464, - 0.05 - ], - [ - 223462.95629031572, - 6757972.751312095, - 0.05 - ], - [ - 223488.30756138393, - 6757979.843302666, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 520, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223446.55680747994, - 6758015.598183304, - 0.05 - ], - [ - 223442.6663481515, - 6758028.575294616, - 0.05 - ], - [ - 223460.32904236496, - 6758033.646649789, - 0.05 - ], - [ - 223471.41078069736, - 6758036.819800647, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 521, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223455.06390328868, - 6757986.163237795, - 0.05 - ], - [ - 223450.5836230729, - 6758001.796343995, - 0.05 - ], - [ - 223469.57157138555, - 6758007.451746147, - 0.05 - ], - [ - 223479.2618029262, - 6758010.336065629, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 522, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223468.95374841895, - 6758058.698815191, - 0.05 - ], - [ - 223467.1684932568, - 6758051.118348794, - 0.05 - ], - [ - 223471.41078069736, - 6758036.819800647, - 0.05 - ], - [ - 223479.2618029262, - 6758010.336065629, - 0.05 - ], - [ - 223488.30756138393, - 6757979.843302666, - 0.05 - ], - [ - 223497.03990096366, - 6757950.401391774, - 0.05 - ], - [ - 223510.52932906145, - 6757954.249543019, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 523, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223516.4481719096, - 6757576.286578864, - 0.05 - ], - [ - 223590.74910171644, - 6757561.567772877, - 0.05 - ], - [ - 223599.69289236155, - 6757556.041114829, - 0.05 - ], - [ - 223606.3242511024, - 6757551.949682422, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 524, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223531.99025113002, - 6758314.875048352, - 0.05 - ], - [ - 223554.57652641775, - 6758319.024925705, - 0.05 - ], - [ - 223565.91535542381, - 6758321.107351169, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 525, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223491.44105081342, - 6758242.943935513, - 0.05 - ], - [ - 223491.90041050984, - 6758246.117094207, - 0.05 - ], - [ - 223487.72785494116, - 6758265.649010679, - 0.05 - ], - [ - 223486.66246179224, - 6758271.163582813, - 0.05 - ], - [ - 223486.95297018345, - 6758277.270844404, - 0.05 - ], - [ - 223488.5102027866, - 6758282.774147549, - 0.05 - ], - [ - 223500.01664447534, - 6758294.930755678, - 0.05 - ], - [ - 223568.58817818027, - 6758305.620327218, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 526, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223508.88500572904, - 6758050.857682557, - 0.05 - ], - [ - 223541.41198417847, - 6757942.803673015, - 0.05 - ], - [ - 223543.21373526618, - 6757936.817211822, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 527, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222966.9205206816, - 6757952.849171328, - 0.05 - ], - [ - 222979.02684520016, - 6757950.465459552, - 0.05 - ], - [ - 223031.36358757608, - 6757914.464057433, - 0.05 - ], - [ - 223047.77924331056, - 6757912.935842617, - 0.05 - ], - [ - 223057.28377939464, - 6757924.9526243005, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 528, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223015.6432518944, - 6758123.133605605, - 0.05 - ], - [ - 223007.62330943957, - 6758112.089211073, - 0.05 - ], - [ - 223042.15460274566, - 6758087.2145074485, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 529, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223677.37902653596, - 6758802.684443143, - 0.05 - ], - [ - 223679.05357172113, - 6758804.990328663, - 0.05 - ], - [ - 223679.77277344163, - 6758807.752374476, - 0.05 - ], - [ - 223679.4446860752, - 6758810.576722595, - 0.05 - ], - [ - 223678.10789581854, - 6758813.10355888, - 0.05 - ], - [ - 223675.9428772797, - 6758814.961608338, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 530, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223566.52725882875, - 6757817.246411543, - 0.05 - ], - [ - 223570.2387333081, - 6757821.40529297, - 0.05 - ], - [ - 223575.97688608186, - 6757826.269907027, - 0.05 - ], - [ - 223588.2020588186, - 6757838.569289994, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 531, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223301.6187954211, - 6757567.205757065, - 0.05 - ], - [ - 223308.70899991976, - 6757569.909859174, - 0.05 - ], - [ - 223316.39177386643, - 6757574.271533019, - 0.05 - ], - [ - 223321.9505377434, - 6757578.771437482, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 532, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224115.17435245693, - 6757275.76640564, - 0.05 - ], - [ - 224106.97930704785, - 6757277.910099557, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 533, - "lwd63": 81.89725490106659, - "lwd125": 71.88783370853906, - "lwd250": 70.45347125200192, - "lwd500": 70.77472168108605, - "lwd1000": 72.60927071449348, - "lwd2000": 69.89498221182919, - "lwd4000": 65.13201503418793, - "lwd8000": 57.66372583065063, - "lwe63": 76.39340352366376, - "lwe125": 66.3839849143855, - "lwe250": 64.94962358085901, - "lwe500": 65.27087372526692, - "lwe1000": 67.10542148114162, - "lwe2000": 64.39113508859629, - "lwe4000": 59.62817696611757, - "lwe8000": 52.15995006422352, - "lwn63": 73.38310396559334, - "lwn125": 63.37368895209104, - "lwn250": 61.939329181747304, - "lwn500": 62.26057892989822, - "lwn1000": 64.09512490750173, - "lwn2000": 61.38084145215147, - "lwn4000": 56.617895934032056, - "lwn8000": 49.14975575138363 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223517.12445619196, - 6758122.133263785, - 0.05 - ], - [ - 223508.90633075644, - 6758128.348341589, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 534, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223154.84589878272, - 6758566.868549614, - 0.05 - ], - [ - 223151.73777514265, - 6758569.984621737, - 0.05 - ], - [ - 223148.67979110556, - 6758578.926449822, - 0.05 - ], - [ - 223142.50029641652, - 6758637.11116826, - 0.05 - ], - [ - 223140.7093025137, - 6758655.770943321, - 0.05 - ], - [ - 223134.18304942216, - 6758723.792999362, - 0.05 - ], - [ - 223132.21700811153, - 6758744.283887228, - 0.05 - ], - [ - 223128.74863803084, - 6758778.729545745, - 0.05 - ], - [ - 223127.6040642546, - 6758794.505764728, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 535, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223755.1335154802, - 6758588.840048891, - 0.05 - ], - [ - 223751.30165058578, - 6758599.192755541, - 0.05 - ], - [ - 223732.50885718386, - 6758650.558904779, - 0.05 - ], - [ - 223727.90645704512, - 6758662.445244192, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 536, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224187.76577497623, - 6757605.13388599, - 0.05 - ], - [ - 224192.08171033167, - 6757591.721842442, - 0.05 - ], - [ - 224192.07352900505, - 6757584.165079898, - 0.05 - ], - [ - 224189.66577632527, - 6757576.032778874, - 0.05 - ], - [ - 224188.35675358376, - 6757565.025180998, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 537, - "lwd63": 76.32321275564011, - "lwd125": 69.2737354033623, - "lwd250": 68.01621692030905, - "lwd500": 69.66168841280886, - "lwd1000": 73.74408262591645, - "lwd2000": 70.16553600512536, - "lwd4000": 63.56269555054705, - "lwd8000": 55.55614220090115, - "lwe63": 70.81274018319574, - "lwe125": 63.76326704518494, - "lwe250": 62.5057503252124, - "lwe500": 64.15121960599792, - "lwe1000": 68.23361089334108, - "lwe2000": 64.65506667239288, - "lwe4000": 58.05224149729196, - "lwe8000": 50.04579216021435, - "lwn63": 67.80244166724485, - "lwn125": 60.75297439181305, - "lwn250": 59.49546012450498, - "lwn500": 61.14092632852059, - "lwn1000": 65.22331354575536, - "lwn2000": 61.6447726632926, - "lwn4000": 55.04196874377687, - "lwn8000": 47.03566409590195 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224030.798176397, - 6757785.3112886725, - 0.05 - ], - [ - 224039.10565570975, - 6757788.575637356, - 0.05 - ], - [ - 224041.33260827855, - 6757789.900721589, - 0.05 - ], - [ - 224043.50242343632, - 6757791.542524544, - 0.05 - ], - [ - 224045.01756960247, - 6757793.549267014, - 0.05 - ], - [ - 224045.5435330086, - 6757795.502076778, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 538, - "lwd63": 79.34921937900936, - "lwd125": 72.29974119959442, - "lwd250": 71.04222237049981, - "lwd500": 72.68769429709465, - "lwd1000": 76.7700890844441, - "lwd2000": 73.1915419926342, - "lwd4000": 66.58869853913498, - "lwd8000": 58.58212477448526, - "lwe63": 73.84536823011977, - "lwe125": 66.79589214578274, - "lwe250": 65.53837419318543, - "lwe500": 67.18384502024949, - "lwe1000": 71.2662383530863, - "lwe2000": 67.68769245433265, - "lwe4000": 61.08485659687639, - "lwe8000": 53.07833454169498, - "lwn63": 70.83506899013052, - "lwn125": 63.78559582205517, - "lwn250": 62.528079089504836, - "lwn500": 64.1735483860687, - "lwn1000": 68.25593969428424, - "lwn2000": 64.67739545621556, - "lwn4000": 58.07457017211124, - "lwn8000": 50.06812009302061 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 224040.70202359313, - 6757696.754271708, - 0.05 - ], - [ - 224022.9004656456, - 6757662.855926628, - 0.05 - ], - [ - 224020.22678229434, - 6757657.76588376, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 539, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223834.00588222675, - 6757224.065273133, - 0.05 - ], - [ - 223777.75236819062, - 6757145.285391136, - 0.05 - ], - [ - 223773.0317070071, - 6757139.524706666, - 0.05 - ], - [ - 223769.42680301197, - 6757133.428714673, - 0.05 - ], - [ - 223720.3372028537, - 6757062.28599722, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 540, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223834.00588222675, - 6757224.065273133, - 0.05 - ], - [ - 223890.11320811423, - 6757187.322254927, - 0.05 - ], - [ - 223895.40443781036, - 6757183.573455169, - 0.05 - ], - [ - 223915.35284722847, - 6757169.434470559, - 0.05 - ], - [ - 223974.1331707412, - 6757128.162842854, - 0.05 - ], - [ - 223985.59304903, - 6757124.640839328, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 541, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223457.56145479577, - 6758522.5903863525, - 0.05 - ], - [ - 223463.79065348755, - 6758523.770178057, - 0.05 - ], - [ - 223524.66775327886, - 6758535.270333475, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 542, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 222980.81073312543, - 6758143.908521716, - 0.05 - ], - [ - 222995.48029295343, - 6758178.982708396, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 543, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223553.86122842768, - 6758607.996468405, - 0.05 - ], - [ - 223522.80282628932, - 6758600.941940771, - 0.05 - ], - [ - 223482.16456517408, - 6758591.707772524, - 0.05 - ], - [ - 223464.01596996433, - 6758586.463942803, - 0.05 - ], - [ - 223458.1947734169, - 6758586.332425885, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 544, - "lwd63": 72.86321898462634, - "lwd125": 62.85380488565608, - "lwd250": 61.41944551288429, - "lwd500": 61.74069516025324, - "lwd1000": 63.575240685580226, - "lwd2000": 60.86095797726122, - "lwd4000": 56.098015664863105, - "lwd8000": 48.62989753757982, - "lwe63": 67.38472102740067, - "lwe125": 57.37532744171243, - "lwe250": 55.94097698659047, - "lwe500": 56.262224373393515, - "lwe1000": 58.09675975402483, - "lwe2000": 55.38249380182356, - "lwe4000": 50.61962339387704, - "lwe8000": 43.151999935570124, - "lwn63": 64.46216335922846, - "lwn125": 54.452797247918305, - "lwn250": 53.0184587365185, - "lwn500": 53.33970309567153, - "lwn1000": 55.174224889133974, - "lwn2000": 52.459981378985496, - "lwn4000": 47.697207272878835, - "lwn8000": 40.230246225083654 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223275.59774431208, - 6757566.176673736, - 0.05 - ], - [ - 223219.0097277643, - 6757567.128111406, - 0.05 - ], - [ - 223188.96104832, - 6757567.149531239, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 545, - "lwd63": 86.95496394010574, - "lwd125": 76.94554205101154, - "lwd250": 75.51117929165724, - "lwd500": 75.83242979750362, - "lwd1000": 77.66697917539472, - "lwd2000": 74.95269010374184, - "lwd4000": 70.18972048439339, - "lwd8000": 62.7214144811625, - "lwe63": 81.52921545787827, - "lwe125": 71.51979435489754, - "lwe250": 70.0854319372889, - "lwe500": 70.40668235650487, - "lwe1000": 72.2412313456274, - "lwe2000": 69.52694291610916, - "lwe4000": 64.76397605236016, - "lwe8000": 57.29568900849256, - "lwn63": 78.07546905618496, - "lwn125": 68.06604929223269, - "lwn250": 66.63168745673727, - "lwn500": 66.95293772839116, - "lwn1000": 68.78748605530389, - "lwn2000": 66.073198719567, - "lwn4000": 61.310236549569154, - "lwn8000": 53.8419817999202 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223505.47440407786, - 6758136.9522710955, - 0.05 - ], - [ - 223452.87614130403, - 6758081.243698745, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 546, - "lwd63": 75.86094845611883, - "lwd125": 65.85153031585503, - "lwd250": 64.41716918622214, - "lwd500": 64.73841927894429, - "lwd1000": 66.57296680287038, - "lwd2000": 63.85868079343783, - "lwd4000": 59.09572431501012, - "lwd8000": 51.62750872446309, - "lwe63": 70.3950193978977, - "lwe125": 60.38561150255343, - "lwe250": 58.95125482666334, - "lwe500": 59.272503790390054, - "lwe1000": 61.107046247752706, - "lwe2000": 58.39276860683054, - "lwe4000": 53.6298480399818, - "lwe8000": 46.16187951870871, - "lwn63": 67.38472102740067, - "lwn125": 57.37532744171243, - "lwn250": 55.94097698659047, - "lwn500": 56.262224373393515, - "lwn1000": 58.09675975402483, - "lwn2000": 55.38249380182356, - "lwn4000": 50.61962339387704, - "lwn8000": 43.151999935570124 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223531.024064507, - 6758527.790004899, - 0.05 - ], - [ - 223531.44007638353, - 6758531.078139163, - 0.05 - ], - [ - 223532.50382697338, - 6758533.544808631, - 0.05 - ], - [ - 223533.9912347069, - 6758535.48678874, - 0.05 - ], - [ - 223535.41239252116, - 6758536.887928666, - 0.05 - ], - [ - 223537.04747816816, - 6758537.959673823, - 0.05 - ], - [ - 223539.42067485844, - 6758539.328480481, - 0.05 - ], - [ - 223542.07473808498, - 6758540.172989162, - 0.05 - ], - [ - 223548.1064532146, - 6758541.2350609545, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 547, - "lwd63": 75.90171332041136, - "lwd125": 66.50354895698379, - "lwd250": 65.07810131032979, - "lwd500": 67.03547618298532, - "lwd1000": 68.69573012731246, - "lwd2000": 63.98750464460184, - "lwd4000": 59.83951230326983, - "lwd8000": 52.46266685676584, - "lwe63": 70.43578425158094, - "lwe125": 61.037628557169114, - "lwe250": 59.612184715440435, - "lwe500": 61.569554654148824, - "lwe1000": 63.22980584560604, - "lwe2000": 58.52159193169619, - "lwe4000": 54.37362754144347, - "lwe8000": 46.99698499689735, - "lwn63": 67.42548586626533, - "lwn125": 58.02734228036127, - "lwn250": 56.601903753170085, - "lwn500": 58.55926680037521, - "lwn1000": 60.21951414674617, - "lwn2000": 55.51131639158329, - "lwn4000": 51.363391041634046, - "lwn8000": 43.98703187968516 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223531.024064507, - 6758527.790004899, - 0.05 - ], - [ - 223530.42601911776, - 6758530.15686022, - 0.05 - ], - [ - 223529.67241620336, - 6758531.900916633, - 0.05 - ], - [ - 223529.0240577942, - 6758532.900780712, - 0.05 - ], - [ - 223527.59360297024, - 6758534.175625948, - 0.05 - ], - [ - 223526.5234812601, - 6758534.886310754, - 0.05 - ], - [ - 223524.66775327886, - 6758535.270333475, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 548, - "lwd63": 75.90171332041136, - "lwd125": 66.50354895698379, - "lwd250": 65.07810131032979, - "lwd500": 67.03547618298532, - "lwd1000": 68.69573012731246, - "lwd2000": 63.98750464460184, - "lwd4000": 59.83951230326983, - "lwd8000": 52.46266685676584, - "lwe63": 70.43578425158094, - "lwe125": 61.037628557169114, - "lwe250": 59.612184715440435, - "lwe500": 61.569554654148824, - "lwe1000": 63.22980584560604, - "lwe2000": 58.52159193169619, - "lwe4000": 54.37362754144347, - "lwe8000": 46.99698499689735, - "lwn63": 67.42548586626533, - "lwn125": 58.02734228036127, - "lwn250": 56.601903753170085, - "lwn500": 58.55926680037521, - "lwn1000": 60.21951414674617, - "lwn2000": 55.51131639158329, - "lwn4000": 51.363391041634046, - "lwn8000": 43.98703187968516 - } - }, - { - "type": "Feature", - "geometry": { - "type": "MultiLineString", - "coordinates": [ - [ - [ - 223524.66775327886, - 6758535.270333475, - 0.05 - ], - [ - 223527.3719988297, - 6758536.177662022, - 0.05 - ], - [ - 223529.66163819167, - 6758536.884408118, - 0.05 - ], - [ - 223532.26225695666, - 6758537.532588347, - 0.05 - ], - [ - 223534.86287507752, - 6758538.180769723, - 0.05 - ], - [ - 223539.42067485844, - 6758539.328480481, - 0.05 - ] - ] - ] - }, - "properties": { - "pk": 549, - "lwd63": 75.90171332041136, - "lwd125": 66.50354895698379, - "lwd250": 65.07810131032979, - "lwd500": 67.03547618298532, - "lwd1000": 68.69573012731246, - "lwd2000": 63.98750464460184, - "lwd4000": 59.83951230326983, - "lwd8000": 52.46266685676584, - "lwe63": 70.43578425158094, - "lwe125": 61.037628557169114, - "lwe250": 59.612184715440435, - "lwe500": 61.569554654148824, - "lwe1000": 63.22980584560604, - "lwe2000": 58.52159193169619, - "lwe4000": 54.37362754144347, - "lwe8000": 46.99698499689735, - "lwn63": 67.42548586626533, - "lwn125": 58.02734228036127, - "lwn250": 56.601903753170085, - "lwn500": 58.55926680037521, - "lwn1000": 60.21951414674617, - "lwn2000": 55.51131639158329, - "lwn4000": 51.363391041634046, - "lwn8000": 43.98703187968516 - } - } - ] -} \ No newline at end of file diff --git a/noisemodelling-tutorial-01/src/test/java/org/noise_planet/nmtutorial01/TutorialTest.java b/noisemodelling-tutorial-01/src/test/java/org/noise_planet/nmtutorial01/TutorialTest.java deleted file mode 100644 index bcc2be165..000000000 --- a/noisemodelling-tutorial-01/src/test/java/org/noise_planet/nmtutorial01/TutorialTest.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.noise_planet.nmtutorial01; - -import org.h2gis.functions.factory.H2GISDBFactory; -import org.h2gis.postgis_jts_osgi.DataSourceFactoryImpl; -import org.h2gis.utilities.JDBCUtilities; -import org.h2gis.utilities.TableLocation; -import org.h2gis.utilities.dbtypes.DBTypes; -import org.h2gis.utilities.dbtypes.DBUtils; -import org.junit.jupiter.api.Test; -import org.noise_planet.noisemodelling.jdbc.NoiseMapByReceiverMaker; -import org.noise_planet.noisemodelling.jdbc.NoiseMapDatabaseParameters; -import org.noise_planet.noisemodelling.jdbc.input.DefaultTableLoader; -import org.postgresql.util.PSQLException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.ConnectException; -import java.sql.Connection; -import java.util.*; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class TutorialTest { - Logger LOGGER = LoggerFactory.getLogger(TutorialTest.class); - - @Test - public void testPostgisNoiseModelling1() throws Exception { - DataSourceFactoryImpl dataSourceFactory = new DataSourceFactoryImpl(); - Properties p = new Properties(); - p.setProperty("serverName", "localhost"); - p.setProperty("portNumber", "5432"); - p.setProperty("databaseName", "noisemodelling_db"); - p.setProperty("user", "noisemodelling"); - p.setProperty("password", "noisemodelling"); - try(Connection connection = JDBCUtilities.wrapConnection(dataSourceFactory.createDataSource(p).getConnection())) { - connection.createStatement().execute("DROP TABLE IF EXISTS receivers_level"); - connection.createStatement().execute("DROP TABLE IF EXISTS contouring_noise_map"); - NoiseMapByReceiverMaker map = Main.mainWithConnection(connection, "target/postgis"); - String receiverTable = TableLocation.capsIdentifier( - NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME, DBTypes.POSTGIS); - assertTrue(JDBCUtilities.tableExists(connection.unwrap(Connection.class), receiverTable)); - assertTrue(JDBCUtilities.hasField(connection.unwrap(Connection.class), receiverTable, "period")); - assertTrue(JDBCUtilities.tableExists(connection.unwrap(Connection.class), "contouring_noise_map")); - assertTrue(JDBCUtilities.hasField(connection.unwrap(Connection.class), "contouring_noise_map", "period")); - - - int receiversRowCount = JDBCUtilities.getRowCount(connection, "RECEIVERS"); - - int resultRowCount = JDBCUtilities.getRowCount(connection, - receiverTable); - - // D E N and DEN, should be 4 more rows than receivers - assertEquals(receiversRowCount * 4, resultRowCount); - - assertEquals(3, ((DefaultTableLoader)map.getTableLoader()).getCnossosParametersPerPeriod().size()); - assertEquals(20, ((DefaultTableLoader)map.getTableLoader()).getCnossosParametersPerPeriod().get("D").temperature); - assertEquals(16, ((DefaultTableLoader)map.getTableLoader()).getCnossosParametersPerPeriod().get("E").temperature); - assertEquals(10, ((DefaultTableLoader)map.getTableLoader()).getCnossosParametersPerPeriod().get("N").temperature); - - } catch (PSQLException psqlException) { - if(!(psqlException.getCause() instanceof ConnectException)) { - throw psqlException; - } else { - // Ignore connection exception, we may not be inside the unit test of github workflow - LOGGER.warn(psqlException.getLocalizedMessage(), psqlException); - } - } - } - - @Test - public void testH2gisNoiseModelling() throws Exception { - try(Connection connection = JDBCUtilities.wrapConnection( - H2GISDBFactory.createSpatialDataBase(TutorialTest.class.getSimpleName(), - true, ""));) { - NoiseMapByReceiverMaker map = Main.mainWithConnection(connection, "target/h2gis"); - - String receiverTable = TableLocation.capsIdentifier( - NoiseMapDatabaseParameters.DEFAULT_RECEIVERS_LEVEL_TABLE_NAME, DBTypes.H2GIS); - assertTrue(JDBCUtilities.tableExists(connection.unwrap(Connection.class), receiverTable)); - assertTrue(JDBCUtilities.hasField(connection.unwrap(Connection.class), receiverTable, "period")); - assertTrue(JDBCUtilities.tableExists(connection.unwrap(Connection.class), "contouring_noise_map")); - assertTrue(JDBCUtilities.hasField(connection.unwrap(Connection.class), "contouring_noise_map", "period")); - - - int receiversRowCount = JDBCUtilities.getRowCount(connection, "RECEIVERS"); - - int resultRowCount = JDBCUtilities.getRowCount(connection, - receiverTable); - - // D E N and DEN, should be 4 more rows than receivers - assertEquals(receiversRowCount * 4, resultRowCount); - - assertEquals(3, ((DefaultTableLoader)map.getTableLoader()).getCnossosParametersPerPeriod().size()); - assertEquals(20, ((DefaultTableLoader)map.getTableLoader()).getCnossosParametersPerPeriod().get("D").temperature); - assertEquals(16, ((DefaultTableLoader)map.getTableLoader()).getCnossosParametersPerPeriod().get("E").temperature); - assertEquals(10, ((DefaultTableLoader)map.getTableLoader()).getCnossosParametersPerPeriod().get("N").temperature); - - } catch (PSQLException psqlException) { - if(!(psqlException.getCause() instanceof ConnectException)) { - throw psqlException; - } else { - // Ignore connection exception, we may not be inside the unit test of github workflow - LOGGER.warn(psqlException.getLocalizedMessage(), psqlException); - } - } - } -} diff --git a/pom.xml b/pom.xml index 4f006603f..ab47aa204 100644 --- a/pom.xml +++ b/pom.xml @@ -5,8 +5,11 @@ noisemodelling-parent noisemodelling-parent org.noise-planet - 5.0.2-SNAPSHOT + 6.0.1-SNAPSHOT NoiseModelling is an extension of H2GIS + + 5.0.3 + UMRAE, CEREMA, Univ Gustave Eiffel https://umrae.fr @@ -23,7 +26,7 @@ noisemodelling-pathfinder noisemodelling-propagation noisemodelling-jdbc - noisemodelling-tutorial-01 + noisemodelling-scripts scm:git:https://github.com/Universite-Gustave-Eiffel/NoiseModelling.git @@ -31,6 +34,27 @@ git@github.com:Universite-Gustave-Eiffel/NoiseModelling.git HEAD + + + use-snapshots + + true + + + + Central Portal Snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + + + + + @@ -188,14 +212,23 @@ https://repo1.maven.org/maven2 - Central Portal Snapshots - central-portal-snapshots - https://central.sonatype.com/repository/maven-snapshots/ + osgeo + https://repo.osgeo.org/repository/release/ - false + true + false + + + + matsim + https://repo.matsim.org/repository/matsim + true + + + false @@ -210,87 +243,268 @@ + + org.tinfour + TinfourCore + 2.1.9 + + + org.junit.jupiter + junit-jupiter + 5.10.2 + test + + + com.auth0 + java-jwt + [4.5.0, 5) + + + org.codehaus.mojo + appassembler-maven-plugin + 2.1.0 + compile + com.h2database h2 - 2.3.232 + [2.4.240, 3) org.orbisgis cts - 1.7.1 + [1.7.2, 2) org.orbisgis h2gis - 2.2.3 + [2.2.5, 3) org.orbisgis h2gis-api - 2.2.3 + [2.2.5, 3) org.orbisgis postgis-jts-osgi - 2.2.3 + [2.2.5, 3) + + + org.orbisgis + postgis-jts + [2.2.5, 3) org.orbisgis h2gis-utilities - 2.2.3 + [2.2.5, 3) com.fasterxml.jackson.core jackson-core - 2.18.2 + 2.21.1 com.fasterxml.jackson.core jackson-databind - 2.18.2 + 2.21.1 com.fasterxml.jackson.core jackson-annotations - 2.18.2 + 2.21 org.locationtech.jts jts-core - 1.20.0 + [1.20.0, 2) org.slf4j slf4j-api - 2.0.16 + 2.0.13 + + + org.slf4j + slf4j-reload4j + 2.0.13 + + + ch.qos.reload4j + reload4j + 1.2.25 org.postgresql postgresql - 42.7.4 + [42.7.4, 43) org.apache.commons commons-math3 - 3.6.1 + [3.6.1, 4) org.apache.maven.plugins maven-gpg-plugin 3.2.7 - - org.tinfour - TinfourCore - 2.1.7 - org.apache.commons commons-collections4 4.5.0-M2 - + + org.apache.groovy + groovy-templates + ${groovy-version} + + + org.apache.groovy + groovy + ${groovy-version} + + + io.javalin + javalin-bundle + [6.7.0, 7.-alpha.alpha) + + + io.javalin + javalin-rendering + [6.7.0, 7.-alpha.alpha) + + + org.thymeleaf + thymeleaf + [3.1.3, 4) + + + org.geotools + gt-wps + 30.2 + + + org.geotools + gt-xml + 30.2 + + + org.geotools.xsd + gt-xsd-core + 30.2 + + + org.geotools.xsd + gt-xsd-wps + 30.2 + + + org.geotools.ogc + net.opengis.wps + 30.2 + + + org.geotools + gt-jdbc + 30.2 + + + org.geotools + gt-referencing + 30.2 + + + org.geotools + gt-metadata + 30.2 + + + org.geotools + gt-epsg-hsql + 30.2 + + + org.apache.groovy + groovy-json + ${groovy-version} + + + org.apache.groovy + groovy-sql + ${groovy-version} + + + com.opencsv + opencsv + 5.7.1 + + + commons-cli + commons-cli + 1.9.0 + + + org.osgi + org.osgi.service.jdbc + 1.0.0 + + + com.zaxxer + HikariCP + [6.3.0, 7) + + + com.atlassian + onetime + [2.1.1, 3) + + + com.google.zxing + core + [3.5.4, 4) + + + com.google.zxing + javase + [3.5.4, 4) + + + org.openstreetmap.osmosis + osmosis-core + [0.48, 0.49) + + + xerces + xercesImpl + + + xml-apis + xml-apis + + + + + org.openstreetmap.osmosis + osmosis-pbf + [0.48, 0.49) + + + org.openstreetmap.osmosis + osmosis-xml + [0.48, 0.49) + + + org.jfree + jfreechart + 1.5.6 + + + org.matsim + matsim + 14.0 + org.junit.jupiter @@ -310,6 +524,8 @@ 2.0.16 test + + diff --git a/preparation.sh b/preparation.sh deleted file mode 100644 index 52c047f36..000000000 --- a/preparation.sh +++ /dev/null @@ -1,10 +0,0 @@ -mvn clean install -Dmaven.test.skip=true -o -mkdir /tmp/nm -rm /tmp/nm/* -for i in $(find . -type d -name 'target'); do # Not recommended, will break on whitespace - for j in $(find "$i" -type f -name '*.jar'); do # Not recommended, will break on whitespace - cp "$j" /tmp/nm - done -done -cd /tmp/nm -rename 's/3.4.3/3.4.4/' *3.4.3.jar diff --git a/wps_scripts/.gitignore b/wps_scripts/.gitignore deleted file mode 100644 index 33e48f09a..000000000 --- a/wps_scripts/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -out/ -.gradle -build/ -.idea -dependencies/ -lib/ \ No newline at end of file diff --git a/wps_scripts/README.md b/wps_scripts/README.md deleted file mode 100644 index 7ceed696b..000000000 --- a/wps_scripts/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Build standalone command line program - -In shell write the following command (need Java 11) - -```shell -./gradlew build -``` - -The program will be available in the folder `build/distributions/scriptrunner.zip` - diff --git a/wps_scripts/build.gradle b/wps_scripts/build.gradle deleted file mode 100644 index 6f13c1bec..000000000 --- a/wps_scripts/build.gradle +++ /dev/null @@ -1,246 +0,0 @@ -plugins { - id 'java' - id 'groovy' - id 'application' - id 'distribution' - id 'java-library' - id 'maven-publish' -} - -sourceCompatibility = 11 - -def nm_version='5.0.1' - -distributions { - main { - distributionBaseName = 'NoiseModelling_without_gui' - archivesBaseName = "NoiseModelling_without_gui" - contents { - from '../LICENSE' - from '../README.md' - from 'get_started_tutorial.sh' - from 'src/main/groovy/org/noise_planet/' - from 'src/main/groovy/get_started_tutorial.groovy' - from('src/test/') { include 'resources/**' } - } - } -} - -startScripts { - doLast { - windowsScript.text = windowsScript.text.replaceAll('set CLASSPATH=.*', 'set CLASSPATH=.;%APP_HOME%/lib/*') - } -} - - -compileJava { - sourceCompatibility = '11' - targetCompatibility = '11' -} -compileJava.options.encoding = "UTF-8" -compileTestJava.options.encoding = "UTF-8" - -java { - withJavadocJar() - withSourcesJar() -} - -javadoc { - if(JavaVersion.current().isJava9Compatible()) { - options.addBooleanOption('html5', true) - } -} - -group = "org.noise-planet" -archivesBaseName = "noisemodelling-wps" -version = nm_version - - -publishing { - publications { - mavenJava(MavenPublication) { - artifactId = archivesBaseName - from components.java - versionMapping { - usage('java-api') { - fromResolutionOf('runtimeClasspath') - } - usage('java-runtime') { - fromResolutionResult() - } - } - - pom { - name = archivesBaseName - description = 'Groovy scripts for NoiseModelling' - url = 'https://github.com/Universite-Gustave-Eiffel/NoiseModelling' - inceptionYear = '2025' - - licenses { - license { - name = 'GNU General Public License (GPLV3+)' - url = 'http://www.gnu.org/licenses/gpl-3.0.html' - } - } - developers { - developer { - name = 'Nicolas Fortin' - organization = 'Gustave Eiffel University UMRAE' - url = 'https://github.com/nicolas-f' - } - developer { - name = 'Pierre Aumond' - organization = 'Gustave Eiffel University UMRAE' - url = 'https://github.com/pierromond' - } - } - scm { - connection='scm:git:https://github.com/Universite-Gustave-Eiffel/NoiseModelling.git' - developerConnection='scm:git:https://github.com/Universite-Gustave-Eiffel/NoiseModelling.git' - url='git@github.com:Universite-Gustave-Eiffel/NoiseModelling.git' - tag='HEAD' - } - } - } - } - repositories { - maven { - name = "OSSRH" - url = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" - - def releasesRepoUrl = 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/' - def snapshotsRepoUrl = 'https://central.sonatype.com/repository/maven-snapshots/' - url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl - credentials { - username = System.getenv('OSSRH_USERNAME') ?: project.findProperty('ossrhUsername') - password = System.getenv('OSSRH_PASSWORD') ?: project.findProperty('ossrhPassword') - } - } - } -} - - -repositories { - mavenLocal() // To test noise modelling updated locally we have to put this first - maven { - name = 'Central Portal Snapshots' - url = 'https://central.sonatype.com/repository/maven-snapshots/' - } - mavenCentral() - maven { //for outdated geoserver wps plugin - url "libs/" - } - maven { - url "https://repo.osgeo.org/repository/release/" - } - maven { - url "https://download.osgeo.org/webdav/geotools/" - } - maven { - url "https://maven.geo-solutions.it/" - } - maven { - url "https://repo.matsim.org/repository/matsim/" - } -} - -test { - minHeapSize = "128m" // initial heap size - maxHeapSize = "1g" // maximum heap size - jvmArgs '-XX:MaxPermSize=1g' // mem argument for the test JVM - afterTest { desc, result -> - println "Executing test ${desc.name} [${desc.className}] with result: ${result.resultType}" - } -} -dependencies { - implementation group: 'commons-cli', name: 'commons-cli', version: '1.4' - implementation('org.geotools:gt-jdbc:21.1') { - exclude group: 'javax.media' - } - implementation('org.geoserver.script:gs-script-groovy:2.15.1') { - exclude group: 'org.geoscript' - exclude group: 'no.ecc.vectortile' - exclude group: 'javax.media' - exclude group: 'commons-beanutils' - exclude group: 'org.locationtech.jts' - exclude group: 'org.geoserver', module: 'gs-wms' - exclude group: 'org.geoserver', module: 'gs-wfs' - exclude group: 'org.geoserver', module: 'gs-ows' - exclude group: 'org.geoserver', module: 'gs-rest' - exclude group: 'org.geoserver', module: 'gs-restconfig' - exclude group: 'org.geoserver', module: 'gs-main' - exclude group: 'org.geoserver', module: 'gs-wcs2_0' - exclude group: 'org.geoserver', module: 'gs-wcs1_1' - exclude group: 'org.geoserver', module: 'gs-wcs1_0' - exclude group: 'org.geotools.xsd', module: 'gt-xsd-sld' - exclude group: 'org.geotools.xsd', module: 'gt-xsd-wps' - exclude group: 'org.geotools', module: 'gt-process-raster' - exclude group: 'org.geotools', module: 'gt-process-feature' - } - implementation 'org.postgresql:postgresql:42.7.4' - implementation group: 'org.codehaus.groovy', name: 'groovy-all', version: '[2.5, 2.6)' - implementation group: 'org.ejml', name: 'all', version: '0.29' - implementation group: 'org.eclipse.emf', name: 'org.eclipse.emf.ecore', version: '2.10.1' - implementation group: 'org.orbisgis', name: 'h2gis', version: '[2.2, 3)' - implementation('org.locationtech.jts:jts-core:1.20.0') - implementation('org.locationtech.jts:jts-io:1.20.0') - implementation group: 'org.noise-planet', name: 'noisemodelling-emission', version: '[5.0, 6)', changing: true - implementation group: 'org.noise-planet', name: 'noisemodelling-propagation', version: '[5.0, 6)', changing: true - implementation group: 'org.noise-planet', name: 'noisemodelling-pathfinder', version: '[5.0, 6)', changing: true - implementation group: 'org.noise-planet', name: 'noisemodelling-jdbc', version: '[5.0, 6.0)', changing: true - implementation group: 'org.osgi', name: 'org.osgi.service.jdbc', version: '1.0.0' - implementation group: 'org.openstreetmap.osmosis', name: 'osmosis-core', version: '[0.48, 0.49)' - implementation group: 'org.openstreetmap.osmosis', name: 'osmosis-pbf', version: '[0.48, 0.49)' - implementation group: 'org.openstreetmap.osmosis', name: 'osmosis-xml', version: '[0.48, 0.49)' - implementation(group: 'org.matsim', name: 'matsim', version: '14.0') { - exclude group: 'org.geotools' - } - - implementation 'com.opencsv:opencsv:5.7.1' - implementation group: 'org.slf4j', name: 'slf4j-log4j12', version: '[2, 3)' - testImplementation 'junit:junit:4.13.1' -} - -// Function to extract the first GPG key's fingerprint -def getFirstGpgKeyFingerprint() { - def stdout = new ByteArrayOutputStream() - exec { - def cmd = "gpg2" - if(project.hasProperty('signing.gnupg.executable')) { - cmd = project.signing.gnupg.executable - } - commandLine cmd, '--list-secret-keys', '--with-colons' - standardOutput = stdout - ignoreExitValue = false - } - def fprLine = stdout.toString().split('\n').find { it.startsWith('fpr:') } - if (!fprLine) throw new GradleException('No GPG key found.') - return fprLine.split(':')[9] -} - -if (project.hasProperty("ossrhUsername")) { - apply plugin: 'signing' - - signing { - // You'll need to tell gradle what you want your GPG key ID to be so that the gpg-agent can do the right thing. - // On the command line this means including the following gradle property: -Psigning.gnupg.keyName=${MY_GPG_PUBLIC_KEY_ID} -P - // And if the machine this is running on has the gpg command but not the gpg2 command, then you'll need this gradle prop as well: -Psigning.gnupg.useLegacyGpg=true - // Full details here: https://docs.gradle.org/current/userguide/signing_plugin.html#sec:using_gpg_agent - if ( ! project.hasProperty("signing.gnupg.keyName") ) { - // Set the keyName property using the first defined in gpg program - project.ext.'signing.gnupg.keyName' = getFirstGpgKeyFingerprint() - logger.warn("Using the first GPG keyId " + project.ext.'signing.gnupg.keyName') - } - useGpgCmd() - sign publishing.publications.mavenJava - } -} - -mainClassName = 'org.noise_planet.noisemodelling.runner.Main' - -jar { - manifest { - attributes('Class-Path': configurations.runtimeClasspath.collect { it.getName() }.join(' '), - 'Main-Class': 'org.noise_planet.noisemodelling.runner.Main') - } -} diff --git a/wps_scripts/get_started_tutorial.bat b/wps_scripts/get_started_tutorial.bat deleted file mode 100755 index 62dec3201..000000000 --- a/wps_scripts/get_started_tutorial.bat +++ /dev/null @@ -1,18 +0,0 @@ -@rem Run the get started tutorial -@rem https://noisemodelling.readthedocs.io/en/latest/Get_Started_Tutorial.html - -@rem Step 4: Upload files to database -@rem create (or load existing) database and load a shape file into the database -bin\wps_scripts.bat -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/ground_type.shp -bin\wps_scripts.bat -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/buildings.shp -bin\wps_scripts.bat -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/receivers.shp -bin\wps_scripts.bat -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/ROADS2.shp -bin\wps_scripts.bat -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/dem.geojson - - -@rem Step 5: Run Calculation -bin\wps_scripts.bat -w ./ -s noisemodelling/wps/NoiseModelling/Noise_level_from_traffic.groovy -tableBuilding BUILDINGS -tableRoads ROADS2 -tableReceivers RECEIVERS -tableDEM DEM -tableGroundAbs GROUND_TYPE - -@rem Step 6: Export (& see) the results -bin\wps_scripts.bat -w ./ -s noisemodelling/wps/Import_and_Export/Export_Table.groovy -exportPath RECEIVERS_LEVEL.shp -tableToExport RECEIVERS_LEVEL - diff --git a/wps_scripts/get_started_tutorial.sh b/wps_scripts/get_started_tutorial.sh deleted file mode 100755 index 2324dd7bb..000000000 --- a/wps_scripts/get_started_tutorial.sh +++ /dev/null @@ -1,19 +0,0 @@ -#! /bin/bash - -# Run the get started tutorial -# https://noisemodelling.readthedocs.io/en/latest/Get_Started_Tutorial.html - -# Step 4: Upload files to database -# create (or load existing) database and load a shape file into the database -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/ground_type.shp -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/buildings.shp -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/receivers.shp -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/ROADS2.shp -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Import_File.groovy -pathFile resources/org/noise_planet/noisemodelling/wps/dem.geojson - - -# Step 5: Run Calculation -./bin/wps_scripts -w ./ -s noisemodelling/wps/NoiseModelling/Noise_level_from_traffic.groovy -tableBuilding BUILDINGS -tableRoads ROADS2 -tableReceivers RECEIVERS -tableDEM DEM -tableGroundAbs GROUND_TYPE - -# Step 6: Export (& see) the results -./bin/wps_scripts -w ./ -s noisemodelling/wps/Import_and_Export/Export_Table.groovy -exportPath RECEIVERS_LEVEL.shp -tableToExport RECEIVERS_LEVEL diff --git a/wps_scripts/gradle/wrapper/gradle-wrapper.jar b/wps_scripts/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index a4b76b953..000000000 Binary files a/wps_scripts/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/wps_scripts/gradle/wrapper/gradle-wrapper.properties b/wps_scripts/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index cea7a793a..000000000 --- a/wps_scripts/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/wps_scripts/gradlew b/wps_scripts/gradlew deleted file mode 100755 index f3b75f3b0..000000000 --- a/wps_scripts/gradlew +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# 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 -# -# https://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. -# -# SPDX-License-Identifier: Apache-2.0 -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/wps_scripts/gradlew.bat b/wps_scripts/gradlew.bat deleted file mode 100644 index 9d21a2183..000000000 --- a/wps_scripts/gradlew.bat +++ /dev/null @@ -1,94 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/_remote.repositories b/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/_remote.repositories deleted file mode 100644 index ea91dc80f..000000000 --- a/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/_remote.repositories +++ /dev/null @@ -1,4 +0,0 @@ -#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice. -#Thu Oct 03 10:54:23 CEST 2019 -noisemodelling-wps-1.0-SNAPSHOT.jar>= -noisemodelling-wps-1.0-SNAPSHOT.pom>= diff --git a/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/maven-metadata-local.xml b/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index 0c2d96a4d..000000000 --- a/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - noisemodelling - noisemodelling-wps - 1.0-SNAPSHOT - - - true - - 20191003085423 - - - jar - 1.0-SNAPSHOT - 20191003085423 - - - pom - 1.0-SNAPSHOT - 20191003085423 - - - - diff --git a/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/noisemodelling-wps-1.0-SNAPSHOT-sources.jar b/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/noisemodelling-wps-1.0-SNAPSHOT-sources.jar deleted file mode 100644 index 3f9ccc01c..000000000 Binary files a/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/noisemodelling-wps-1.0-SNAPSHOT-sources.jar and /dev/null differ diff --git a/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/noisemodelling-wps-1.0-SNAPSHOT.jar b/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/noisemodelling-wps-1.0-SNAPSHOT.jar deleted file mode 100644 index 523a0cb19..000000000 Binary files a/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/noisemodelling-wps-1.0-SNAPSHOT.jar and /dev/null differ diff --git a/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/noisemodelling-wps-1.0-SNAPSHOT.pom b/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/noisemodelling-wps-1.0-SNAPSHOT.pom deleted file mode 100644 index bc51532ac..000000000 --- a/wps_scripts/libs/noisemodelling/noisemodelling-wps/1.0-SNAPSHOT/noisemodelling-wps-1.0-SNAPSHOT.pom +++ /dev/null @@ -1,28 +0,0 @@ - - - 4.0.0 - - noisemodelling - noisemodelling-wps - 1.0-SNAPSHOT - - - - org.orbisgis - h2gis-utilities - 1.5.0 - - - org.orbisgis - postgis-jts - 1.5.0 - - - org.postgresql - postgresql - 42.0.0.jre7 - - - \ No newline at end of file diff --git a/wps_scripts/libs/noisemodelling/noisemodelling-wps/maven-metadata-local.xml b/wps_scripts/libs/noisemodelling/noisemodelling-wps/maven-metadata-local.xml deleted file mode 100644 index c5e10a6f5..000000000 --- a/wps_scripts/libs/noisemodelling/noisemodelling-wps/maven-metadata-local.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - noisemodelling - noisemodelling-wps - - - 1.0-SNAPSHOT - - 20191003085424 - - diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/_remote.repositories b/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/_remote.repositories deleted file mode 100644 index fe457938c..000000000 --- a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/_remote.repositories +++ /dev/null @@ -1,5 +0,0 @@ -#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. -#Tue Apr 30 08:55:19 CEST 2019 -gs-script-core-2.15.1-tests.jar>boundless= -gs-script-core-2.15.1.jar>boundless= -gs-script-core-2.15.1.pom>boundless= diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1-tests.jar b/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1-tests.jar deleted file mode 100644 index 64d2890d1..000000000 Binary files a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1-tests.jar and /dev/null differ diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1-tests.jar.sha1 b/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1-tests.jar.sha1 deleted file mode 100644 index 4c8d8f751..000000000 --- a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1-tests.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -80a6de828e6cf77907838675ac95723a90117976 \ No newline at end of file diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.jar b/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.jar deleted file mode 100644 index e601ac5fb..000000000 Binary files a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.jar and /dev/null differ diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.jar.sha1 b/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.jar.sha1 deleted file mode 100644 index 7cc62f2b2..000000000 --- a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -787c2367b7ae2268983416786db4f10f5babe3b7 \ No newline at end of file diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.pom b/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.pom deleted file mode 100644 index ff599aca5..000000000 --- a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.pom +++ /dev/null @@ -1,36 +0,0 @@ - - - - 4.0.0 - - org.geoserver.community - gs-script - 2.15.1 - - org.geoserver.script - gs-script-core - jar - Core Scripting Extension - - - - com.google.guava - guava - - - org.easymock - easymockclassextension - test - - - cglib - cglib-nodep - test - - - - diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.pom.sha1 b/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.pom.sha1 deleted file mode 100644 index f1d8e9246..000000000 --- a/wps_scripts/libs/org/geoserver/script/gs-script-core/2.15.1/gs-script-core-2.15.1.pom.sha1 +++ /dev/null @@ -1 +0,0 @@ -c9752381215955f962ce2b3b0e17a3bbfb862d37 \ No newline at end of file diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/_remote.repositories b/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/_remote.repositories deleted file mode 100644 index 158986c9b..000000000 --- a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/_remote.repositories +++ /dev/null @@ -1,7 +0,0 @@ -#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. -#Tue Apr 30 10:31:28 CEST 2019 -gs-script-groovy-2.15.1-sources.jar>= -gs-script-groovy-2.15.1-test-sources.jar>= -gs-script-groovy-2.15.1.jar>= -gs-script-groovy-2.15.1-tests.jar>= -gs-script-groovy-2.15.1.pom>= diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1-sources.jar b/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1-sources.jar deleted file mode 100644 index 7bf0f2e4f..000000000 Binary files a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1-sources.jar and /dev/null differ diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1-test-sources.jar b/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1-test-sources.jar deleted file mode 100644 index 47f86ea1f..000000000 Binary files a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1-test-sources.jar and /dev/null differ diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1-tests.jar b/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1-tests.jar deleted file mode 100644 index 47b0ce264..000000000 Binary files a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1-tests.jar and /dev/null differ diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1.jar b/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1.jar deleted file mode 100644 index f53d76656..000000000 Binary files a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1.jar and /dev/null differ diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1.pom b/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1.pom deleted file mode 100644 index b70447d4f..000000000 --- a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/2.15.1/gs-script-groovy-2.15.1.pom +++ /dev/null @@ -1,123 +0,0 @@ - - - - 4.0.0 - - org.geoserver.community - gs-script - 2.15.1 - - org.geoserver.script - gs-script-groovy - jar - Groovy Scripting Extension - - - org.geoserver.script - gs-script-core - ${project.version} - - - org.geoscript - geoscript-groovy - 1.13-SNAPSHOT - - - org.codehaus.groovy - groovy-jsr223 - 2.5.5 - - - org.codehaus.groovy - groovy-ant - 2.5.5 - - - org.codehaus.groovy - groovy-groovydoc - 2.5.5 - - - - no.ecc.vectortile - java-vector-tile - - - - com.google.protobuf - protobuf-java - - - - - net.sf.json-lib - json-lib - jdk15 - - - org.geoserver.script - gs-script-core - ${project.version} - tests - test - - - - - - org.codehaus.groovy - groovy-eclipse-compiler - 2.9.2-01 - true - - - maven-compiler-plugin - 3.1 - - groovy-eclipse-compiler - true - 11 - 11 - UTF-8 - - - - org.codehaus.groovy - groovy-eclipse-compiler - 2.9.2-01 - - - org.codehaus.groovy - groovy-eclipse-batch - 2.3.7-01 - - - - - maven-antrun-plugin - - - package - - - - - - - - - - - - run - - - - - - - diff --git a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/maven-metadata-local.xml b/wps_scripts/libs/org/geoserver/script/gs-script-groovy/maven-metadata-local.xml deleted file mode 100644 index e7c67b4e5..000000000 --- a/wps_scripts/libs/org/geoserver/script/gs-script-groovy/maven-metadata-local.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - org.geoserver.script - gs-script-groovy - - 2.15.1 - - 2.15-SNAPSHOT - 2.15.1 - - 20190430083128 - - diff --git a/wps_scripts/src/main/groovy/get_started_tutorial.groovy b/wps_scripts/src/main/groovy/get_started_tutorial.groovy deleted file mode 100644 index 4a4f8ef63..000000000 --- a/wps_scripts/src/main/groovy/get_started_tutorial.groovy +++ /dev/null @@ -1,70 +0,0 @@ -/** - * NoiseModelling is an open-source tool designed to produce environmental noise maps - * on very large urban areas. It can be used as a Java library or be controlled through - * a user friendly web interface. - * - * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the - * Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). - * - * - * NoiseModelling is distributed under GPL 3 license. You can read a copy of this - * License in the file LICENCE provided with this software. - * - * Contact: contact@noise-planet.org - */ - -/** - * @Author Pierre Aumond, Université Gustave Eiffel - * @Author Nicolas Fortin, Université Gustave Eiffel - */ - -import org.h2gis.api.ProgressVisitor -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import java.sql.Connection - -title = 'Tutorial script' -description = 'Long description of tutorial script' - -inputs = [:] - -outputs = [result: [name: 'Result output string', title: 'Result output string', description: 'This type of result does not allow the blocks to be linked together.', type: String.class]] - - -def runScript(connection, scriptFile, arguments) { - Logger logger = LoggerFactory.getLogger("script") - GroovyShell shell = new GroovyShell() - Script scriptInstance = shell.parse(new File(scriptFile)) - Object result = scriptInstance.invokeMethod("exec", [connection, arguments]) - if(result != null) { - logger.info(result.toString()) - } -} - -def exec(Connection connection, input) { - - // Step 4: Upload files to database - runScript(connection, "noisemodelling/wps/Import_and_Export/Import_File.groovy", - ["pathFile":"resources/org/noise_planet/noisemodelling/wps/ground_type.shp"]) - - runScript(connection, "noisemodelling/wps/Import_and_Export/Import_File.groovy", - ["pathFile":"resources/org/noise_planet/noisemodelling/wps/buildings.shp"]) - - runScript(connection, "noisemodelling/wps/Import_and_Export/Import_File.groovy", - ["pathFile":"resources/org/noise_planet/noisemodelling/wps/receivers.shp"]) - - runScript(connection, "noisemodelling/wps/Import_and_Export/Import_File.groovy", - ["pathFile":"resources/org/noise_planet/noisemodelling/wps/ROADS2.shp"]) - - runScript(connection, "noisemodelling/wps/Import_and_Export/Import_File.groovy", - ["pathFile":"resources/org/noise_planet/noisemodelling/wps/dem.geojson"]) - - // Step 5: Run Calculation - runScript(connection, "noisemodelling/wps/NoiseModelling/Noise_level_from_traffic.groovy", - ["tableBuilding":"BUILDINGS", "tableRoads":"ROADS2", "tableReceivers":"RECEIVERS", - "tableDEM":"DEM", "tableGroundAbs":"GROUND_TYPE"]) - - // Step 6: Export (& see) the results - runScript(connection, "noisemodelling/wps/Import_and_Export/Export_Table.groovy", - ["exportPath":"LDAY_GEOM.shp", "tableToExport":"LDAY_GEOM"]) -} diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/template/Template.groovy b/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/template/Template.groovy deleted file mode 100644 index 1ab738e38..000000000 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/template/Template.groovy +++ /dev/null @@ -1,175 +0,0 @@ -/** - * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. - * - * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). - * - * - * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. - * - * Contact: contact@noise-planet.org - * - */ - -/** - * @Author Pierre Aumond, Université Gustave Eiffel - * @Author Nicolas Fortin, Université Gustave Eiffel - * @Author Valentin Le Bescond, Université Gustave Eiffel - */ - -package org.noise_planet.noisemodelling.template - -import geoserver.GeoServer -import geoserver.catalog.Store -import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore -import org.h2gis.utilities.TableLocation -import org.h2gis.utilities.wrapper.ConnectionWrapper -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import java.sql.Connection -import java.sql.SQLException - -// ---------------- -// This is a short template. -// Some doubts may remain about writing a WPS script. -// You can look at other WPS scripts to get inspiration. -// ---------------- - -title = 'Simple Title' // This is not use in WPS Builder. The real title of the WPS bloc is the name of the file. It can't contain space or special character. - -description = 'Description of the WPS.' + - '
    Description of the WPS.' + - '

    Description of the output tables : NAME OF THE OUTPUT TABLES ' + - 'and contain :
    ' + - '- NAME OF ATTRIBUTE 1 : description attribute 1 (INTEGER, PRIMARY KEY).
    ' + - '- NAME OF ATTRIBUTE 2 : description attribute 2 (POINT).' - -inputs = [ - input1 : [ - name : 'Title of the input bloc', // This is not use in WPS Builder. The real title of the WPS bloc is the title item. - title : 'Title of the input bloc', // Please be short - description: 'Name of the input table.
    ' + // Please be long - '
    The table shall contain :
    ' + - '- NAME OF ATTRIBUTE 1 : description attribute 1 (POLYGON or MULTIPOLYGON).
    ' + - '- NAME OF ATTRIBUTE 2 : description attribute 2 (FLOAT)', - type : String.class // Input type - ], - input2 : [ - name : 'Title of the input bloc', // This is not use in WPS Builder. The real title of the WPS bloc is the title item. - title : 'Title of the input bloc', // Please be short - description: 'Name of the input table.
    ' + // Please be long - '
    The table shall contain :
    ' + - '- NAME OF ATTRIBUTE 1 : description attribute 1 (POLYGON or MULTIPOLYGON).
    ' + - '- NAME OF ATTRIBUTE 2 : description attribute 2 (FLOAT)', - min : 0, max: 1, // it makes this bloc optional - type : Integer.class // Input type - ] -] - -outputs = [ - result: [ - name: 'Result output string', // This is not use in WPS Builder. The real title of the WPS bloc is the title item. - title: 'Result output string', // Please be short - description: 'This type of result does not allow the blocks to be linked together.', // This is not use in WPS Builder. - type: String.class - ] -] - -// Open Connection to Geoserver -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -// run the script -def run(input) { - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a PostGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -// Functions definition -def testFunction(Sql sql, String test) { - StringBuilder sb = new StringBuilder("create table ") - sb.append(test) -} - -// Main function of the script -def exec(Connection connection, input) { - - //Need to change the ConnectionWrapper to WpsConnectionWrapper to work under postGIS database - connection = new ConnectionWrapper(connection) - - // Create a sql connection to interact with the database in SQL - Sql sql = new Sql(connection) - - // output string, the information given back to the user - // This is the output displayed in the WPS Builder. HTML code can be used. - // Please inform the user about the actions that have been performed by the script (e.g. table creation), and about any warnings he should receive. - String resultString = null - - // Create a logger to display messages in the geoserver logs and in the command prompt. - // Please use logger.info at least when the script starts, ends and creates a table. - // You can use the warning but the user could not be noticed. Please fill in the resultString variable with your warnings. - // Don't register errors by this logger, use "throw Exception" instead. - Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") - - // print to command window - logger.info('Start : Template') - logger.info("inputs {}", input) // log inputs of the run - - // ------------------- - // Get every inputs - // ------------------- - - String sources_table_name = input['input1'] as String - // do it case-insensitive - sources_table_name = sources_table_name.toUpperCase() - - //Get the geometry field of the source table - TableLocation sourceTableIdentifier = TableLocation.parse(sources_table_name) - List geomFields = GeometryTableUtilities.getGeometryFields(connection, sourceTableIdentifier) - - // Please throw Exception in this format - if (geomFields.isEmpty()) { - throw new SQLException(String.format("The table %s does not exists or does not contain a geometry field", sourceTableIdentifier)) - } - - String receivers_table_name = input['input2'] - // do it case-insensitive - receivers_table_name = receivers_table_name.toUpperCase() - - // ------------------- - // Calculation - // ------------------- - - def a = 0 - a=a+1 - - // ------------------- - // Print results - // ------------------- - - resultString = "Calculation Done ! LDEN_GEOM table has been created." - - // print to command window and geoserver log - logger.info('Result : ' + resultString) - logger.info('End : Template') - - // send resultString to WPS Builder - return resultString - -} - diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Table_Visualization_Data.groovy b/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Table_Visualization_Data.groovy deleted file mode 100644 index 014fb55fc..000000000 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Database_Manager/Table_Visualization_Data.groovy +++ /dev/null @@ -1,190 +0,0 @@ -/** - * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. - * - * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). - * - * - * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. - * - * Contact: contact@noise-planet.org - * - */ - -/** - * @Author Pierre Aumond, Université Gustave Eiffel - * @Author Nicolas Fortin, Université Gustave Eiffel - */ - - -package org.noise_planet.noisemodelling.wps.Database_Manager - -import geoserver.GeoServer -import geoserver.catalog.Store -import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore -import org.h2gis.utilities.JDBCUtilities -import org.h2gis.utilities.GeometryTableUtilities -import org.h2gis.utilities.TableLocation -import org.locationtech.jts.geom.Geometry -import org.locationtech.jts.io.WKTWriter -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import java.sql.Connection - - -title = 'Display first rows of a table.' -description = '➡️ Display the content of a table.
    ' + - '


    ' + - 'Using "linesNumber" parameter, you can choose the number of lines to display

    ' + - '🚨 Be careful, this treatment can be very long if the table is large.' - -inputs = [ - linesNumber: [ - name : 'Number of rows', - title : 'Number of rows', - description: 'Number of rows you want to display (INTEGER)

    ' + - '🛠 Default value: 10 ', - min : 0, max: 1, - type : Integer.class - ], - tableName : [ - name : 'Name of the table', - title : 'Name of the table', - description: 'Name of the table you want to display', - type : String.class - ] -] - -outputs = [ - result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', - type : String.class - ] -] - -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -def exec(Connection connection, input) { - - // Create a logger to display messages in the geoserver logs and in the command prompt. - Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") - - // print to command window - logger.info('Start : Display first rows of a table') - logger.info("inputs {}", input) // log inputs of the run - - // Get the number of rows the user want to display - int linesNumber = 10 - if (input['linesNumber']) { - linesNumber = input['linesNumber'] as Integer - } - - // Get name of the table - String tableName = input["tableName"] as String - // do it case-insensitive - tableName = tableName.toUpperCase() - - // Create a connection statement to interact with the database in SQL - Sql sql = new Sql(connection) - - List output = sql.rows(String.format("select * from %s LIMIT %s", tableName, linesNumber.toString())) - - logger.info('End : Display first rows of a table') - - - // print to WPS Builder - return mapToTable(output, sql, tableName, connection) -} - - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -/** - * Convert a list to HTML table - * @param list - * @return - */ -static String mapToTable(List list, Sql sql, String tableName, Connection connection) { - - StringBuilder output = new StringBuilder() - - Map first = list.first() - - output.append("The total number of rows is " + sql.firstRow('SELECT COUNT(*) FROM ' + tableName)[0]) - - //get SRID of the table - int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(tableName)) - - if (srid > 0) { - output.append("
    ") - output.append("The srid of the table is " + srid) - } else { - output.append("
    ") - output.append("This table doesn't have any srid") - } - - //get SRID of the table - int pkIndex = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(tableName)) - - if (pkIndex > 0) { - output.append("
    ") - output.append("The table has the following primary key : " + JDBCUtilities.getColumnName(connection, tableName, pkIndex)) - } else { - output.append("
    ") - output.append("This table does not have primary key.") - } - - - output.append("

    ") - output.append("") - - first.each { key, val -> - output.append("") - } - - output.append("") - WKTWriter wktWriter = new WKTWriter(3) - list.each { map -> - if (map.size() > 0) { - - def values = map.values() - - output.append("") - - values.each { - def val = it - if (it instanceof Geometry) { - val = wktWriter.write(it) - } - output.append "" - } - - output.append("") - } - } - output.append("
    ${key}
    ${val}
    ") - - output.toString() -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Noise_From_Attenuation_Matrix_MatSim.groovy b/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Noise_From_Attenuation_Matrix_MatSim.groovy deleted file mode 100644 index f392634a3..000000000 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Noise_From_Attenuation_Matrix_MatSim.groovy +++ /dev/null @@ -1,289 +0,0 @@ -/** - * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. - * - * This version is developed by Université Gustave Eiffel and CNRS - * - * - * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. - * - * Contact: contact@noise-planet.org - * - */ -/** - * @Author Valentin Le Bescond, Université Gustave Eiffel - */ - -package org.noise_planet.noisemodelling.wps.Experimental_Matsim - -import geoserver.GeoServer -import geoserver.catalog.Store -import groovy.sql.GroovyRowResult -import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore -import org.h2gis.utilities.wrapper.ConnectionWrapper -import org.locationtech.jts.geom.Geometry -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import java.sql.* -import groovy.sql.Sql - -title = 'Noise Map From Attenuation Matrix' -description = 'Noise Map From Attenuation Matrix.' + - '
    ' - -inputs = [ - matsimRoads: [ - name: 'Table name of the MATSIM table containing the roads geometries', - title: 'Table name of the MATSIM table containing the roads geometries', - description: 'Table name of the MATSIM table containing the roads geometries' + - '
    The table must contain the following fields : (PK, LINK_ID, THE_GEOM)', - type: String.class - ], - matsimRoadsLw : [ - name: 'Table name of the MATSIM table containing the roads LW stats per timeBin', - title: 'Table name of the MATSIM table containing the roads LW stats per timeBin', - description: 'Table name of the MATSIM table containing the roads LW stats per timeBin' + - '
    The table must contain the following fields : ' + - '
    PK, LINK_ID, LW63, LW125, LW250, LW500, LW1000, LW2000, LW4000, LW8000, TIME', - type: String.class - ], - receiversTable : [ - name: 'Name of the table containing the receivers', - title: 'Name of the table containing the receivers', - description: 'Name of the table containing the receivers' + - '
    The table must contain the following fields : ' + - '
    PK, THE_GEOM', - type: String.class - ], - attenuationTable : [ - name: 'Attenuation Matrix Table name', - title: 'Attenuation Matrix Table name', - description: 'Attenuation Matrix Table name, Obtained from the Noise_level_from_source script with "confExportSourceId" enabled' + - '
    The table must contain the following fields :' + - '
    IDRECEIVER, IDSOURCE, THE_GEOM, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ4000, HZ8000', - type: String.class - ], - timeBinSize: [ - name: 'The size of time bins in seconds.', - title: 'The size of time bins in seconds.', - description: 'This parameter dictates the time resolution of the resulting data ' + - '
    The time information stored will be the starting time of the time bins ' + - '
    For exemple with a timeBinSize of 3600, the data will be analysed using the following timeBins: ' + - '
    0, 3600, 7200, ..., 79200, 82800', - type: Integer.class - ], - outTableName: [ - name: 'Output table name', - title: 'Output table name', - description: 'Output table name' + - '
    The table will contain the following fields :' + - '
    PK, IDRECEIVER, THE_GEOM, HZ63, HZ125, HZ250, HZ500, HZ1000, HZ2000, HZ000, HZ8000, TIME', - type: String.class - ] -] - -outputs = [ - result: [ - name: 'Result output string', - title: 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', - type: String.class - ] -] - -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - - // Get name of the database - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -// main function of the script -@CompileStatic -static def exec(Connection connection, input) { - - connection = new ConnectionWrapper(connection) - - Sql sql = new Sql(connection) - - String resultString - - Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") - logger.info('Start : Noise_From_Attenuation_Matrix') - logger.info("inputs {}", input) - - String matsimRoads = input['matsimRoads'] - String matsimRoadsLw = input['matsimRoadsLw'] - String attenuationTable = input['attenuationTable'] - String receiversTable = input['receiversTable'] - String outTableName = input['outTableName'] - - int timeBinSize = 3600 - if (input["timeBinSize"]) { - timeBinSize = input["timeBinSize"] as int; - } - - DatabaseMetaData dbMeta = connection.getMetaData(); - ResultSet rs = dbMeta.getIndexInfo(null, null, attenuationTable, false, false); - - - sql.execute(String.format("DROP TABLE %s IF EXISTS", outTableName)) - String query = "CREATE TABLE " + outTableName + '''( - PK integer PRIMARY KEY AUTO_INCREMENT, - IDRECEIVER integer, - THE_GEOM geometry, - HZ63 double precision, - HZ125 double precision, - HZ250 double precision, - HZ500 double precision, - HZ1000 double precision, - HZ2000 double precision, - HZ4000 double precision, - HZ8000 double precision, - TIME int - ) - ''' - sql.execute(query) - PreparedStatement insert_stmt = connection.prepareStatement( - "INSERT INTO " + outTableName + " VALUES(DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ) - - logger.info("searching indexes on attenuation matrix ... ") - ensureIndex(connection, attenuationTable, "IDSOURCE", false) - ensureIndex(connection, attenuationTable, "IDRECEIVER", false) - logger.info("searching indexes on traffic tables ... ") - ensureIndex(connection, matsimRoads, "LINK_ID", false) - ensureIndex(connection, matsimRoadsLw, "LINK_ID", false) - ensureIndex(connection, matsimRoadsLw, "TIME", false) - - List mrs_freqs = ["LW63", "LW125", "LW250", "LW500", "LW1000", "LW2000", "LW4000", "LW8000"] - - long count = 0, do_print = 1 - List receivers_res = sql.rows("SELECT * FROM " + receiversTable); - long nb_receivers = receivers_res.size() - long start = System.currentTimeMillis(); - for (GroovyRowResult receiver: receivers_res) { - long receiver_id = receiver["PK"] as long; - Geometry receiver_geom = receiver["THE_GEOM"] as Geometry; - Map> levels = new HashMap>(); - List sources_att_res = sql.rows(String.format("SELECT lg.* FROM %s lg WHERE lg.IDRECEIVER = %d", attenuationTable, receiver_id)); - long nb_sources = sources_att_res.size(); - if (nb_sources == 0) { - count++ - continue - } - for (GroovyRowResult sources_att: sources_att_res) { - long source_id = sources_att["IDSOURCE"] as long; - List attenuation = [ - sources_att["HZ63"] as double, - sources_att["HZ125"] as double, - sources_att["HZ250"] as double, - sources_att["HZ500"] as double, - sources_att["HZ1000"] as double, - sources_att["HZ2000"] as double, - sources_att["HZ4000"] as double, - sources_att["HZ8000"] as double, - ]; - List roads_stats_res = sql.rows(String.format( - "SELECT mrs.* FROM %s mrs INNER JOIN %s mr ON mr.LINK_ID = mrs.LINK_ID WHERE mr.PK = %d", - matsimRoadsLw, matsimRoads, source_id)); - for (GroovyRowResult roads_stats: roads_stats_res) { - int timeBin = roads_stats["TIME"] as int - if (!levels.containsKey(timeBin)) { - levels[timeBin] = [-99.0, -99.0, -99.0, -99.0, -99.0, -99.0, -99.0, -99.0] as List - } - for (i in 0..<8) { - double new_level = (roads_stats[mrs_freqs[i]] as double) + attenuation[i]; - levels[timeBin][i] = (double) 10 * Math.log10( Math.pow(10, (double) levels[timeBin][i] / 10.0) + Math.pow(10, (double) new_level / 10.0) ); - } - } - } - - for (int timeBin = 0; timeBin < 86400; timeBin += timeBinSize) { - if (!levels.containsKey(timeBin)) { - levels[timeBin] = [-99.0, -99.0, -99.0, -99.0, -99.0, -99.0, -99.0, -99.0] as List - } - List ts_levels = levels[timeBin] - insert_stmt.setLong(1, receiver_id) - insert_stmt.setString(2, receiver_geom.toText()) - for (i in 0..<8) { - insert_stmt.setDouble(i+3, ts_levels[i]) - } - insert_stmt.setInt(11, timeBin) - insert_stmt.execute() - } - if (count >= do_print) { - double elapsed = (System.currentTimeMillis() - start + 1) / 1000 - logger.info(String.format("Processing Receiver %d (max:%d) - elapsed : %ss (%.1fit/s)", - count, nb_receivers, elapsed, count/elapsed)) - do_print *= 2 - } - count ++ - } - - String prefix = "HZ" - sql.execute("ALTER TABLE " + outTableName + " ADD COLUMN LEQA float as 10*log10((power(10,(" + prefix + "63-26.2)/10)+power(10,(" + prefix + "125-16.1)/10)+power(10,(" + prefix + "250-8.6)/10)+power(10,(" + prefix + "500-3.2)/10)+power(10,(" + prefix + "1000)/10)+power(10,(" + prefix + "2000+1.2)/10)+power(10,(" + prefix + "4000+1)/10)+power(10,(" + prefix + "8000-1.1)/10)))") - sql.execute("ALTER TABLE " + outTableName + " ADD COLUMN LEQ float as 10*log10((power(10,(" + prefix + "63)/10)+power(10,(" + prefix + "125)/10)+power(10,(" + prefix + "250)/10)+power(10,(" + prefix + "500)/10)+power(10,(" + prefix + "1000)/10)+power(10,(" + prefix + "2000)/10)+power(10,(" + prefix + "4000)/10)+power(10,(" + prefix + "8000)/10)))") - - logger.info('End : Noise_From_Attenuation_Matrix') - resultString = "Process done. Table of receivers " + outTableName + " created !" - logger.info('Result : ' + resultString) - return resultString -} - -static boolean tableExists(Connection connection, String table) { - DatabaseMetaData dbMeta = connection.getMetaData(); - ResultSet rs = dbMeta.getTables(null, null, table, null); - boolean table_found = false; - if (rs.next()) { - table_found = true - } - return table_found -} - -static boolean columnExists(Connection connection, String table, String column_name) { - DatabaseMetaData dbMeta = connection.getMetaData(); - ResultSet rs = dbMeta.getColumns(null, null, table, column_name); - boolean col_found = false; - if (rs.next()) { - col_found = true - } - return col_found -} - -static boolean indexExists(Connection connection, String table, String column_name) { - DatabaseMetaData dbMeta = connection.getMetaData(); - ResultSet rs = dbMeta.getIndexInfo(null, null, table, false, false); - boolean index_found = false; - while (rs.next()) { - String column = rs.getString("COLUMN_NAME"); - String pos = rs.getString("ORDINAL_POSITION"); - if (column == column_name && pos == "1") { - index_found = true; - } - } - return index_found -} - -static void ensureIndex(Connection connection, String table, String column_name, boolean spatial) { - if (!indexExists(connection, table, column_name)) { - Sql sql = new Sql(connection) - sql.execute("CREATE " + (spatial ? "SPATIAL " : "") + "INDEX ON " + table + " (" + column_name + ")"); - } -} \ No newline at end of file diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Sources_From_TimeString.groovy b/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Sources_From_TimeString.groovy deleted file mode 100644 index 7bceab2bd..000000000 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Experimental_Matsim/Sources_From_TimeString.groovy +++ /dev/null @@ -1,142 +0,0 @@ -/** - * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. - * - * This version is developed by Université Gustave Eiffel and CNRS - * - * - * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. - * - * Contact: contact@noise-planet.org - * - */ -/** - * @Author Valentin Le Bescond, Université Gustave Eiffel - */ - -package org.noise_planet.noisemodelling.wps.Experimental_Matsim - -import geoserver.GeoServer -import geoserver.catalog.Store -import groovy.sql.Sql -import groovy.transform.CompileStatic -import org.geotools.jdbc.JDBCDataStore -import org.h2gis.utilities.wrapper.ConnectionWrapper -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import java.sql.Connection - -title = 'Create a SOURCE table from imported MATSim tables' -description = 'Create a ROADS table from imported MATSim tables, for a specific timeBin' + - '
    The timeBin can be 0, 900, 1800, etc. for example for 15minutes analysis.' + - '
    The resulting table will contain the following fields :' + - '

    - ' - -inputs = [ - roadsTableName: [ - name: 'Table name of the MATSIM table containing the roads geometries', - title: 'Table name of the MATSIM table containing the roads geometries', - description: 'Table name of the MATSIM table containing the roads geometries' + - '
    The table must contain the following fields : (PK, LINK_ID, THE_GEOM)', - type: String.class - ], - lwTableName: [ - name: 'Table name of the MATSIM table containing the roads LW stats per timeBin', - title: 'Table name of the MATSIM table containing the roads LW stats per timeBin', - description: 'Table name of the MATSIM table containing the roads LW stats per timeBin' + - '
    The table must contain the following fields : ' + - '
    (PK, LINK_ID, LW63, LW125, LW250, LW500, LW1000, LW2000, LW4000, LW8000, TIME)' + - '
    default : roadsTableName + "_LW"', - min: 0, - max: 1, - type: String.class - ], - timeBin: [ - name: 'TIME Field value', - title: 'TIME Field value', - description: 'TIME Field value' + - '
    The timeBin is an integer representing the starting time of the desired timebin in seconds, it should exist in the traffic data tables', - type: Integer.class - ], - outTableName: [ - name: 'Output table name', - title: 'Output table name', - description: 'Output table name' + - '
    The table will contain the following fields :' + - '
    (PK, THE_GEOM, LW63, LW125, LW250, LW500, LW1000, LW2000, LW4000, LW8000)', - type: String.class - ] -] - -outputs = [ - result: [ - name: 'Result output string', - title: 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', - type: String.class - ] -] - -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - - -def run(input) { - - // Get name of the database - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -// main function of the script -@CompileStatic -static def exec(Connection connection, input) { - - connection = new ConnectionWrapper(connection) - - Sql sql = new Sql(connection) - - String resultString = null - - Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") - logger.info('Start : Create_Sources_Matsim_From_TimeString') - logger.info("inputs {}", input) - - String roadsTableName = input["roadsTableName"] as String; - String statsTableName = roadsTableName + "_STATS"; - if (input["statsTableName"]) { - statsTableName = input["statsTableName"] as String; - } - String timeString = input["timeString"] as String; - String outTableName = input["outTableName"] as String; - - sql.execute("DROP TABLE IF EXISTS " + outTableName) - sql.execute("CREATE TABLE " + outTableName + '''( - PK integer PRIMARY KEY, - THE_GEOM geometry, - LW63 double precision, LW125 double precision, LW250 double precision, LW500 double precision, LW1000 double precision, LW2000 double precision, LW4000 double precision, LW8000 double precision, - );''') - - sql.execute("MERGE INTO " + outTableName + ''' - SELECT R.PK PK, R.THE_GEOM THE_GEOM, - S.LW63, S.LW125, S.LW250, S.LW500, S.LW1000, S.LW2000, S.LW4000, S.LW8000 - FROM ''' + roadsTableName + ''' R, ''' + statsTableName + ''' S - WHERE R.LINK_ID = S.LINK_ID AND S.TIMESTRING = \'''' + timeString + '''\'; - ''') - - logger.info('End : Create_Sources_Matsim_From_TimeString') - resultString = outTableName + " created."; - logger.info('Result : ' + resultString) - return resultString; -} diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Set_Height.groovy b/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Set_Height.groovy deleted file mode 100644 index 992d19041..000000000 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Geometric_Tools/Set_Height.groovy +++ /dev/null @@ -1,121 +0,0 @@ -/** - * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. - * - * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). - * - * - * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. - * - * Contact: contact@noise-planet.org - * - */ - -/** - * @Author Aumond Pierre, Université Gustave Eiffel - */ - -package org.noise_planet.noisemodelling.wps.Geometric_Tools - -import geoserver.GeoServer -import geoserver.catalog.Store -import groovy.sql.Sql -import org.geotools.jdbc.JDBCDataStore -import org.h2gis.utilities.GeometryMetaData -import org.h2gis.utilities.GeometryTableUtilities -import org.h2gis.utilities.TableLocation -import org.h2gis.utilities.dbtypes.DBUtils -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import java.sql.Connection - -title = 'Set_Height' -description = '➡️ Set a new height to a set of receivers or sources (Points or LineStrings).' - -inputs = [ - tableName: [ - title : 'Name of the table', - name : 'Name of the table', - description: 'Name of the table on which the height will be modified.', - type : String.class - ], - height: [ - name : 'New height', - title : 'New height', - description: 'New height for the input table (in meters) (FLOAT)', - type : Double.class - ] -] - -outputs = [ - result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', - type : String.class - ] -] - -// run the script -def run(input) { - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -def exec(Connection connection, input) { - - // output string, the information given back to the user - String resultString = "" - - // Create a sql connection to interact with the database in SQL - Sql sql = new Sql(connection) - - // Create a logger to display messages in the geoserver logs and in the command prompt. - Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") - - // print to command window - logger.info('Start : Set new height') - logger.info("inputs {}", input) // log inputs of the run - - String table_name = input['tableName'] as String - table_name = table_name.toUpperCase() - - Double h = input['height'] - - //get SRID of the table - int srid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(table_name)) - if (srid == 3785 || srid == 4326) throw new IllegalArgumentException("Error : This SRID is not metric. Please use another SRID for your table.") - if (srid == 0) throw new IllegalArgumentException("Error : The table does not have an associated SRID.") - - GeometryMetaData metaData = GeometryTableUtilities.getMetaData(connection, TableLocation.parse(table_name, DBUtils.getDBType(connection)), "THE_GEOM"); - metaData.setSRID(srid) - metaData.setHasZ(true) - metaData.initGeometryType() - connection.createStatement().execute(String.format(Locale.ROOT, "ALTER TABLE %s ALTER COLUMN %s %s USING ST_SetSRID(ST_UPDATEZ(%s, %f),%d)", - TableLocation.parse(table_name, DBUtils.getDBType(connection)), "THE_GEOM" , metaData.getSQL(),"THE_GEOM", h,srid)) - - resultString = "Process done. Table of receivers " + table_name + " has now a new height set to " + h + "." - - logger.info('End : Set new height') - - return resultString -} - - diff --git a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_File.groovy b/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_File.groovy deleted file mode 100644 index 45492fb7a..000000000 --- a/wps_scripts/src/main/groovy/org/noise_planet/noisemodelling/wps/Import_and_Export/Import_File.groovy +++ /dev/null @@ -1,283 +0,0 @@ -/** - * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. - * - * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). - * - * - * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. - * - * Contact: contact@noise-planet.org - * - */ - -/** - * @Author Pierre Aumond, Université Gustave Eiffel - * @Author Nicolas Fortin, Université Gustave Eiffel - */ - -package org.noise_planet.noisemodelling.wps.Import_and_Export - -import geoserver.GeoServer -import geoserver.catalog.Store -import org.apache.commons.io.FilenameUtils -import org.geotools.jdbc.JDBCDataStore -import org.h2gis.api.EmptyProgressVisitor -import org.h2gis.functions.io.csv.CSVDriverFunction -import org.h2gis.functions.io.dbf.DBFDriverFunction -import org.h2gis.functions.io.fgb.FGBDriverFunction -import org.h2gis.functions.io.geojson.GeoJsonDriverFunction -import org.h2gis.functions.io.gpx.GPXDriverFunction -import org.h2gis.functions.io.osm.OSMDriverFunction -import org.h2gis.functions.io.shp.SHPDriverFunction -import org.h2gis.functions.io.tsv.TSVDriverFunction -import org.h2gis.utilities.JDBCUtilities -import org.h2gis.utilities.GeometryTableUtilities -import org.h2gis.utilities.TableLocation -import org.h2gis.utilities.dbtypes.DBUtils -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import java.sql.Connection -import java.sql.ResultSet -import java.sql.Statement - -title = 'Import File' -description = '➡️ Import file into the database.
    '+ - '
    ' + - 'Valid file extensions: csv, dbf, geojson, gpx, bz2, gz, osm, shp, tsv

    ' + - 'Import file' - -inputs = [ - pathFile : [ - name : 'Path of the input File', - title : 'Path of the input File', - description: '📂 Path of the file you want to import, including its extension.

    ' + - 'For example: c:/home/buildings.geojson', - type : String.class - ], - inputSRID: [ - name : 'Projection identifier', - title : 'Projection identifier', - description: '🌍 Original projection identifier (also called SRID) of your table.

    ' + - 'It should be an EPSG code, an integer with 4 or 5 digits (ex: 3857 is Pseudo-Mercator projection).

    ' + - 'This entry is optional because many formats already include the projection and you can also import files without geometry attributes.

    ' + - 'If the table is geometric and if this parameter is not filled and:
    ' + - '- the file has a .prj file associated: the SRID is deduced from the .prj
    ' + - '- the file has no .prj file associated: we apply the WGS84 (EPSG:4326) code

    ' + - '🛠 Default value: 4326 ', - type : Integer.class, - min : 0, max: 1 - ], - tableName: [ - name : 'Output table name', - title : 'Name of created table', - description: 'Name of the table you want to create from the file.

    ' + - '🛠 Default value: it will take the name of the file without its extension (special characters will be removed and whitespaces will be replace by an underscore.', - min : 0, max: 1, - type : String.class - ] -] - -outputs = [ - result: [ - name : 'Result output string', - title : 'Result output string', - description: 'This type of result does not allow the blocks to be linked together.', - type : String.class - ] -] - -static Connection openGeoserverDataStoreConnection(String dbName) { - if (dbName == null || dbName.isEmpty()) { - dbName = new GeoServer().catalog.getStoreNames().get(0) - } - Store store = new GeoServer().catalog.getStore(dbName) - JDBCDataStore jdbcDataStore = (JDBCDataStore) store.getDataStoreInfo().getDataStore(null) - return jdbcDataStore.getDataSource().getConnection() -} - -def run(input) { - - // Get name of the database - // by default an embedded h2gis database is created - // Advanced user can replace this database for a postGis or h2Gis server database. - String dbName = "h2gisdb" - - // Open connection - openGeoserverDataStoreConnection(dbName).withCloseable { - Connection connection -> - return [result: exec(connection, input)] - } -} - -def exec(Connection connection, input) { - - // output string, the information given back to the user - String resultString = null - - - // Create a logger to display messages in the geoserver logs and in the command prompt. - Logger logger = LoggerFactory.getLogger("org.noise_planet.noisemodelling") - - // print to command window - logger.info('Start : Import File') - logger.info("inputs {}", input) // log inputs of the run - - - // Default SRID (WGS84) - Integer srid = 4326 - // Get user SRID - if (input['inputSRID']) { - srid = input['inputSRID'] as Integer - } - - // Get the path of the file to import - String pathFile = input["pathFile"] as String - if (!input["pathFile"]) { - resultString = "pathFile argument has not been provided." - throw new Exception('ERROR : ' + resultString) - } - - def file = new File(pathFile) - if (!file.exists()) { - resultString = pathFile + " is not found." - throw new Exception('ERROR : ' + resultString) - } - - // Get name of the table - String tableName = input["tableName"] as String - - // By default the name of the output table is the same than the file name - if (!tableName) { - // get the name of the fileName - String fileName = FilenameUtils.removeExtension(new File(pathFile).getName()) - // replace whitespaces by _ in the file name - fileName.replaceAll("\\s", "_") - // remove special characters in the file name - fileName.replaceAll("[^a-zA-Z0-9 ]+", "_") - // the tableName will be called as the fileName - tableName = fileName - } - - // do it case-insensitive - tableName = tableName.toUpperCase() - - // Create a connection statement to interact with the database in SQL - Statement stmt = connection.createStatement() - - // Drop the table if already exists - String dropOutputTable = "drop table if exists " + tableName - stmt.execute(dropOutputTable) - - // Get the extension of the file - String ext = pathFile.substring(pathFile.lastIndexOf('.') + 1, pathFile.length()).toLowerCase() - switch (ext) { - case "csv": - CSVDriverFunction csvDriver = new CSVDriverFunction() - csvDriver.importFile(connection, tableName, new File(pathFile), new EmptyProgressVisitor()) - break - case "dbf": - DBFDriverFunction dbfDriver = new DBFDriverFunction() - dbfDriver.importFile(connection, tableName, new File(pathFile), new EmptyProgressVisitor()) - break - case "geojson": - GeoJsonDriverFunction geoJsonDriver = new GeoJsonDriverFunction() - geoJsonDriver.importFile(connection, tableName, new File(pathFile), new EmptyProgressVisitor()) - break - case "gpx": - GPXDriverFunction gpxDriver = new GPXDriverFunction() - gpxDriver.importFile(connection, tableName, new File(pathFile), new EmptyProgressVisitor()) - break - case "bz2": - OSMDriverFunction osmDriver = new OSMDriverFunction() - osmDriver.importFile(connection, tableName, new File(pathFile), new EmptyProgressVisitor()) - break - case "gz": - OSMDriverFunction osmDriver = new OSMDriverFunction() - osmDriver.importFile(connection, tableName, new File(pathFile), new EmptyProgressVisitor()) - break - case "osm": - OSMDriverFunction osmDriver = new OSMDriverFunction() - osmDriver.importFile(connection, tableName, new File(pathFile), new EmptyProgressVisitor()) - break - case "shp": - SHPDriverFunction shpDriver = new SHPDriverFunction() - shpDriver.importFile(connection, tableName, new File(pathFile), new EmptyProgressVisitor()) - ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName) - - int pk2Field = JDBCUtilities.getFieldIndex(rs.getMetaData(), "PK2") - int pkField = JDBCUtilities.getFieldIndex(rs.getMetaData(), "PK") - - if (pk2Field > 0 && pkField > 0) { - stmt.execute("ALTER TABLE " + tableName + " DROP COLUMN PK2;") - logger.warn("The PK2 column automatically created by the SHP driver has been deleted.") - } - break - case "fgb": - FGBDriverFunction fgbDriver = new FGBDriverFunction() - fgbDriver.importFile(connection, tableName, new File(pathFile), new EmptyProgressVisitor()) - break - case "tsv": - TSVDriverFunction tsvDriver = new TSVDriverFunction() - tsvDriver.importFile(connection, tableName, new File(pathFile), new EmptyProgressVisitor()) - break - - } - - // Read Geometry Index and type of the table - List spatialFieldNames = GeometryTableUtilities.getGeometryColumnNames(connection, TableLocation.parse(tableName, DBUtils.getDBType(connection))) - - // If the table does not contain a geometry field - if (spatialFieldNames.isEmpty()) { - logger.warn("The table " + tableName + " does not contain a geometry field.") - } else { - stmt.execute('CREATE SPATIAL INDEX IF NOT EXISTS ' + tableName + '_INDEX ON ' + tableName + '(the_geom);') - - // Get the SRID of the table - Integer tableSrid = GeometryTableUtilities.getSRID(connection, TableLocation.parse(tableName)) - - if (tableSrid != 0 && tableSrid != srid && input['inputSRID']) { - resultString = "The table already has a different SRID than the one you gave." - throw new Exception('ERROR : ' + resultString) - } - - // Replace default SRID by the srid of the table - if (tableSrid != 0) srid = tableSrid - - // Display the actual SRID in the command window - logger.info("The SRID of the table is " + srid) - - // If the table does not have an associated SRID, add a SRID - if (tableSrid == 0 && !spatialFieldNames.isEmpty()) { - connection.createStatement().execute(String.format("SELECT UpdateGeometrySRID('%s', '" + spatialFieldNames.get(0) + "', %d);", - TableLocation.parse(tableName).toString(), srid)) - } - - } - - - // If the table has a PK column and doesn't have any Primary Key Constraint, then automatically associate a Primary Key - ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName) - int pkUserIndex = JDBCUtilities.getFieldIndex(rs.getMetaData(), "PK") - int pkIndex = JDBCUtilities.getIntegerPrimaryKey(connection, TableLocation.parse(tableName)) - - if (pkIndex == 0) { - if (pkUserIndex > 0) { - stmt.execute("ALTER TABLE " + tableName + " ALTER COLUMN PK INT NOT NULL;") - stmt.execute("ALTER TABLE " + tableName + " ADD PRIMARY KEY (PK); ") - resultString = resultString + String.format(tableName + " has a new primary key constraint on PK") - logger.info(String.format(tableName + " has a new primary key constraint on PK")) - } - } - - resultString = "The table " + tableName + " has been uploaded to database!" - - // print to command window - logger.info(resultString) - logger.info('End : Import File') - - // print to WPS Builder - return resultString - -} - diff --git a/wps_scripts/src/main/java/org/noise_planet/noisemodelling/runner/Main.java b/wps_scripts/src/main/java/org/noise_planet/noisemodelling/runner/Main.java deleted file mode 100644 index 1102f17dc..000000000 --- a/wps_scripts/src/main/java/org/noise_planet/noisemodelling/runner/Main.java +++ /dev/null @@ -1,288 +0,0 @@ -/** - * NoiseModelling is an open-source tool designed to produce environmental noise maps on very large urban areas. It can be used as a Java library or be controlled through a user friendly web interface. - * - * This version is developed by the DECIDE team from the Lab-STICC (CNRS) and by the Mixt Research Unit in Environmental Acoustics (Université Gustave Eiffel). - * - * - * NoiseModelling is distributed under GPL 3 license. You can read a copy of this License in the file LICENCE provided with this software. - * - * Contact: contact@noise-planet.org - * - */ -package org.noise_planet.noisemodelling.runner; - -import groovy.lang.GroovyShell; -import groovy.lang.Script; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.log4j.Level; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.RollingFileAppender; -import org.h2.util.OsgiDataSourceFactory; -import org.h2gis.functions.factory.H2GISFunctions; -import org.h2gis.utilities.wrapper.ConnectionWrapper; -import org.noise_planet.noisemodelling.pathfinder.utils.profiler.RootProgressVisitor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.sql.DataSource; -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.sql.Connection; -import java.sql.SQLException; -import java.text.NumberFormat; -import java.sql.Statement; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; -import java.util.jar.Attributes; -import java.util.jar.Manifest; - -import org.osgi.service.jdbc.DataSourceFactory; - - -public class Main { - public static final int SECONDS_BETWEEN_PROGRESSION_PRINT = 5; - - - public static DataSource createDataSource(String user, String password, String dbDirectory, String dbName, boolean debug) throws SQLException { - // Create H2 memory DataSource - org.h2.Driver driver = org.h2.Driver.load(); - OsgiDataSourceFactory dataSourceFactory = new OsgiDataSourceFactory(driver); - Properties properties = new Properties(); - String databasePath = "jdbc:h2:" + new File(dbDirectory, dbName).getAbsolutePath(); - properties.setProperty(DataSourceFactory.JDBC_URL, databasePath); - properties.setProperty(DataSourceFactory.JDBC_USER, user); - properties.setProperty(DataSourceFactory.JDBC_PASSWORD, password); - if(debug) { - properties.setProperty("TRACE_LEVEL_FILE", "3"); // enable debug - } - DataSource dataSource = dataSourceFactory.createDataSource(properties); - // Init spatial ext - try (Connection connection = dataSource.getConnection()) { - H2GISFunctions.load(connection); - } - return dataSource; - - } - - public static void printBuildIdentifiers(Logger logger) { - try { - String columnFormat = "%-35.35s %-35.35s %-20.20s %-30.30s"; - String[] columns = new String[] {"name", "last-modified", "version", "commit"}; - Enumeration resources = Main.class.getClassLoader().getResources("META-INF/MANIFEST.MF"); - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append( "Loaded libraries:\n"); - stringBuilder.append(String.format(Locale.ROOT, columnFormat, - (Object[]) columns)); - stringBuilder.append( "\n"); - Map> rows = new HashMap<>(); - for (String column : columns) { - rows.put(column, new ArrayList<>()); - } - SimpleDateFormat simpleDateFormat = new SimpleDateFormat( - "EEE, d MMM yyyy HH:mm:ss Z", Locale.getDefault()); - int nbRows = 0; - while (resources.hasMoreElements()) { - try { - Manifest manifest = new Manifest(resources.nextElement().openStream()); - Attributes attributes = manifest.getMainAttributes(); - String bundleName = attributes.getValue("Bundle-Name"); - String bundleVersion = attributes.getValue("Bundle-Version"); - String gitCommitId = attributes.getValue("Implementation-Build"); - String lastModifier = attributes.getValue("Bnd-LastModified"); - if(bundleName != null) { - nbRows++; - rows.get(columns[0]).add(bundleName); - if(lastModifier != null) { - long lastModifiedLong = Long.parseLong(lastModifier); - rows.get(columns[1]).add(simpleDateFormat.format(new Date(lastModifiedLong))); - } else { - rows.get(columns[1]).add(" - "); - } - rows.get(columns[2]).add(bundleVersion != null ? bundleVersion : " - "); - rows.get(columns[3]).add(gitCommitId != null ? gitCommitId : " - "); - } - } catch (IOException ex) { - logger.error(ex.getLocalizedMessage(), ex); - } - } - for(int idRow = 0; idRow < nbRows; idRow++) { - String[] rowValues = new String[columns.length]; - for (int idColumn = 0; idColumn < columns.length; idColumn++) { - String column = columns[idColumn]; - rowValues[idColumn] = rows.get(column).get(idRow); - } - stringBuilder.append(String.format(Locale.ROOT, columnFormat, - (Object[]) rowValues)); - stringBuilder.append("\n"); - } - logger.info(stringBuilder.toString()); - } catch (IOException ex) { - logger.error("Error while accessing resources", ex); - } - } - - - public static void main(String... args) throws Exception { - PropertyConfigurator.configure(Main.class.getResource("log4j.properties")); - - // Arguments parser - Options options = new Options(); - Option workingDirOption = new Option("w", "working-dir", true, "Path where the database will be located"); - workingDirOption.setRequired(true); - workingDirOption.setArgName("folder path"); - options.addOption(workingDirOption); - Option scriptPathOption = new Option("s", "script", true, "Path and file name of the script"); - scriptPathOption.setRequired(true); - scriptPathOption.setArgName("script path"); - options.addOption(scriptPathOption); - Option databaseNameOption = new Option("d", "database-name", true, "Database name (default to h2gisdb)"); - options.addOption(databaseNameOption); - Option printVersionOption = new Option("v", false,"Print version of all libraries"); - options.addOption(printVersionOption); - Option shutdownOption = new Option("c", "shutdown" ,false,"Do not shutdown compact the database at the end of the execution"); - options.addOption(shutdownOption); - Logger logger = LoggerFactory.getLogger("org.noise_planet"); - try { - // Read parameters - String workingDir = ""; - String scriptPath = ""; - String databaseName = ""; - Map customParameters = new HashMap<>(); - boolean printVersion = false; - - CommandLineParser commandLineParser = new DefaultParser(); - HelpFormatter helpFormatter = new HelpFormatter(); - CommandLine commandLine; - try { - commandLine = commandLineParser.parse(options, args, true); - } catch (ParseException ex) { - logger.info(ex.getMessage()); - helpFormatter.printHelp("NoiseModelling Script Runner", options); - System.exit(1); - return; - } - workingDir = commandLine.getOptionValue(workingDirOption.getOpt()); - scriptPath = commandLine.getOptionValue(scriptPathOption.getOpt()); - printVersion = commandLine.hasOption(printVersionOption.getOpt()); - databaseName = commandLine.getOptionValue(databaseNameOption.getOpt(), "h2gisdb"); - boolean shutdown = !commandLine.hasOption(shutdownOption.getOpt()); - - if(printVersion) { - printBuildIdentifiers(logger); - } - - // configure file logger - try { - // Create rolling file appender - RollingFileAppender rollingAppender = new RollingFileAppender(); - - // Configure appender properties - rollingAppender.setName("rollingFile"); - rollingAppender.setFile(new File(workingDir, "application.log").getPath()); - rollingAppender.setAppend(true); - rollingAppender.setMaxBackupIndex(5); - rollingAppender.setMaximumFileSize(10_000_000); - - // Create and set pattern layout - PatternLayout layout = new PatternLayout("[%t] %-5p %d{dd MMM HH:mm:ss} - %m%n"); - rollingAppender.setLayout(layout); - - // init stream - rollingAppender.activateOptions(); - - // Configure root logger - org.apache.log4j.Logger rootLogger = org.apache.log4j.Logger.getRootLogger(); - rootLogger.addAppender(rollingAppender); - } catch (Exception e) { - System.err.println("Failed to configure logger: " + e.getMessage()); - } - - // Open database - DataSource ds = createDataSource("", "", new File(workingDir).getAbsolutePath(), databaseName, false); - - RootProgressVisitor progressVisitor = new RootProgressVisitor(1, true, - SECONDS_BETWEEN_PROGRESSION_PRINT); - - try (Connection connection = new ConnectionWrapper(ds.getConnection())) { - GroovyShell shell = new GroovyShell(); - Script script= shell.parse(new File(scriptPath)); - script.run(); - if(shell.getVariable("inputs") == null) { - throw new IllegalArgumentException("Script does not contains inputs variable"); - } - ((Map) shell.getVariable("inputs")).forEach((key, value) -> { - Map optionAttributes = ((Map)value); - Option customOption = new Option(key.toString(), - optionAttributes.get("type") != Boolean.class, - optionAttributes.getOrDefault("description", ""). - toString().replaceAll("<[^>]*>", "")); - customOption.setType((Class)optionAttributes.get("type")); - customOption.setArgs(1); - customOption.setArgName(optionAttributes.get("name").toString()); - customOption.setRequired(!optionAttributes.containsKey("min") || (Integer)optionAttributes.get("min") == 1); - options.addOption(customOption); - }); - try { - commandLine = commandLineParser.parse(options, args); - for (Iterator