Compare commits
4 Commits
2dd955ee70
...
7d9580965f
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d9580965f | |||
| 3e54ae8f23 | |||
| e7956db333 | |||
| 65a8601ea1 |
88
.gitignore
vendored
88
.gitignore
vendored
@@ -1,3 +1,91 @@
|
|||||||
|
# Covers JetBrains IDEs: IntelliJ, GoLand, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# AWS User-specific
|
||||||
|
.idea/**/aws.xml
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# SonarLint plugin
|
||||||
|
.idea/sonarlint/
|
||||||
|
.idea/sonarlint.xml # see https://community.sonarsource.com/t/is-the-file-idea-idea-idea-sonarlint-xml-intended-to-be-under-source-control/121119
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based HTTP Client
|
||||||
|
.idea/httpRequests
|
||||||
|
http-client.private.env.json
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
# Apifox Helper cache
|
||||||
|
.idea/.cache/.Apifox_Helper
|
||||||
|
.idea/ApifoxUploaderProjectSetting.xml
|
||||||
|
|
||||||
|
# Github Copilot persisted session migrations, see: https://github.com/microsoft/copilot-intellij-feedback/issues/712#issuecomment-3322062215
|
||||||
|
.idea/**/copilot.data.migration.*.xml
|
||||||
|
|
||||||
# ---> Java
|
# ---> Java
|
||||||
# Compiled class file
|
# Compiled class file
|
||||||
*.class
|
*.class
|
||||||
|
|||||||
10
.idea/.gitignore
generated
vendored
Normal file
10
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Ignored default folder with query files
|
||||||
|
/queries/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
13
.idea/compiler.xml
generated
Normal file
13
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<annotationProcessing>
|
||||||
|
<profile name="Maven default annotation processors profile" enabled="true">
|
||||||
|
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||||
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||||
|
<outputRelativeToContentRoot value="true" />
|
||||||
|
<module name="teren-funkcje" />
|
||||||
|
</profile>
|
||||||
|
</annotationProcessing>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
7
.idea/encodings.xml
generated
Normal file
7
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding">
|
||||||
|
<file url="file://$PROJECT_DIR$" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
25
.idea/jarRepositories.xml
generated
Normal file
25
.idea/jarRepositories.xml
generated
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RemoteRepositoriesConfiguration">
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="nexus-homelab" />
|
||||||
|
<option name="name" value="nexus-homelab" />
|
||||||
|
<option name="url" value="https://nexus.rulka.pl/repository/maven-public/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="central" />
|
||||||
|
<option name="name" value="Maven Central repository" />
|
||||||
|
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="central" />
|
||||||
|
<option name="name" value="Central Repository" />
|
||||||
|
<option name="url" value="https://nexus.rulka.pl/repository/maven-public/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="jboss.community" />
|
||||||
|
<option name="name" value="JBoss Community repository" />
|
||||||
|
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||||
|
</remote-repository>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
14
.idea/misc.xml
generated
Normal file
14
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="MavenProjectsManager">
|
||||||
|
<option name="originalFiles">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/pom.xml" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="jdk-25.0.2-sim" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/terrain-utilities.iml" filepath="$PROJECT_DIR$/.idea/terrain-utilities.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
9
.idea/terrain-utilities.iml
generated
Normal file
9
.idea/terrain-utilities.iml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
55
log4j.properties
Normal file
55
log4j.properties
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#Glowny logger, pierwsza wartosc to poziom logowania
|
||||||
|
#Logowane sa zdarzenia o poziomie wiekszym lub rownym danemu
|
||||||
|
#Hierarchia poziomow to: DEBUG<INFO<WARN<ERROR<FATAL
|
||||||
|
#Po przecinku, rozdzielane przecinakmi appendery, moze byc ich wiecej niz jeden, wtedy logi zapisuje sie w kilka miejsc
|
||||||
|
#Nie ma problemu, aby zapisywac np. do trzech roznych plikow i na konsole
|
||||||
|
#Appendery rozrozniane sa po nazwach, nazwy nadajemy sami, potem wykorzystujemy je w definicji appenderow
|
||||||
|
#
|
||||||
|
#Ustawilem dla calosci logowanie od DEBUG w gore.
|
||||||
|
log4j.rootLogger=DEBUG, Konsola
|
||||||
|
#Appendery tworza hierarchie, na gorze jest rootLogger, potem loggery maja hierarchie mniej wiecej jak pakiety w javie
|
||||||
|
#np. logger: pl
|
||||||
|
# ^
|
||||||
|
# / \
|
||||||
|
# |
|
||||||
|
# |
|
||||||
|
# pl.edu
|
||||||
|
# Jezeli w pliku konfiguracyjnym znajduje sie definicja np. log4j.logger.pl.wat.wcy=WARN, Konsola to zostanie ona uzyta
|
||||||
|
# , ale jezeli jest tez definicja log4j.logger.pl.wat.wcy.au2=INFO - to wybrana bedzie ta, czyli taka, co najbardziej pasuje
|
||||||
|
# w definicji loggera mozna podac, jaki poziom logowac, mozna tez podawac appendery, tylko tu uwaga,
|
||||||
|
# zadzialaja wszystkie appendery w hierarchii, czyli dla konfiguracji
|
||||||
|
# log4j.logger.pl.wat.wcy.au2=INFO, Konsola
|
||||||
|
# log4j.logger.pl.wat.wcy=INFO, Konsola
|
||||||
|
# zdarzenie logowania dla zdefiniowanego wczesniej logowania o poziomie, np. warn, wypisane bedzie na konsoli dwa razy
|
||||||
|
#
|
||||||
|
#Ustawilem dla mojego pakietu logowanie wszystkiego.
|
||||||
|
log4j.logger.pl.wat.wcy.mip=WARN
|
||||||
|
log4j.logger.pl.wat.wcy.db=DEBUG
|
||||||
|
log4j.logger.pl.wat.wcy.au2krok=DEBUG
|
||||||
|
log4j.logger.pl.wat.wcy.au2krok.JednostkaSym=TRACE
|
||||||
|
log4j.logger.pl.wat.wcy.au2krok.JednostkaZaop=DEBUG
|
||||||
|
log4j.logger.pl.wat.wcy.warstwy=DEBUG
|
||||||
|
log4j.logger.pl.wat.wcy.au2=DEBUG
|
||||||
|
#log4j.logger.pl.wat.wcy.au2.gui=DEBUG
|
||||||
|
|
||||||
|
#Appender zrzucajacy logi do pliku-----------------------------------------
|
||||||
|
log4j.appender.Plik=org.apache.log4j.FileAppender
|
||||||
|
#Od jakiego poziomu ten appender bedzie dzialac, czyli tu do pliku zapisywane beda dane o poziomie ERROR i FATAL
|
||||||
|
log4j.appender.Plik.threshold=TRACE
|
||||||
|
#Nazwa pliku dziennika
|
||||||
|
#log4j.appender.XXXX.parametr=wartosc - gdzie XXXX to nazwa naszego appendera, my ja wymyslamy, obowiazuje w ramach konfiguracji w tym pliku
|
||||||
|
log4j.appender.Plik.File=log.txt
|
||||||
|
log4j.appender.Plik.layout=org.apache.log4j.PatternLayout
|
||||||
|
#Format zrzucanych informacji (odsylam do manuala w kwestii definicji mozliwych do zastosowania znacznikow)
|
||||||
|
#Uzycie niektorych znacznikow potrafi drastycznie zmniejszyc wydajnosc zapisu do dziennikow.
|
||||||
|
log4j.appender.Plik.layout.ConversionPattern=[%-5p] %d - %m%n
|
||||||
|
|
||||||
|
#Appender zapisujacy dane logowania na konsole-----------------------------
|
||||||
|
log4j.appender.Konsola=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.Konsola.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.Konsola.layout.ConversionPattern=[%-5p] %d - %m%n
|
||||||
|
#W pliku moze byc zdefiniowana dowolna liczba appenderow, moga byc niewykorzystywane
|
||||||
|
log4j.appender.Konsola2=org.apache.log4j.ConsoleAppender
|
||||||
|
#log4j.appender.Konsola2.threshold=DEBUG
|
||||||
|
log4j.appender.Konsola2.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.Konsola2.layout.ConversionPattern=[%-5p] %l - %m%n
|
||||||
24
logback.xml
Normal file
24
logback.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<!-- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>-->
|
||||||
|
<pattern>%-30(%d{HH:mm:ss.SSS} [%thread]) %-5level %logger{32} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||||
|
<file>terrain.log</file>
|
||||||
|
<append>true</append>
|
||||||
|
<encoder>
|
||||||
|
<!-- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>-->
|
||||||
|
<pattern>%-30(%d{HH:mm:ss.SSS} [%thread]) %-5level %logger{32} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<logger name="pl.wat.ms4ds.terenfunkcje" level="trace">
|
||||||
|
<appender-ref ref="FILE"/>
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<root level="trace">
|
||||||
|
<appender-ref ref="STDOUT"/>
|
||||||
|
</root>
|
||||||
|
</configuration>
|
||||||
183
pom.xml
Normal file
183
pom.xml
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>ms4ds</groupId>
|
||||||
|
<artifactId>teren-funkcje</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>nexus-homelab</id>
|
||||||
|
<name>nexus-homelab</name>
|
||||||
|
<url>https://nexus.rulka.pl/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>${basedir}</directory>
|
||||||
|
<includes>
|
||||||
|
<include>*.properties</include>
|
||||||
|
<include>logback.xml</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.14.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>25</source>
|
||||||
|
<target>25</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<version>3.4.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-sources</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.12.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-javadocs</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!--/JR Generowanie aplikacji-->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<version>3.9.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-dependencies</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/teren/lib</outputDirectory>
|
||||||
|
<overWriteReleases>false</overWriteReleases>
|
||||||
|
<overWriteSnapshots>false</overWriteSnapshots>
|
||||||
|
<overWriteIfNewer>true</overWriteIfNewer>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/teren/lib</outputDirectory>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<mainClass>pl.wat.ms4ds.terenfunkcje.nmt.NMTDataProvider</mainClass>
|
||||||
|
</manifest>
|
||||||
|
<manifestEntries>
|
||||||
|
<Class-Path>teren-funkcje-1.0.2-SNAPSHOT.jar</Class-Path>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.4.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-resources-runbat</id>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-resources</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/teren/lib</outputDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>${basedir}</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<include>*.properties</include>
|
||||||
|
<include>*.bat</include>
|
||||||
|
<include>*.xml</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<!--/JR Generowanie aplikacji-->
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<distributionManagement>
|
||||||
|
<snapshotRepository>
|
||||||
|
<id>nexus-snapshots</id>
|
||||||
|
<url>https://nexus.rulka.pl/repository/maven-snapshots/</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
<repository>
|
||||||
|
<id>nexus-releases</id>
|
||||||
|
<url>https://nexus.rulka.pl/repository/maven-releases/</url>
|
||||||
|
</repository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ms4ds</groupId>
|
||||||
|
<artifactId>common-types</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>log4j</groupId>-->
|
||||||
|
<!-- <artifactId>log4j</artifactId>-->
|
||||||
|
<!-- <version>1.2.17</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-core</artifactId>
|
||||||
|
<version>1.5.20</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>1.5.20</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>2.0.17</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.nocrala</groupId>
|
||||||
|
<artifactId>shapefilereader</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
338
src/main/java/pl/wat/ms4ds/terenfunkcje/AStar.java
Normal file
338
src/main/java/pl/wat/ms4ds/terenfunkcje/AStar.java
Normal file
@@ -0,0 +1,338 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
import pl.wat.ms4ds.common.EGeoDirection;
|
||||||
|
import pl.wat.ms4ds.common.ERodzajDzialania;
|
||||||
|
import pl.wat.ms4ds.common.ERodzajPodwozia;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public final class AStar {
|
||||||
|
|
||||||
|
private static class Node {
|
||||||
|
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
boolean koncowy;
|
||||||
|
boolean zamkniety;
|
||||||
|
double kosztOdStartu;
|
||||||
|
double kosztZHeurystyka;
|
||||||
|
Node poprzednik;
|
||||||
|
EGeoDirection zKierunku;
|
||||||
|
|
||||||
|
private static Hashtable<Node, Node> allNodes = new Hashtable<>();
|
||||||
|
private static Node roboczy = new Node(0, 0);
|
||||||
|
|
||||||
|
static Node dajAStarNode(int x, int y) {
|
||||||
|
if (x < 0 || y < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
roboczy.x = x;
|
||||||
|
roboczy.y = y;
|
||||||
|
Node node = allNodes.get(roboczy);
|
||||||
|
if (node == null) {
|
||||||
|
node = new Node(x, y);
|
||||||
|
allNodes.put(node, node);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Node dajAStarNode(GridCoord gridCoord) {
|
||||||
|
return dajAStarNode(gridCoord.x, gridCoord.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<Node> dajNiezamknietychSasiadow() {
|
||||||
|
ArrayList<Node> wynik = new ArrayList<>();
|
||||||
|
Node sasiad;
|
||||||
|
sasiad = Node.dajAStarNode(this.x - 1, this.y - 1);
|
||||||
|
if (null != sasiad && !sasiad.zamkniety)
|
||||||
|
wynik.add(sasiad);
|
||||||
|
sasiad = Node.dajAStarNode(this.x - 1, this.y);
|
||||||
|
if (null != sasiad && !sasiad.zamkniety)
|
||||||
|
wynik.add(sasiad);
|
||||||
|
sasiad = Node.dajAStarNode(this.x - 1, this.y + 1);
|
||||||
|
if (null != sasiad && !sasiad.zamkniety)
|
||||||
|
wynik.add(sasiad);
|
||||||
|
sasiad = Node.dajAStarNode(this.x, this.y - 1);
|
||||||
|
if (null != sasiad && !sasiad.zamkniety)
|
||||||
|
wynik.add(sasiad);
|
||||||
|
sasiad = Node.dajAStarNode(this.x, this.y + 1);
|
||||||
|
if (null != sasiad && !sasiad.zamkniety)
|
||||||
|
wynik.add(sasiad);
|
||||||
|
sasiad = Node.dajAStarNode(this.x + 1, this.y - 1);
|
||||||
|
if (null != sasiad && !sasiad.zamkniety)
|
||||||
|
wynik.add(sasiad);
|
||||||
|
sasiad = Node.dajAStarNode(this.x + 1, this.y);
|
||||||
|
if (null != sasiad && !sasiad.zamkniety)
|
||||||
|
wynik.add(sasiad);
|
||||||
|
sasiad = Node.dajAStarNode(this.x + 1, this.y + 1);
|
||||||
|
if (null != sasiad && !sasiad.zamkniety)
|
||||||
|
wynik.add(sasiad);
|
||||||
|
return wynik;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset() {
|
||||||
|
allNodes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Node(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
koncowy = false;
|
||||||
|
zamkniety = false;
|
||||||
|
kosztOdStartu = 0.0;
|
||||||
|
kosztZHeurystyka = Double.MAX_VALUE;
|
||||||
|
poprzednik = null;
|
||||||
|
zKierunku = EGeoDirection.UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node(GridCoord id) {
|
||||||
|
this(id.x, id.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AStarNode{" +
|
||||||
|
"x=" + x +
|
||||||
|
", y=" + y +
|
||||||
|
", koncowy=" + koncowy +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = prime + x;
|
||||||
|
result = prime * result + y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (obj instanceof Node other) {
|
||||||
|
if (x != other.x) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return y == other.y;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja wyznacza drogę po sąsiednich kwadratach przechodzącą przez punkty profilujące punktyProfilujace
|
||||||
|
*
|
||||||
|
* @param punktyProfilujace punkty profilujące drogę (droga musi je zawierać)
|
||||||
|
* @param staryKierunek kierunek z którego osiągnięto punkt startowy (1. punkt profilujący)
|
||||||
|
* @param podwozie rodzaj podwozia
|
||||||
|
* @param rodzajDzialania rodzaj działania, w ramach którego określana jest droga
|
||||||
|
* @return uporządkowana kolekcja współrzędnych kolejnych kwadratów drogi zawierająca kwadrat startowy i docelowy lub kolekcja pusta, gdy nie istnieje droga
|
||||||
|
*/
|
||||||
|
public static ArrayList<GridCoord> wyznaczDroge(GridCoord[] punktyProfilujace, EGeoDirection staryKierunek,
|
||||||
|
ERodzajPodwozia podwozie, ERodzajDzialania rodzajDzialania) {
|
||||||
|
if (null == punktyProfilujace || 0 == punktyProfilujace.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Node.reset();
|
||||||
|
ArrayList<GridCoord> wynik = new ArrayList<>();
|
||||||
|
GridCoord start;
|
||||||
|
GridCoord stop = punktyProfilujace[0];
|
||||||
|
ArrayList<GridCoord> odcinek;
|
||||||
|
for (int i = 1; i < punktyProfilujace.length; i++) {
|
||||||
|
start = stop;
|
||||||
|
stop = punktyProfilujace[i];
|
||||||
|
EGeoDirection staryKier;
|
||||||
|
if (wynik.size() > 1) {
|
||||||
|
staryKier = GeomUtils.kierunekDlaSasiada(wynik.get(wynik.size() - 2), wynik.get(wynik.size() - 1));
|
||||||
|
} else {
|
||||||
|
staryKier = staryKierunek;
|
||||||
|
}
|
||||||
|
if (i == 1) {
|
||||||
|
odcinek = wyznaczDroge(start, stop, staryKier, true, podwozie, rodzajDzialania);
|
||||||
|
} else {
|
||||||
|
odcinek = wyznaczDroge(start, stop, staryKier, false, podwozie, rodzajDzialania);
|
||||||
|
}
|
||||||
|
if (odcinek.size() == 0) {
|
||||||
|
// gdy nie istnieje droga między danymi punktami profilującymi, to zwracam kolekcję pustą
|
||||||
|
return odcinek;
|
||||||
|
}
|
||||||
|
wynik.addAll(odcinek);
|
||||||
|
Node.reset();
|
||||||
|
}
|
||||||
|
return wynik;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja wyznacza drogę po sąsiednich kwadratach od kwadratu startowego start do docelowego stop
|
||||||
|
*
|
||||||
|
* @param start współrzędne kwadratu startowego
|
||||||
|
* @param stop współrzędne kwadratu docelowego
|
||||||
|
* @param staryKierunek kierunek z którego osiągnięto punkt startowy (1. punkt profilujący)
|
||||||
|
* @param podwozie rodzaj podwozia
|
||||||
|
* @param rodzajDzialania rodzaj działania, w ramach którego określana jest droga
|
||||||
|
* @param zawieraStartowy parametr wskazujący, czy wyznaczona droga ma zawierać kwadrat startowy
|
||||||
|
* @return uporządkowana kolekcja współrzędnych kolejnych kwadratów drogi zawierająca kwadrat startowy (jeśli zawieraStartowy==true) i docelowy lub kolekcja pusta, gdy nie istnieje droga
|
||||||
|
*/
|
||||||
|
public static ArrayList<GridCoord> wyznaczDroge(GridCoord start, GridCoord stop, EGeoDirection staryKierunek,
|
||||||
|
boolean zawieraStartowy, ERodzajPodwozia podwozie, ERodzajDzialania rodzajDzialania) {
|
||||||
|
|
||||||
|
PriorityQueue<Node> listaOtwarta = new PriorityQueue<>(100, (o1, o2) -> Double.compare(o1.kosztZHeurystyka, o2.kosztZHeurystyka));
|
||||||
|
boolean naPrzelaj = false;
|
||||||
|
switch (rodzajDzialania) {
|
||||||
|
case DZIALANIE_ATAK:
|
||||||
|
case DZIALANIE_MAGIC_MOVEMENT:
|
||||||
|
case DZIALANIE_OBRONA:
|
||||||
|
case DZIALANIE_OPL:
|
||||||
|
case DZIALANIE_WRIA:
|
||||||
|
case DZIALANIE_ROZMIESZCZENIE:
|
||||||
|
case DZIALANIE_ZESRODKOWANIE:
|
||||||
|
case DZIALANIE_MINOWANIE:
|
||||||
|
naPrzelaj = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
Node aktualny = Node.dajAStarNode(stop.x, stop.y);
|
||||||
|
aktualny.koncowy = true;
|
||||||
|
ArrayList<Node> sasiedzi;
|
||||||
|
aktualny = Node.dajAStarNode(start.x, start.y);
|
||||||
|
aktualny.zKierunku = staryKierunek;
|
||||||
|
listaOtwarta.add(aktualny);
|
||||||
|
ArrayList<GridCoord> wynik = new ArrayList<GridCoord>();
|
||||||
|
int licznik_zabezpieczajacy = 200000;
|
||||||
|
while (listaOtwarta.size() > 0 && licznik_zabezpieczajacy-- > 0) {
|
||||||
|
aktualny = listaOtwarta.remove();
|
||||||
|
if (aktualny.koncowy) {
|
||||||
|
while (null != aktualny) {
|
||||||
|
wynik.add(new GridCoord(aktualny.x, aktualny.y));
|
||||||
|
aktualny = aktualny.poprzednik;
|
||||||
|
}
|
||||||
|
if (!zawieraStartowy) {
|
||||||
|
//Usuwam poczatek drogi
|
||||||
|
wynik.remove(wynik.size() - 1);
|
||||||
|
}
|
||||||
|
Collections.reverse(wynik);
|
||||||
|
return wynik;
|
||||||
|
}
|
||||||
|
sasiedzi = aktualny.dajNiezamknietychSasiadow();
|
||||||
|
for (Node sasiad : sasiedzi) {
|
||||||
|
double stopienPrzejezdnosci = Teren.getStopienPrzejezdnosci(aktualny.x, aktualny.y, sasiad.x, sasiad.y,
|
||||||
|
aktualny.zKierunku, podwozie);
|
||||||
|
if (stopienPrzejezdnosci < 0.005f) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (naPrzelaj) {
|
||||||
|
stopienPrzejezdnosci = Math.max(Teren.minStopienPrzejezdNaPrzelaj, stopienPrzejezdnosci);
|
||||||
|
}
|
||||||
|
double nowyKosztOdStartu = (float) aktualny.kosztOdStartu + GridCoord.odleglosc(aktualny.x, aktualny.y, sasiad.x, sasiad.y) / stopienPrzejezdnosci;
|
||||||
|
double nowyKosztZHeurystyka = nowyKosztOdStartu + GridCoord.odleglosc(sasiad.x, sasiad.y, stop.x, stop.y);
|
||||||
|
if (sasiad.kosztZHeurystyka > nowyKosztZHeurystyka) {
|
||||||
|
//UPDATE kosztow i zmiany w kolejce
|
||||||
|
sasiad.kosztOdStartu = nowyKosztOdStartu;
|
||||||
|
sasiad.kosztZHeurystyka = nowyKosztZHeurystyka;
|
||||||
|
sasiad.poprzednik = aktualny;
|
||||||
|
sasiad.zKierunku = GeomUtils.kierunekDlaSasiada(aktualny.x, aktualny.y, sasiad.x, sasiad.y);
|
||||||
|
listaOtwarta.remove(sasiad);
|
||||||
|
listaOtwarta.add(sasiad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aktualny.zamkniety = true;
|
||||||
|
}
|
||||||
|
return wynik;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja wyznacza drogę po sąsiednich kwadratach od kwadratu startowego start do docelowego stop
|
||||||
|
*
|
||||||
|
* @param start współrzędne kwadratu startowego
|
||||||
|
* @param stop współrzędne kwadratu docelowego
|
||||||
|
* @param staryKierunek kierunek z którego osiągnięto punkt startowy (1. punkt profilujący)
|
||||||
|
* @param podwozie rodzaj podwozia
|
||||||
|
* @param rodzajDzialania rodzaj działania, w ramach którego określana jest droga
|
||||||
|
* @param zawieraStartowy parametr wskazujący, czy wyznaczona droga ma zawierać kwadrat startowy
|
||||||
|
* @return uporządkowana kolekcja współrzędnych kolejnych kwadratów drogi zawierająca kwadrat startowy (jeśli zawieraStartowy==true) i docelowy lub kolekcja pusta, gdy nie istnieje droga
|
||||||
|
*/
|
||||||
|
public static ArrayList<GridCoord> wyznaczDrogeNew(GridCoord start, GridCoord stop, EGeoDirection staryKierunek,
|
||||||
|
boolean zawieraStartowy, ERodzajPodwozia podwozie,
|
||||||
|
ERodzajDzialania rodzajDzialania,
|
||||||
|
double szerokoscPokonywRowow,
|
||||||
|
double glebokoscBrodzenia,
|
||||||
|
double predkoscPlywania) {
|
||||||
|
PriorityQueue<Node> listaOtwarta = new PriorityQueue<>(100, new Comparator<Node>() {
|
||||||
|
public int compare(Node o1, Node o2) {
|
||||||
|
return Double.compare(o1.kosztZHeurystyka, o2.kosztZHeurystyka);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// PriorityQueue<AStarNode> listaOtwarta = new PriorityQueue<>(100, (AStarNode o1, AStarNode o2) -> Double.compare(o1.kosztZHeurystyka, o2.kosztZHeurystyka));
|
||||||
|
boolean naPrzelaj = false;
|
||||||
|
switch (rodzajDzialania) {
|
||||||
|
case DZIALANIE_ATAK:
|
||||||
|
case DZIALANIE_MAGIC_MOVEMENT:
|
||||||
|
case DZIALANIE_OBRONA:
|
||||||
|
case DZIALANIE_OPL:
|
||||||
|
case DZIALANIE_WRIA:
|
||||||
|
case DZIALANIE_ROZMIESZCZENIE:
|
||||||
|
case DZIALANIE_ZESRODKOWANIE:
|
||||||
|
case DZIALANIE_MINOWANIE:
|
||||||
|
naPrzelaj = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
Node aktualny = Node.dajAStarNode(stop.x, stop.y);
|
||||||
|
aktualny.koncowy = true;
|
||||||
|
ArrayList<Node> sasiedzi;
|
||||||
|
aktualny = Node.dajAStarNode(start.x, start.y);
|
||||||
|
aktualny.zKierunku = staryKierunek;
|
||||||
|
listaOtwarta.add(aktualny);
|
||||||
|
ArrayList<GridCoord> wynik = new ArrayList<GridCoord>();
|
||||||
|
int licznik_zabezpieczajacy = 200000;
|
||||||
|
while (listaOtwarta.size() > 0 && licznik_zabezpieczajacy-- > 0) {
|
||||||
|
aktualny = listaOtwarta.remove();
|
||||||
|
if (aktualny.koncowy) {
|
||||||
|
while (null != aktualny) {
|
||||||
|
wynik.add(new GridCoord(aktualny.x, aktualny.y));
|
||||||
|
aktualny = aktualny.poprzednik;
|
||||||
|
}
|
||||||
|
if (!zawieraStartowy) {
|
||||||
|
//Usuwam poczatek drogi
|
||||||
|
wynik.remove(wynik.size() - 1);
|
||||||
|
}
|
||||||
|
Collections.reverse(wynik);
|
||||||
|
return wynik;
|
||||||
|
}
|
||||||
|
sasiedzi = aktualny.dajNiezamknietychSasiadow();
|
||||||
|
for (Node sasiad : sasiedzi) {
|
||||||
|
double stopienPrzejezdnosci = Teren.getStopienPrzejezdnosciNew(aktualny.x, aktualny.y, sasiad.x, sasiad.y,
|
||||||
|
aktualny.zKierunku, podwozie, szerokoscPokonywRowow, glebokoscBrodzenia, predkoscPlywania);
|
||||||
|
if (stopienPrzejezdnosci < 0.005f) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (naPrzelaj) {
|
||||||
|
stopienPrzejezdnosci = Math.max(Teren.minStopienPrzejezdNaPrzelaj, stopienPrzejezdnosci);
|
||||||
|
}
|
||||||
|
double nowyKosztOdStartu = (float) aktualny.kosztOdStartu + GridCoord.odleglosc(aktualny.x, aktualny.y, sasiad.x, sasiad.y) / stopienPrzejezdnosci;
|
||||||
|
double nowyKosztZHeurystyka = nowyKosztOdStartu + GridCoord.odleglosc(sasiad.x, sasiad.y, stop.x, stop.y);
|
||||||
|
if (sasiad.kosztZHeurystyka > nowyKosztZHeurystyka) {
|
||||||
|
//UPDATE kosztow i zmiany w kolejce
|
||||||
|
sasiad.kosztOdStartu = nowyKosztOdStartu;
|
||||||
|
sasiad.kosztZHeurystyka = nowyKosztZHeurystyka;
|
||||||
|
sasiad.poprzednik = aktualny;
|
||||||
|
sasiad.zKierunku = GeomUtils.kierunekDlaSasiada(aktualny.x, aktualny.y, sasiad.x, sasiad.y);
|
||||||
|
listaOtwarta.remove(sasiad);
|
||||||
|
listaOtwarta.add(sasiad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aktualny.zamkniety = true;
|
||||||
|
}
|
||||||
|
return wynik;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
src/main/java/pl/wat/ms4ds/terenfunkcje/Arkusz.java
Normal file
35
src/main/java/pl/wat/ms4ds/terenfunkcje/Arkusz.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class Arkusz {
|
||||||
|
|
||||||
|
ArrayList<WezelDrogowy> wezly = new ArrayList<>();
|
||||||
|
// arkusz mapy zawiera luki rozlacznie (jeden luk moze nalezec tylko do jednego arkusza)
|
||||||
|
ArrayList<LukDrogowy> luki = new ArrayList<>();
|
||||||
|
|
||||||
|
// liczba arkuszy mapy
|
||||||
|
static int lx = 0;
|
||||||
|
static int ly = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja porownuje wspolrzedne leksykograficznie.
|
||||||
|
* @param x1
|
||||||
|
* @param y1
|
||||||
|
* @param x2
|
||||||
|
* @param y2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static boolean mniejszeWspolrzedne(int x1, int y1, int x2, int y2) {
|
||||||
|
if (x1 < x2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (x1 > x2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (y1 < y2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/main/java/pl/wat/ms4ds/terenfunkcje/BigSquare.java
Normal file
12
src/main/java/pl/wat/ms4ds/terenfunkcje/BigSquare.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
abstract class BigSquare {
|
||||||
|
abstract Kwadrat getKwadrat(int Id_X, int Id_Y);
|
||||||
|
|
||||||
|
protected transient String fileName;
|
||||||
|
public int xRefMs = 0;
|
||||||
|
public int yRefMs = 0;
|
||||||
|
public transient int liczbaZmian = 0;
|
||||||
|
// TODO zamienic na 100
|
||||||
|
static final int LICZBA_ZMIAN_DO_ZAPISU = 100000;
|
||||||
|
}
|
||||||
152
src/main/java/pl/wat/ms4ds/terenfunkcje/Bresenham.java
Normal file
152
src/main/java/pl/wat/ms4ds/terenfunkcje/Bresenham.java
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Klasa algorytmiczna do wyznaczania kwadratów odcinka (dyskretyzacja odcinka kwadratami/pikselami).
|
||||||
|
*/
|
||||||
|
public class Bresenham {
|
||||||
|
|
||||||
|
static int sign(int a) {
|
||||||
|
if (a > 0)
|
||||||
|
return 1;
|
||||||
|
if (a < 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metoda generuje tablicę współrzędnych gridowych kolejnych punktów/kwadratów podanego odcinka.
|
||||||
|
* <p>
|
||||||
|
* Wykorzystuje algorytm Bresenhama.
|
||||||
|
*
|
||||||
|
* @param x1 współrzędna x początku
|
||||||
|
* @param y1 współrzędna y początku
|
||||||
|
* @param x2 współrzędna x końca
|
||||||
|
* @param y2 współrzędna y końca
|
||||||
|
* @return tablicę kolejnych kwadratów tworzących odcinek o zadanych końcach
|
||||||
|
*/
|
||||||
|
public static GridCoord[] generateSegment(int x1, int y1, int x2, int y2) {
|
||||||
|
int x = x1;
|
||||||
|
int y = y1;
|
||||||
|
int dx = x2 - x1;
|
||||||
|
int dy = y2 - y1;
|
||||||
|
final int sx = sign(dx);
|
||||||
|
final int sy = sign(dy);
|
||||||
|
if (dx < 0) {
|
||||||
|
dx = -dx;
|
||||||
|
}
|
||||||
|
if (dy < 0) {
|
||||||
|
dy = -dy;
|
||||||
|
}
|
||||||
|
final int ddx = 2 * dx;
|
||||||
|
final int ddy = 2 * dy;
|
||||||
|
int p;
|
||||||
|
if (dx >= dy) {
|
||||||
|
// poruszamy się po x
|
||||||
|
p = ddy - dx;
|
||||||
|
GridCoord[] res = new GridCoord[dx + 1];
|
||||||
|
for (int i = 0; i <= dx; i++) {
|
||||||
|
res[i] = new GridCoord(x, y);
|
||||||
|
if (p > 0) {
|
||||||
|
y += sy;
|
||||||
|
p -= ddx;
|
||||||
|
}
|
||||||
|
x += sx;
|
||||||
|
p += ddy;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
// poruszamy sie po y
|
||||||
|
p = ddx - dy;
|
||||||
|
GridCoord[] res = new GridCoord[dy + 1];
|
||||||
|
for (int i = 0; i <= dy; i++) {
|
||||||
|
res[i] = new GridCoord(x, y);
|
||||||
|
if (p > 0) {
|
||||||
|
x += sx;
|
||||||
|
p -= ddy;
|
||||||
|
}
|
||||||
|
y += sy;
|
||||||
|
p += ddx;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void print(GridCoord[] segment) {
|
||||||
|
StringBuilder sb = new StringBuilder(300);
|
||||||
|
sb.append('[');
|
||||||
|
int last = segment.length - 1;
|
||||||
|
for (int i = 0; i < segment.length; i++) {
|
||||||
|
sb.append('(');
|
||||||
|
sb.append(segment[i].x);
|
||||||
|
sb.append(',');
|
||||||
|
sb.append(segment[i].y);
|
||||||
|
sb.append(')');
|
||||||
|
if (i < last) {
|
||||||
|
sb.append('|');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append(']');
|
||||||
|
System.out.println(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public static void main(String[] args) {
|
||||||
|
//
|
||||||
|
// var segment = generateSegmentSquares(10, 3, 1, 6);
|
||||||
|
// var segment2 = generateSegmentSquares(1, 6, 10, 3);
|
||||||
|
// var line = generateSegmentSquares(2, 1, 5, 8);
|
||||||
|
// var line1 = generateSegmentSquares(5, 8, 2, 1);
|
||||||
|
// var line2 = generateSegmentSquares(1, 6, 6, 11);
|
||||||
|
// var line3 = generateSegmentSquares(11, 6, 6, 1);
|
||||||
|
//
|
||||||
|
// final int low = 300;
|
||||||
|
// final int xHigh = 2000;
|
||||||
|
// final int yHigh = 1000;
|
||||||
|
// final int TRIAL_LENGTH = 100;
|
||||||
|
// System.out.println("Start trial 1");
|
||||||
|
// long t0 = System.nanoTime();
|
||||||
|
// long sumLen = 0;
|
||||||
|
// for (int i = 0; i < TRIAL_LENGTH; i++) {
|
||||||
|
// int x1 = low + RandomStream.uniformInt(-20, 20);
|
||||||
|
// int y1 = low + RandomStream.uniformInt(-20, 20);
|
||||||
|
// int x2 = low + RandomStream.uniformInt(-20, 20);
|
||||||
|
// int y2 = low + RandomStream.uniformInt(-20, 20);
|
||||||
|
// int dx = Math.abs(x2 - x1);
|
||||||
|
// int dy = Math.abs(y2 - y1);
|
||||||
|
// if (dx == dy) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// var seg1 = generateSegmentSquares(x1, y1, x2, y2);
|
||||||
|
// print(seg1);
|
||||||
|
// }
|
||||||
|
// long dt = System.nanoTime() - t0;
|
||||||
|
// dt /= 1_000_000;
|
||||||
|
// System.out.println("Czas = " + dt + " [ms]");
|
||||||
|
// sumLen = 0;
|
||||||
|
// System.out.println("Start trial 2");
|
||||||
|
// t0 = System.nanoTime();
|
||||||
|
// for (int i = 0; i < TRIAL_LENGTH * 10000; i++) {
|
||||||
|
// int x1 = low + RandomStream.uniformInt(50);
|
||||||
|
// int y1 = low + RandomStream.uniformInt(50);
|
||||||
|
// int x2 = 2 * xHigh + RandomStream.uniformInt(1000);
|
||||||
|
// int y2 = 2 * yHigh + RandomStream.uniformInt(2000);
|
||||||
|
// int dx = Math.abs(x2 - x1);
|
||||||
|
// int dy = Math.abs(y2 - y1);
|
||||||
|
// if (dx == dy) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var seg1 = generateSegmentSquares(x1, y1, x2, y2);
|
||||||
|
//
|
||||||
|
// sumLen += seg1.length;
|
||||||
|
// }
|
||||||
|
// dt = System.nanoTime() - t0;
|
||||||
|
// dt /= 1_000_000;
|
||||||
|
// System.out.println("Czas = " + dt + " [ms] - len=" + sumLen);
|
||||||
|
//
|
||||||
|
//// var seg1 = generateSegment(1, 1, 3, 5);
|
||||||
|
//// var seg2 = generateSegment(14, 4, 3, 8);
|
||||||
|
//// System.out.println(seg1);
|
||||||
|
// }
|
||||||
|
}
|
||||||
13
src/main/java/pl/wat/ms4ds/terenfunkcje/EmptyBigSquare.java
Normal file
13
src/main/java/pl/wat/ms4ds/terenfunkcje/EmptyBigSquare.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
class EmptyBigSquare extends BigSquare {
|
||||||
|
|
||||||
|
public static final EmptyBigSquare EMPTY_BIG_SQUARE = new EmptyBigSquare();
|
||||||
|
|
||||||
|
private EmptyBigSquare() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Kwadrat getKwadrat(int ssX, int ssY) {
|
||||||
|
return Kwadrat.EMPTY_SQUARE;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/main/java/pl/wat/ms4ds/terenfunkcje/GeoCoord.java
Normal file
9
src/main/java/pl/wat/ms4ds/terenfunkcje/GeoCoord.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GeoCoord {
|
||||||
|
public double lat;
|
||||||
|
public double lon;
|
||||||
|
}
|
||||||
1647
src/main/java/pl/wat/ms4ds/terenfunkcje/GeomUtils.java
Normal file
1647
src/main/java/pl/wat/ms4ds/terenfunkcje/GeomUtils.java
Normal file
File diff suppressed because it is too large
Load Diff
689
src/main/java/pl/wat/ms4ds/terenfunkcje/GridCoord.java
Normal file
689
src/main/java/pl/wat/ms4ds/terenfunkcje/GridCoord.java
Normal file
@@ -0,0 +1,689 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
//import pl.wat.wcy.exception.IdKwadratuException;
|
||||||
|
|
||||||
|
|
||||||
|
import pl.wat.ms4ds.common.EGeoDirection;
|
||||||
|
|
||||||
|
public class GridCoord {
|
||||||
|
|
||||||
|
public int x;
|
||||||
|
public int y;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konstruktor klasy na bazie współrzędnych geograficznych.
|
||||||
|
*
|
||||||
|
* @param lon długość geograficzna
|
||||||
|
* @param lat szerokość geograficzna
|
||||||
|
*/
|
||||||
|
public GridCoord(double lon, double lat) {
|
||||||
|
double xms_f = (lon + 180) * MapConsts.DEG_MS;
|
||||||
|
long xms = (long) xms_f;
|
||||||
|
x = zamienWspXmsNaIdKwadratuX(xms);
|
||||||
|
|
||||||
|
double yms_f = (lat + 90) * MapConsts.DEG_MS;
|
||||||
|
long yms = (long) yms_f;
|
||||||
|
y = zamienWspYmsNaIdKwadratuY(yms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja zamienia dlugosc geog. xms w milisekundach na IdKwadrat.x.
|
||||||
|
*
|
||||||
|
* @param xms długość geograficzna (lon) w milisekundach
|
||||||
|
* @return współrzędna GridCoord.x
|
||||||
|
*/
|
||||||
|
public static int zamienWspXmsNaIdKwadratuX(long xms) {
|
||||||
|
// wspolrzedne geograficzne w milisekundach zawieraja sie w zakresie:
|
||||||
|
// 0 <= x < 360 dlugosc geograficzna
|
||||||
|
// 0 <= y <= 180 szerokosc geograficzna
|
||||||
|
if ((xms < 0) || (xms >= 360 * MapConsts.DEG_MS)) {
|
||||||
|
// poza zakresem
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
long x = xms;
|
||||||
|
if (x < MapConsts.X_REF_MS) {
|
||||||
|
// // poza zakresem
|
||||||
|
long dx = x + MapConsts.ANGLE_360_MS - MapConsts.X_REF_MS;
|
||||||
|
if (dx > MapConsts.DX_REF_MS) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
x += MapConsts.ANGLE_360_MS;
|
||||||
|
}
|
||||||
|
// if (x > MapConsts.X_REF_MS + MapConsts.DX_REF_MS) {
|
||||||
|
// // poza zakresem
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
// indeksowanie kwadratow pola walki zaczyna sie od (0, 0)
|
||||||
|
double xx = (x - MapConsts.X_REF_MS) * ODWROT_SS_DX_MS;
|
||||||
|
// x = (x - MapConsts.X_REF_MS) / MapConsts.SS_DX_MS;
|
||||||
|
return (int) xx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja zamienia szerokosc geog. yms w milisekundach na IdKwadrat.y.
|
||||||
|
*
|
||||||
|
* @param yms szerokosc geograficzna (lat) w milisekundach
|
||||||
|
* @return współrzędna GridCoord.y
|
||||||
|
*/
|
||||||
|
public static int zamienWspYmsNaIdKwadratuY(long yms) {
|
||||||
|
// wspolrzedne geograficzne w milisekundach zawieraja sie w zakresie:
|
||||||
|
// 0 <= x < 360 dlugosc geograficzna
|
||||||
|
// 0 <= y <= 180 szerokosc geograficzna
|
||||||
|
// if ((yms < MapConsts.Y_REF_MS) || (yms > MapConsts.Y_REF_MS + MapConsts.DY_REF_MS)) {
|
||||||
|
// // poza zakresem
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
if (yms < MapConsts.Y_REF_MS) {
|
||||||
|
// poza zakresem
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// indeksowanie kwadratow pola walki zaczyna sie od (0, 0)
|
||||||
|
double yy = (yms - MapConsts.Y_REF_MS) * ODWROT_SS_DY_MS;
|
||||||
|
// long y = (yms - MapConsts.Y_REF_MS) / MapConsts.SS_DY_MS;
|
||||||
|
return (int) yy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zamienia długość geograficzną na współrzędna x GridCoord.
|
||||||
|
*
|
||||||
|
* @param lon długość geograficzna
|
||||||
|
* @return współrzędna x klasy GridCoord
|
||||||
|
*/
|
||||||
|
public static int zamienDlugoscGeoNaIdKwadratuX(double lon) {
|
||||||
|
double xms_f = (lon + 180) * MapConsts.DEG_MS;
|
||||||
|
return zamienWspXmsNaIdKwadratuX((long) xms_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zamienia szerokość geograficzną na współrzędna y GridCoord.
|
||||||
|
*
|
||||||
|
* @param lat szerokość geograficzna
|
||||||
|
* @return współrzędna y klasy GridCoord
|
||||||
|
*/
|
||||||
|
public static int zamienSzerokoscGeoNaIdKwadratuY(double lat) {
|
||||||
|
double yms_f = (lat + 90) * MapConsts.DEG_MS;
|
||||||
|
return zamienWspYmsNaIdKwadratuY((long) yms_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridCoord kwadratSasiedni(EGeoDirection kier) {
|
||||||
|
GridCoord idKwSasiedni = new GridCoord();
|
||||||
|
switch (kier) {
|
||||||
|
case NORTH:
|
||||||
|
idKwSasiedni.x = x;
|
||||||
|
idKwSasiedni.y = y + 1;
|
||||||
|
break;
|
||||||
|
case NORTHEAST:
|
||||||
|
idKwSasiedni.x = x + 1;
|
||||||
|
idKwSasiedni.y = y + 1;
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
idKwSasiedni.x = x + 1;
|
||||||
|
idKwSasiedni.y = y;
|
||||||
|
break;
|
||||||
|
case SOUTHEAST:
|
||||||
|
idKwSasiedni.x = x + 1;
|
||||||
|
idKwSasiedni.y = y - 1;
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
idKwSasiedni.x = x;
|
||||||
|
idKwSasiedni.y = y - 1;
|
||||||
|
break;
|
||||||
|
case SOUTHWEST:
|
||||||
|
idKwSasiedni.x = x - 1;
|
||||||
|
idKwSasiedni.y = y - 1;
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
idKwSasiedni.x = x - 1;
|
||||||
|
idKwSasiedni.y = y;
|
||||||
|
break;
|
||||||
|
case NORTHWEST:
|
||||||
|
idKwSasiedni.x = x - 1;
|
||||||
|
idKwSasiedni.y = y + 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return idKwSasiedni;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void kwadratSasiedni(GridCoord idKwSasiedni, EGeoDirection kier) {
|
||||||
|
switch (kier) {
|
||||||
|
case NORTH:
|
||||||
|
idKwSasiedni.x = x;
|
||||||
|
idKwSasiedni.y = y + 1;
|
||||||
|
break;
|
||||||
|
case NORTHEAST:
|
||||||
|
idKwSasiedni.x = x + 1;
|
||||||
|
idKwSasiedni.y = y + 1;
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
idKwSasiedni.x = x + 1;
|
||||||
|
idKwSasiedni.y = y;
|
||||||
|
break;
|
||||||
|
case SOUTHEAST:
|
||||||
|
idKwSasiedni.x = x + 1;
|
||||||
|
idKwSasiedni.y = y - 1;
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
idKwSasiedni.x = x;
|
||||||
|
idKwSasiedni.y = y - 1;
|
||||||
|
break;
|
||||||
|
case SOUTHWEST:
|
||||||
|
idKwSasiedni.x = x - 1;
|
||||||
|
idKwSasiedni.y = y - 1;
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
idKwSasiedni.x = x - 1;
|
||||||
|
idKwSasiedni.y = y;
|
||||||
|
break;
|
||||||
|
case NORTHWEST:
|
||||||
|
idKwSasiedni.x = x - 1;
|
||||||
|
idKwSasiedni.y = y + 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridCoord[] dajSasiadow() {
|
||||||
|
GridCoord[] sasiedzi = new GridCoord[8];
|
||||||
|
sasiedzi[0] = new GridCoord(x, y + 1);
|
||||||
|
sasiedzi[1] = new GridCoord(x + 1, y + 1);
|
||||||
|
sasiedzi[2] = new GridCoord(x + 1, y);
|
||||||
|
sasiedzi[3] = new GridCoord(x + 1, y - 1);
|
||||||
|
sasiedzi[4] = new GridCoord(x, y - 1);
|
||||||
|
sasiedzi[5] = new GridCoord(x - 1, y - 1);
|
||||||
|
sasiedzi[6] = new GridCoord(x - 1, y);
|
||||||
|
sasiedzi[7] = new GridCoord(x - 1, y + 1);
|
||||||
|
return sasiedzi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GridCoord[] dajSasiadow(int x, int y) {
|
||||||
|
GridCoord[] sasiedzi = new GridCoord[8];
|
||||||
|
sasiedzi[0] = new GridCoord(x, y + 1);
|
||||||
|
sasiedzi[1] = new GridCoord(x + 1, y + 1);
|
||||||
|
sasiedzi[2] = new GridCoord(x + 1, y);
|
||||||
|
sasiedzi[3] = new GridCoord(x + 1, y - 1);
|
||||||
|
sasiedzi[4] = new GridCoord(x, y - 1);
|
||||||
|
sasiedzi[5] = new GridCoord(x - 1, y - 1);
|
||||||
|
sasiedzi[6] = new GridCoord(x - 1, y);
|
||||||
|
sasiedzi[7] = new GridCoord(x - 1, y + 1);
|
||||||
|
return sasiedzi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GridCoord[] dajSasiadow(GridCoord centralny) {
|
||||||
|
GridCoord[] sasiedzi = new GridCoord[8];
|
||||||
|
sasiedzi[0] = new GridCoord(centralny.x, centralny.y + 1);
|
||||||
|
sasiedzi[1] = new GridCoord(centralny.x + 1, centralny.y + 1);
|
||||||
|
sasiedzi[2] = new GridCoord(centralny.x + 1, centralny.y);
|
||||||
|
sasiedzi[3] = new GridCoord(centralny.x + 1, centralny.y - 1);
|
||||||
|
sasiedzi[4] = new GridCoord(centralny.x, centralny.y - 1);
|
||||||
|
sasiedzi[5] = new GridCoord(centralny.x - 1, centralny.y - 1);
|
||||||
|
sasiedzi[6] = new GridCoord(centralny.x - 1, centralny.y);
|
||||||
|
sasiedzi[7] = new GridCoord(centralny.x - 1, centralny.y + 1);
|
||||||
|
return sasiedzi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridCoord[] dajOtoczenie() {
|
||||||
|
GridCoord[] sasiedzi = new GridCoord[9];
|
||||||
|
sasiedzi[0] = new GridCoord(x, y);
|
||||||
|
sasiedzi[1] = new GridCoord(x, y + 1);
|
||||||
|
sasiedzi[2] = new GridCoord(x + 1, y + 1);
|
||||||
|
sasiedzi[3] = new GridCoord(x + 1, y);
|
||||||
|
sasiedzi[4] = new GridCoord(x + 1, y - 1);
|
||||||
|
sasiedzi[5] = new GridCoord(x, y - 1);
|
||||||
|
sasiedzi[6] = new GridCoord(x - 1, y - 1);
|
||||||
|
sasiedzi[7] = new GridCoord(x - 1, y);
|
||||||
|
sasiedzi[8] = new GridCoord(x - 1, y + 1);
|
||||||
|
return sasiedzi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GridCoord[] dajOtoczenie(int x, int y) {
|
||||||
|
GridCoord[] sasiedzi = new GridCoord[9];
|
||||||
|
sasiedzi[0] = new GridCoord(x, y);
|
||||||
|
sasiedzi[1] = new GridCoord(x, y + 1);
|
||||||
|
sasiedzi[2] = new GridCoord(x + 1, y + 1);
|
||||||
|
sasiedzi[3] = new GridCoord(x + 1, y);
|
||||||
|
sasiedzi[4] = new GridCoord(x + 1, y - 1);
|
||||||
|
sasiedzi[5] = new GridCoord(x, y - 1);
|
||||||
|
sasiedzi[6] = new GridCoord(x - 1, y - 1);
|
||||||
|
sasiedzi[7] = new GridCoord(x - 1, y);
|
||||||
|
sasiedzi[8] = new GridCoord(x - 1, y + 1);
|
||||||
|
return sasiedzi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GridCoord[] dajOtoczenie(GridCoord centralny) {
|
||||||
|
GridCoord[] sasiedzi = new GridCoord[8];
|
||||||
|
sasiedzi[0] = new GridCoord(centralny.x, centralny.y);
|
||||||
|
sasiedzi[1] = new GridCoord(centralny.x, centralny.y + 1);
|
||||||
|
sasiedzi[2] = new GridCoord(centralny.x + 1, centralny.y + 1);
|
||||||
|
sasiedzi[3] = new GridCoord(centralny.x + 1, centralny.y);
|
||||||
|
sasiedzi[4] = new GridCoord(centralny.x + 1, centralny.y - 1);
|
||||||
|
sasiedzi[5] = new GridCoord(centralny.x, centralny.y - 1);
|
||||||
|
sasiedzi[6] = new GridCoord(centralny.x - 1, centralny.y - 1);
|
||||||
|
sasiedzi[7] = new GridCoord(centralny.x - 1, centralny.y);
|
||||||
|
sasiedzi[8] = new GridCoord(centralny.x - 1, centralny.y + 1);
|
||||||
|
return sasiedzi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean rowne(int x, int y) {
|
||||||
|
return this.x == x && this.y == y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder("(x= ");
|
||||||
|
sb.append(x);
|
||||||
|
sb.append(", y= ");
|
||||||
|
sb.append(y);
|
||||||
|
sb.append(')');
|
||||||
|
// String s = "(x= " + Integer.toString(x) + ", y= " + Integer.toString(y) + ")";
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zamienia współrzęną GridCoord.x na długość geograficzną środka małego kwadratu
|
||||||
|
*
|
||||||
|
* @param idX współrzęna x GridCoord
|
||||||
|
* @return długość geograficzna
|
||||||
|
*/
|
||||||
|
public static float zamienIdKwadratuXNaDlugoscGeo(int idX) {
|
||||||
|
long xms = zamienIdKwadratuXNaWspXms(idX);
|
||||||
|
double lon = (double) xms / (double) MapConsts.DEG_MS - 180;
|
||||||
|
return (float) lon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zamienia współrzęną GridCoord.y na szerokość geograficzną środka małego kwadratu
|
||||||
|
*
|
||||||
|
* @param idY współrzęna y GridCoord
|
||||||
|
* @return szerokość geograficzna
|
||||||
|
*/
|
||||||
|
public static float zamienIdKwadratuYNaSzerokoscGeo(int idY) {
|
||||||
|
long yms = zamienIdKwadratuYNaWspYms(idY);
|
||||||
|
double lat = (double) yms / (double) MapConsts.DEG_MS - 90;
|
||||||
|
return (float) lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zamienia współrzęną GridCoord.x na długość geograficzną lewego dolnego rogu małego kwadratu
|
||||||
|
*
|
||||||
|
* @param idX współrzęna x GridCoord
|
||||||
|
* @return długość geograficzna
|
||||||
|
*/
|
||||||
|
public static float zamienIdKwadratuXNaDlugoscGeoLD(int idX) {
|
||||||
|
long xms = zamienIdKwadratuXNaWspXmsLD(idX);
|
||||||
|
double lon = (double) xms / (double) MapConsts.DEG_MS - 180;
|
||||||
|
return (float) lon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zamienia współrzęną GridCoord.y na szerokość geograficzną środka małego kwadratu
|
||||||
|
*
|
||||||
|
* @param idY współrzęna y GridCoord
|
||||||
|
* @return szerokość geograficzna
|
||||||
|
*/
|
||||||
|
public static float zamienIdKwadratuYNaSzerokoscGeoLD(int idY) {
|
||||||
|
long yms = zamienIdKwadratuYNaWspYmsLD(idY);
|
||||||
|
double lat = (double) yms / (double) MapConsts.DEG_MS - 90;
|
||||||
|
return (float) lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int zamienWspUtmNaIdkwadratuX(String wspolrzedneUtm) {
|
||||||
|
// //////////////////////////////////
|
||||||
|
// wspolrzedne - znaki w formacie 522644N0154232E
|
||||||
|
// wyznaczenie numeru kwadraty Au2 dla wspolrzednej X
|
||||||
|
// np.: '153200' to 304
|
||||||
|
|
||||||
|
int xms = Teren.zamienWspUtmNaWspXms(wspolrzedneUtm);
|
||||||
|
int idKwX = GridCoord.zamienWspXmsNaIdKwadratuX(xms);
|
||||||
|
return idKwX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int zamienWspUtmNaIdkwadratuY(String wspolrzedneUtm) {
|
||||||
|
// //////////////////////////////////
|
||||||
|
// wspolrzedne - znaki w formacie 522644N0154232E
|
||||||
|
// wyznaczenie numeru kwadraty Au2 dla wspolrzednej Y
|
||||||
|
// np.: '153200' to 304
|
||||||
|
int yms = Teren.zamienWspUtmNaWspYms(wspolrzedneUtm);
|
||||||
|
int idKwY = GridCoord.zamienWspYmsNaIdKwadratuY(yms);
|
||||||
|
return idKwY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridCoord(String wspolrzedne) {
|
||||||
|
this.x = zamienWspUtmNaIdkwadratuX(wspolrzedne);
|
||||||
|
this.y = zamienWspUtmNaIdkwadratuY(wspolrzedne);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GridCoord zamienWspUtmNaIdKwadratu(String wspolrzedne) {
|
||||||
|
// Utworzenie obiektu GridCoord ze wspolrzednych UTM
|
||||||
|
GridCoord kwadrat = new GridCoord(wspolrzedne);
|
||||||
|
return kwadrat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String zamienIdKwadratuNaWspUtm(GridCoord kwadrat) {
|
||||||
|
long xms = zamienIdKwadratuXNaWspXms(kwadrat.x);
|
||||||
|
long yms = zamienIdKwadratuYNaWspYms(kwadrat.y);
|
||||||
|
return Teren.zamienWspXmsYmsNaWspUtm(xms, yms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja zamienia wsp. X GridCoord na wsp. geo xms w milisekundach.
|
||||||
|
* Zwracana wspolrzedna lezy w srodku kwadratu.
|
||||||
|
*/
|
||||||
|
public static long zamienIdKwadratuXNaWspXms(int idKwX) {
|
||||||
|
// indeksowanie kwadratow pola walki zaczyna sie od (0, 0)
|
||||||
|
// przesuniecie wspolrzednych do srodka kwadratu
|
||||||
|
long xms = MapConsts.X_REF_MS + (long) ((idKwX + 0.5) * MapConsts.SS_DX_MS);
|
||||||
|
xms %= MapConsts.ANGLE_360_MS;
|
||||||
|
return xms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja zamienia wsp. Y GridCoord na wsp. geo yms w milisekundach.
|
||||||
|
* Zwracana wspolrzedna lezy w srodku kwadratu.
|
||||||
|
*/
|
||||||
|
public static long zamienIdKwadratuYNaWspYms(int idKwY) {
|
||||||
|
// indeksowanie kwadratow pola walki zaczyna sie od (0, 0)
|
||||||
|
// przesuniecie wspolrzednych do srodka kwadratu
|
||||||
|
long yms = MapConsts.Y_REF_MS + (long) ((idKwY + 0.5) * MapConsts.SS_DY_MS);
|
||||||
|
return yms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja zamienia wsp. X GridCoord na wsp. geo xms w milisekundach lewego dolnego rogu malego kwadratu.
|
||||||
|
* Zwracana wspolrzedna lezy w srodku kwadratu.
|
||||||
|
*/
|
||||||
|
public static long zamienIdKwadratuXNaWspXmsLD(int idKwX) {
|
||||||
|
// indeksowanie kwadratow pola walki zaczyna sie od (0, 0)
|
||||||
|
// przesuniecie wspolrzednych do srodka kwadratu
|
||||||
|
long xms = MapConsts.X_REF_MS + (long) (idKwX * MapConsts.SS_DX_MS);
|
||||||
|
xms %= MapConsts.ANGLE_360_MS;
|
||||||
|
return xms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja zamienia wsp. Y GridCoord na wsp. geo yms w milisekundach lewego dolnego rogu malego kwadratu.
|
||||||
|
* Zwracana wspolrzedna lezy w srodku kwadratu.
|
||||||
|
*/
|
||||||
|
public static long zamienIdKwadratuYNaWspYmsLD(int idKwY) {
|
||||||
|
// indeksowanie kwadratow pola walki zaczyna sie od (0, 0)
|
||||||
|
// przesuniecie wspolrzednych do srodka kwadratu
|
||||||
|
long yms = MapConsts.Y_REF_MS + (long) (idKwY * MapConsts.SS_DY_MS);
|
||||||
|
return yms;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final double ODWROT_SS_DX_MS = 1.0 / MapConsts.SS_DX_MS;
|
||||||
|
private static final double ODWROT_SS_DY_MS = 1.0 / MapConsts.SS_DY_MS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja sprawdza, czy kwadraty sa takie same.
|
||||||
|
*
|
||||||
|
* @param id1
|
||||||
|
* @param id2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean czyIdentyczne(GridCoord id1, GridCoord id2) {
|
||||||
|
if (null == id1 || null == id2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (id1.x != id2.x || id1.y != id2.y) {
|
||||||
|
return false;
|
||||||
|
} else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja zwraca odleglosc miedzy srodkami malych kwadratow [m].
|
||||||
|
*
|
||||||
|
* @param p1 współrzędna malego kwadratu pocz.
|
||||||
|
* @param p2 współrzędna malego kwadratu konc.
|
||||||
|
* @return Odległość między środkami małych kwadratów [m].
|
||||||
|
*/
|
||||||
|
public static float odleglosc(GridCoord p1, GridCoord p2) {
|
||||||
|
// odleglosc miedzy srodkami malych kwadratow
|
||||||
|
if (null == p1 || null == p2) {
|
||||||
|
return -1.0f;
|
||||||
|
}
|
||||||
|
int xx = p1.x - p2.x;
|
||||||
|
xx *= xx;
|
||||||
|
int yy = p1.y - p2.y;
|
||||||
|
yy *= yy;
|
||||||
|
float odl = (float) Math.sqrt(xx + yy);
|
||||||
|
odl *= MapConsts.DL_MK;
|
||||||
|
return odl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja zwraca odległość między środkami małych kwadratów [m].
|
||||||
|
*
|
||||||
|
* @param x1 Wsp X id malego kwadratu pocz.
|
||||||
|
* @param y1 Wsp Y id malego kwadratu pocz.
|
||||||
|
* @param x2 Wsp X id malego kwadratu konc.
|
||||||
|
* @param y2 Wsp Y id malego kwadratu konc.
|
||||||
|
* @return Odległość miedzy srodkami malych kwadratow [m].
|
||||||
|
*/
|
||||||
|
public static float odleglosc(int x1, int y1, int x2, int y2) {
|
||||||
|
// odleglosc miedzy srodkami malych kwadratow
|
||||||
|
int xx = x1 - x2;
|
||||||
|
xx *= xx;
|
||||||
|
int yy = y1 - y2;
|
||||||
|
yy *= yy;
|
||||||
|
float odl = (float) Math.sqrt(xx + yy);
|
||||||
|
odl *= MapConsts.DL_MK;
|
||||||
|
return odl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja zwraca odległość między środkami małych kwadratów [m].
|
||||||
|
*
|
||||||
|
* @param dx odległość w kwadratach na osi OX.
|
||||||
|
* @param dy odległość w kwadratach na osi OY.
|
||||||
|
* @return Odległość miedzy srodkami malych kwadratow [m].
|
||||||
|
*/
|
||||||
|
public static float odleglosc(int dx, int dy) {
|
||||||
|
float odl = (float) Math.sqrt(dx * dx + dy * dy);
|
||||||
|
odl *= MapConsts.DL_MK;
|
||||||
|
return odl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final float DL_MK2 = MapConsts.DL_MK * 0.0009765625f;
|
||||||
|
/**
|
||||||
|
* Funkcja zwraca aproksymowaną odległość między środkami małych kwadratów [m].
|
||||||
|
*
|
||||||
|
* @param x1 Wsp X id malego kwadratu pocz.
|
||||||
|
* @param y1 Wsp Y id malego kwadratu pocz.
|
||||||
|
* @param x2 Wsp X id malego kwadratu konc.
|
||||||
|
* @param y2 Wsp Y id malego kwadratu konc.
|
||||||
|
* @return Odległość miedzy srodkami malych kwadratow [m].
|
||||||
|
*/
|
||||||
|
public static float odlegloscApprox(int x1, int y1, int x2, int y2) {
|
||||||
|
int dx = x2 - x1;
|
||||||
|
int dy = y2 - y1;
|
||||||
|
int min, max, approx;
|
||||||
|
if (dx < 0) dx = -dx;
|
||||||
|
if (dy < 0) dy = -dy;
|
||||||
|
if (dx < dy) {
|
||||||
|
min = dx;
|
||||||
|
max = dy;
|
||||||
|
} else {
|
||||||
|
min = dy;
|
||||||
|
max = dx;
|
||||||
|
}
|
||||||
|
approx = (max * 1007) + (min * 441);
|
||||||
|
if (max < (min << 4)) {
|
||||||
|
approx -= (max * 40);
|
||||||
|
}
|
||||||
|
float odl = approx * DL_MK2;
|
||||||
|
return odl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int iloczynSkalarny(GridCoord p1, GridCoord p2) {
|
||||||
|
int wynik;
|
||||||
|
wynik = p1.x * p2.x + p1.y * p2.y;
|
||||||
|
return wynik;
|
||||||
|
}
|
||||||
|
|
||||||
|
// funkcja sprawdza, czy dwa obszary skierowane maja czesc wspolna
|
||||||
|
public static boolean majaCzescWspolna(GridCoord[] rejon1, GridCoord[] rejon2) {
|
||||||
|
if ((rejon1 == null) || (rejon2 == null)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < rejon2.length; i++) {
|
||||||
|
if (GeomUtils.insidePolygon(rejon1, rejon2[i].x, rejon2[i].y)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < rejon1.length; i++) {
|
||||||
|
if (GeomUtils.insidePolygon(rejon2, rejon1[i].x, rejon1[i].y)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wyznacza stosunek czesci wspolnej obszarow do obszaru bazowego
|
||||||
|
public static float stosunekCzesciWspolnej(GridCoord[] rejon_bazowy, GridCoord[] rejon2) {
|
||||||
|
if ((rejon_bazowy == null) || (rejon2 == null)) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
boolean majaCzescWspolna = majaCzescWspolna(rejon_bazowy, rejon2);
|
||||||
|
if (!majaCzescWspolna) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
GridCoord[] kwadraty1 = GeomUtils.kwadratyObszaru(rejon_bazowy);
|
||||||
|
GridCoord[] kwadraty2 = GeomUtils.kwadratyObszaru(rejon2);
|
||||||
|
int maxWspolnych = 0;
|
||||||
|
if (kwadraty1.length <= kwadraty2.length) {
|
||||||
|
maxWspolnych = kwadraty1.length;
|
||||||
|
} else {
|
||||||
|
maxWspolnych = kwadraty2.length;
|
||||||
|
}
|
||||||
|
if ((kwadraty1 == null) || (kwadraty2 == null)) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
int wspolnych = 0;
|
||||||
|
for (int i = 0; i < kwadraty1.length; i++) {
|
||||||
|
for (int j = 0; j < kwadraty2.length; j++) {
|
||||||
|
if (czyIdentyczne(kwadraty1[i], kwadraty2[j])) {
|
||||||
|
wspolnych++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ((float) wspolnych) / ((float) (maxWspolnych));
|
||||||
|
}
|
||||||
|
|
||||||
|
// wyznacza wspolrzedne lewego dolnego wierzcholka oraz
|
||||||
|
// prawego gornego wierzcholka prostokata opisanego na obszarze: rejon
|
||||||
|
public static void minMaxIdKwadratu(GridCoord[] rejon, GridCoord min, GridCoord max) {
|
||||||
|
if (rejon == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (min == null) {
|
||||||
|
min = new GridCoord(rejon[0].x, rejon[0].y);
|
||||||
|
}
|
||||||
|
if (max == null) {
|
||||||
|
max = new GridCoord(rejon[0].x, rejon[0].y);
|
||||||
|
}
|
||||||
|
for (int i = 1; i < rejon.length; i++) {
|
||||||
|
if (min.x > rejon[i].x) {
|
||||||
|
min.x = rejon[i].x;
|
||||||
|
}
|
||||||
|
if (min.y > rejon[i].y) {
|
||||||
|
min.y = rejon[i].y;
|
||||||
|
}
|
||||||
|
if (max.x < rejon[i].x) {
|
||||||
|
max.x = rejon[i].x;
|
||||||
|
}
|
||||||
|
if (max.y < rejon[i].y) {
|
||||||
|
max.y = rejon[i].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(double lon, double lat) {
|
||||||
|
double xms_f = (lon + 180) * MapConsts.DEG_MS;
|
||||||
|
long xms = (long) xms_f;
|
||||||
|
x = zamienWspXmsNaIdKwadratuX(xms);
|
||||||
|
|
||||||
|
double yms_f = (lat + 90) * MapConsts.DEG_MS;
|
||||||
|
long yms = (long) yms_f;
|
||||||
|
y = zamienWspYmsNaIdKwadratuY(yms);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridCoord() {
|
||||||
|
x = -1;
|
||||||
|
y = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridCoord(int x, int y) {
|
||||||
|
/* try {
|
||||||
|
if (x < 0 || y < 0)
|
||||||
|
throw new IdKwadratuException();
|
||||||
|
}
|
||||||
|
catch (IdKwadratuException e) {
|
||||||
|
System.out.print(e.opis);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridCoord(GridCoord oryginal) {
|
||||||
|
this.x = oryginal.x;
|
||||||
|
this.y = oryginal.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(int x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY(int y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(GridCoord oryginal) {
|
||||||
|
x = oryginal.x;
|
||||||
|
y = oryginal.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = prime + x;
|
||||||
|
result = prime * result + y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof GridCoord)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
GridCoord other = (GridCoord) obj;
|
||||||
|
if (x != other.x) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (y != other.y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
358
src/main/java/pl/wat/ms4ds/terenfunkcje/Kwadrat.java
Normal file
358
src/main/java/pl/wat/ms4ds/terenfunkcje/Kwadrat.java
Normal file
@@ -0,0 +1,358 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
|
||||||
|
import pl.wat.ms4ds.common.EGeoDirection;
|
||||||
|
|
||||||
|
public class Kwadrat {
|
||||||
|
|
||||||
|
public static final Kwadrat EMPTY_SQUARE = new Kwadrat(null, 0.0f, 0.0f, 0.0f, 0.0f, 200, 0,
|
||||||
|
new boolean[8], new boolean[8], new boolean[8]);
|
||||||
|
|
||||||
|
float stopienZabudowy;
|
||||||
|
float stopienZalesienia;
|
||||||
|
float stopienZawodnienia;
|
||||||
|
float stopienZabagnienia;
|
||||||
|
boolean jestDroga[];
|
||||||
|
boolean jestRow[];
|
||||||
|
boolean jestPrzeszkodaWodna[];
|
||||||
|
int roznicaWzniesien;
|
||||||
|
int wysokoscSrednia;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The height above the level of the sea.
|
||||||
|
*/
|
||||||
|
short elevation;
|
||||||
|
/**
|
||||||
|
* 0 - BARE_GROUND
|
||||||
|
* 1 - GRASS
|
||||||
|
* 2 - SWAMP
|
||||||
|
* 3 - WATER
|
||||||
|
* 4 - SCRUB, BUSHES
|
||||||
|
* 5 - BUILDINGS
|
||||||
|
* 6 - FOREST
|
||||||
|
*/
|
||||||
|
short terrainType;
|
||||||
|
/**
|
||||||
|
* Rodzaj drogi na danym kierunku.
|
||||||
|
* 0 - no road, 1 - small roads, 2 - minor roads, 3 - major roads
|
||||||
|
*/
|
||||||
|
byte[] roads;
|
||||||
|
/**
|
||||||
|
* Rodzaj przeszkody wodnej na danym kierunku.
|
||||||
|
* 0 - no watercourse, 1 - drain, ditch, 2 - canal, stream, 3 - river
|
||||||
|
*/
|
||||||
|
byte[] waterWays;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
transient RightBigSquare bs;
|
||||||
|
|
||||||
|
public float getStopienZabudowy() {
|
||||||
|
return stopienZabudowy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getStopienZalesienia() {
|
||||||
|
return stopienZalesienia;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getStopienZawodnienia() {
|
||||||
|
return stopienZawodnienia;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getStopienZabagnienia() {
|
||||||
|
return stopienZabagnienia;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRoznicaWzniesien() {
|
||||||
|
return roznicaWzniesien;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWysokoscSrednia() {
|
||||||
|
return wysokoscSrednia;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean[] getJestDroga() {
|
||||||
|
return jestDroga;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean jestOdcinekDrogi() {
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
if (jestDroga[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getJestDroga(EGeoDirection naKierunku) {
|
||||||
|
if (naKierunku == EGeoDirection.UNDEFINED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return jestDroga[naKierunku.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean[] getJestRow() {
|
||||||
|
return jestRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean[] getJestPrzeszkodaWodna() {
|
||||||
|
return jestPrzeszkodaWodna;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStopienZabudowy(float stopienZabudowy) {
|
||||||
|
this.stopienZabudowy = stopienZabudowy;
|
||||||
|
normalizujDanePokrycia();
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStopienZalesienia(float stopienZalesienia) {
|
||||||
|
this.stopienZalesienia = stopienZalesienia;
|
||||||
|
normalizujDanePokrycia();
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStopienZawodnienia(float stopienZawodnienia) {
|
||||||
|
this.stopienZawodnienia = stopienZawodnienia;
|
||||||
|
normalizujDanePokrycia();
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStopienZabagnienia(float stopienZabagnienia) {
|
||||||
|
this.stopienZabagnienia = stopienZabagnienia;
|
||||||
|
normalizujDanePokrycia();
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void normalizujDanePokrycia() {
|
||||||
|
float suma = stopienZalesienia + stopienZawodnienia + stopienZabudowy + stopienZabagnienia;
|
||||||
|
if (suma > 1.0f) {
|
||||||
|
stopienZalesienia /= suma;
|
||||||
|
stopienZawodnienia /= suma;
|
||||||
|
stopienZabudowy /= suma;
|
||||||
|
stopienZabagnienia = 1.0f - stopienZalesienia - stopienZawodnienia - stopienZabudowy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoznicaWzniesien(int roznicaWzniesien) {
|
||||||
|
this.roznicaWzniesien = roznicaWzniesien;
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWysokoscSrednia(int wysokoscSrednia) {
|
||||||
|
this.wysokoscSrednia = wysokoscSrednia;
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJestDroga(boolean[] czyJestDroga) {
|
||||||
|
this.jestDroga = czyJestDroga;
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJestDroga(EGeoDirection naKierunku, boolean czyJest) {
|
||||||
|
if (naKierunku == EGeoDirection.UNDEFINED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.jestDroga[naKierunku.id] = czyJest;
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJestPrzeszkodaWodna(EGeoDirection naKierunku, boolean czyJest) {
|
||||||
|
if (naKierunku == EGeoDirection.UNDEFINED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.jestPrzeszkodaWodna[naKierunku.id] = czyJest;
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJestRow(EGeoDirection naKierunku, boolean czyJest) {
|
||||||
|
if (naKierunku == EGeoDirection.UNDEFINED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.jestRow[naKierunku.id] = czyJest;
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJestRow(boolean[] czyJestRow) {
|
||||||
|
this.jestRow = czyJestRow;
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJestPrzeszkodaWodna(boolean[] czyJestPrzeszkodaWodna) {
|
||||||
|
this.jestPrzeszkodaWodna = czyJestPrzeszkodaWodna;
|
||||||
|
// try {
|
||||||
|
// if (null != bs) {
|
||||||
|
// bs.updateFile(false);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getStopienPofaldowania() {
|
||||||
|
// TODO: dodac do normatywow w klasie Teren (parametr kalibracyjny)
|
||||||
|
float stopienPofaldowania = 0.0f;
|
||||||
|
if (this.roznicaWzniesien >= 50)
|
||||||
|
stopienPofaldowania = 1.0f;
|
||||||
|
else if (this.roznicaWzniesien >= 10)
|
||||||
|
stopienPofaldowania = 0.6f;
|
||||||
|
else if (this.roznicaWzniesien >= 5)
|
||||||
|
stopienPofaldowania = 0.4f;
|
||||||
|
else if (this.roznicaWzniesien >= 3)
|
||||||
|
stopienPofaldowania = 0.2f;
|
||||||
|
return stopienPofaldowania;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Kwadrat() {
|
||||||
|
jestDroga = new boolean[8];
|
||||||
|
jestPrzeszkodaWodna = new boolean[8];
|
||||||
|
jestRow = new boolean[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
public Kwadrat(RightBigSquare _bs, float _stopienZabudowy, float _stopienZalesienia, float _stopienZabagnienia, float _stopienZawodnienia,
|
||||||
|
int _wysokoscSrednia, int _roznicaWzniesien, boolean _czyJestDroga[], boolean _czyJestRow[], boolean _czyJestPrzeszkodaWodna[]){
|
||||||
|
bs = _bs;
|
||||||
|
stopienZabudowy = _stopienZabudowy;
|
||||||
|
stopienZalesienia = _stopienZalesienia;
|
||||||
|
stopienZabagnienia = _stopienZabagnienia;
|
||||||
|
stopienZawodnienia = _stopienZawodnienia;
|
||||||
|
wysokoscSrednia = _wysokoscSrednia;
|
||||||
|
roznicaWzniesien = _roznicaWzniesien;
|
||||||
|
jestDroga = new boolean[8];
|
||||||
|
jestRow = new boolean[8];
|
||||||
|
jestPrzeszkodaWodna = new boolean[8];
|
||||||
|
for (int i = 0; i < _czyJestDroga.length; i++) {
|
||||||
|
jestDroga[i]=_czyJestDroga[i];
|
||||||
|
}
|
||||||
|
for (int i = 0; i < jestRow.length; i++) {
|
||||||
|
jestRow[i]=_czyJestRow[i];
|
||||||
|
}
|
||||||
|
for (int i = 0; i < _czyJestPrzeszkodaWodna.length; i++) {
|
||||||
|
jestPrzeszkodaWodna[i]=_czyJestPrzeszkodaWodna[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
float f = this.stopienZabudowy * 255.0f;
|
||||||
|
int hex = (int)f;
|
||||||
|
String s = String.format("%02X", hex);
|
||||||
|
String linia = s;
|
||||||
|
linia += " ";
|
||||||
|
|
||||||
|
f = this.stopienZalesienia * 255.0f;
|
||||||
|
hex = (int)f;
|
||||||
|
s = String.format("%02X", hex);
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
|
||||||
|
f = this.stopienZabagnienia * 255.0f;
|
||||||
|
hex = (int)f;
|
||||||
|
s = String.format("%02X", hex);
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
|
||||||
|
f = this.stopienZawodnienia * 255.0f;
|
||||||
|
hex = (int)f;
|
||||||
|
s = String.format("%02X", hex);
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
|
||||||
|
s = String.format("%4d", this.wysokoscSrednia);
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
|
||||||
|
s = String.format("%4d", this.roznicaWzniesien);
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
|
||||||
|
int bity = 0;
|
||||||
|
int bit_1 = 1;
|
||||||
|
for (int i = 0; i < this.jestDroga.length; i++) {
|
||||||
|
if (this.jestDroga[i]) // jest odcinek drogi na tym kierunku
|
||||||
|
bity += bit_1;
|
||||||
|
|
||||||
|
bit_1 = bit_1 << 1;
|
||||||
|
}
|
||||||
|
s = String.format("%02X", bity);
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
|
||||||
|
bity = 0;
|
||||||
|
bit_1 = 1;
|
||||||
|
for (int i = 0; i < this.jestPrzeszkodaWodna.length; i++) {
|
||||||
|
if (this.jestPrzeszkodaWodna[i]) // jest przeszkod na tym kierunku
|
||||||
|
bity += bit_1;
|
||||||
|
|
||||||
|
bit_1 = bit_1 << 1;
|
||||||
|
}
|
||||||
|
s = String.format("%02X", bity);
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
|
||||||
|
bity = 0;
|
||||||
|
bit_1 = 1;
|
||||||
|
for (int i = 0; i < this.jestRow.length; i++) {
|
||||||
|
if (this.jestRow[i]) // jest row na tym kierunku
|
||||||
|
bity += bit_1;
|
||||||
|
|
||||||
|
bit_1 = bit_1 << 1;
|
||||||
|
}
|
||||||
|
s = String.format("%02X", bity);
|
||||||
|
linia += s;
|
||||||
|
return linia;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
113
src/main/java/pl/wat/ms4ds/terenfunkcje/LukDrogowy.java
Normal file
113
src/main/java/pl/wat/ms4ds/terenfunkcje/LukDrogowy.java
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
public class LukDrogowy {
|
||||||
|
|
||||||
|
private WezelDrogowy[] wezly = new WezelDrogowy[2];
|
||||||
|
int id = -1;
|
||||||
|
int dlugosc = 0;
|
||||||
|
int szerokosc = 0;
|
||||||
|
int rodzajNawierzchni = 0;
|
||||||
|
boolean jestMostem = false;
|
||||||
|
|
||||||
|
LukDrogowy() {}
|
||||||
|
|
||||||
|
LukDrogowy(String opis) {
|
||||||
|
if (null == opis || opis.length() == 0){
|
||||||
|
SiecDrogowa.logger.debug("Pusty ciag opis w konstruktorze Luku Drogowego.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StringTokenizer st = new StringTokenizer(opis, " \t");
|
||||||
|
String[] tokenTable = new String[st.countTokens()];
|
||||||
|
for (int i = 0; st.hasMoreTokens(); i++) {
|
||||||
|
tokenTable[i] = st.nextToken();
|
||||||
|
}
|
||||||
|
if (tokenTable.length == 6) {
|
||||||
|
try {
|
||||||
|
int id = Integer.parseInt(tokenTable[0]);
|
||||||
|
WezelDrogowy wezel = SiecDrogowa.instancja.wezly.get(id);
|
||||||
|
if (null == wezel)
|
||||||
|
SiecDrogowa.logger.warn("Brak wierzcholka (1) poczatkowego luku. [" + opis + "].");
|
||||||
|
this.getWezly()[0] = wezel;
|
||||||
|
wezel.luki.add(this);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
SiecDrogowa.logger.warn("Bledne dane w pliku z lukami [Wezel 1].");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int id = Integer.parseInt(tokenTable[1]);
|
||||||
|
WezelDrogowy wezel = SiecDrogowa.instancja.wezly.get(id);
|
||||||
|
if (null == wezel)
|
||||||
|
SiecDrogowa.logger.warn("Brak wierzcholka (2) koncowego luku. [" + opis + "].");
|
||||||
|
this.getWezly()[1] = wezel;
|
||||||
|
wezel.luki.add(this);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
SiecDrogowa.logger.warn("Bledne dane w pliku z lukami [Wezel 2].");
|
||||||
|
}
|
||||||
|
if (this.wezly[0].id == this.wezly[1].id) {
|
||||||
|
SiecDrogowa.logger.warn("Bledne dane w pliku z lukami [wezly sa identyczne].");
|
||||||
|
}
|
||||||
|
if (GridCoord.czyIdentyczne(this.wezly[0].idKw, this.wezly[1].idKw)) {
|
||||||
|
SiecDrogowa.logger.warn("Bledne dane w pliku z lukami [wezly sa identyczne].");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.dlugosc = Integer.parseInt(tokenTable[2]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
SiecDrogowa.logger.warn("Bledne dane w pliku z lukami [Dlugosc].");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.szerokosc = Integer.parseInt(tokenTable[3]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
SiecDrogowa.logger.warn("Bledne dane w pliku z lukami [Szerokosc].");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.rodzajNawierzchni = Integer.parseInt(tokenTable[4]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
SiecDrogowa.logger.warn("Bledne dane w pliku z lukami [RodzajNawierzchni].");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int b = Integer.parseInt(tokenTable[5]);
|
||||||
|
this.jestMostem = (b != 0);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
SiecDrogowa.logger.warn("Bledne dane w pliku z lukami [CzyJestMost].");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDlugosc() {
|
||||||
|
return dlugosc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDlugosc(int dlugosc) {
|
||||||
|
this.dlugosc = dlugosc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSzerokosc() {
|
||||||
|
return szerokosc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSzerokosc(int szerokosc) {
|
||||||
|
this.szerokosc = szerokosc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRodzajNawierzchni() {
|
||||||
|
return rodzajNawierzchni;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRodzajNawierzchni(int rodzajNawierzchni) {
|
||||||
|
this.rodzajNawierzchni = rodzajNawierzchni;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isJestMostem() {
|
||||||
|
return jestMostem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJestMostem(boolean jestMostem) {
|
||||||
|
this.jestMostem = jestMostem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WezelDrogowy[] getWezly() {
|
||||||
|
return wezly;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
242
src/main/java/pl/wat/ms4ds/terenfunkcje/MapConsts.java
Normal file
242
src/main/java/pl/wat/ms4ds/terenfunkcje/MapConsts.java
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public final class MapConsts {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(MapConsts.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Umowny uklad odniesienia dla lokalizacji geograficznej: <p>
|
||||||
|
* Długość geograficzna (wsp. X) przyjmuje wartości: [0, 360) odpowiadające [-180, 180]<p>
|
||||||
|
* Szerokość geograficzna (wsp. Y) przyjmuje wartości: [0, 180] odpowadające [-90, 90]
|
||||||
|
*/
|
||||||
|
public static final int X_REF;
|
||||||
|
/**
|
||||||
|
* Umowny uklad odniesienia dla lokalizacji geograficznej: <p>
|
||||||
|
* Długość geograficzna (wsp. X) przyjmuje wartości: [0, 360) odpowiadające [-180, 180]<p>
|
||||||
|
* Szerokość geograficzna (wsp. Y) przyjmuje wartości: [0, 180] odpowadające [-90, 90]
|
||||||
|
*/
|
||||||
|
public static final int Y_REF;
|
||||||
|
public static final int DX_REF;
|
||||||
|
public static final int DY_REF;
|
||||||
|
|
||||||
|
public static final String KWADRATY_DIR;
|
||||||
|
public static final String DROGI_DIR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nazwa pliku z konfiguracja mechanizmu odpowiedzialnego za transfer. Plik
|
||||||
|
* musi znajdowac sie w katalogu glownym aplikacji, ewentualnie musi tu byc
|
||||||
|
* podana sciezka bezwzgledna do niego.
|
||||||
|
*/
|
||||||
|
private static final String PLIK_Z_USTAWIENIAMI = "teren.properties";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dlugosc boku duzego kwadratu na osi OX w liczbie malych kwadratow.
|
||||||
|
*/
|
||||||
|
public static final int SS_PER_BS_X;
|
||||||
|
/**
|
||||||
|
* Dlugosc boku duzego kwadratu na osi OY w liczbie malych kwadratow.
|
||||||
|
*/
|
||||||
|
public static final int SS_PER_BS_Y;
|
||||||
|
/**
|
||||||
|
* Dlugosc boku malego kwadratu w metrach.
|
||||||
|
*/
|
||||||
|
public static final int DL_MK;
|
||||||
|
/**
|
||||||
|
* Powierzchnia malego kwadratu w metrach.
|
||||||
|
*/
|
||||||
|
public static final int POW_MK;
|
||||||
|
/**
|
||||||
|
* Szerokość małego kwadratu w stopniach.
|
||||||
|
*/
|
||||||
|
public static final double DELTA_X;
|
||||||
|
/**
|
||||||
|
* Wysokość małego kwadratu w stopniach.
|
||||||
|
*/
|
||||||
|
public static final double DELTA_Y;
|
||||||
|
/**
|
||||||
|
* Liczba duzych kwadratow na stopien geograficzny po osi OX (dlugosc geograficzna).
|
||||||
|
*/
|
||||||
|
public static final int BS_PER_DEG_X = 4;
|
||||||
|
/**
|
||||||
|
* Liczba duzych kwadratow na stopien geograficzny po osi OY (szerokosc geograficzna).
|
||||||
|
*/
|
||||||
|
public static final int BS_PER_DEG_Y = 6;
|
||||||
|
/**
|
||||||
|
* Szerokość duzych kwadratow w stopniach geograficznych po osi OX (dlugosc geograficzna).
|
||||||
|
*/
|
||||||
|
public static final double BS_DX;
|
||||||
|
/**
|
||||||
|
* Wysokość duzych kwadratow w stopniach geograficznych po osi OY (szerokosc geograficzna).
|
||||||
|
*/
|
||||||
|
public static final double BS_DY;
|
||||||
|
|
||||||
|
static Properties ustawienia;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Odczytanie ustawien z pliku konfiguracyjnego.
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
String propertiesFileName = System.getProperty("user.dir") + "\\" + PLIK_Z_USTAWIENIAMI;
|
||||||
|
|
||||||
|
ustawienia = new Properties();
|
||||||
|
try {
|
||||||
|
LOGGER.debug("Odczyt ustawien z pliku " + propertiesFileName + ".");
|
||||||
|
ustawienia.load(new FileInputStream(propertiesFileName));
|
||||||
|
LOGGER.debug("Ustawienia wczytane.");
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
LOGGER.error(e.getLocalizedMessage());
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.error(e.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
// logger.debug("Ustawienia wczytane.");
|
||||||
|
// przesuniecie o 180 stop.
|
||||||
|
// poludnik zerowy ma wartosc 180, zatem wspolrzedne zachodnie (ujemne) zawierają sie w <0, 180)
|
||||||
|
// wspolrzedne wschodnie (nieujemne) zawieraja sie w przedziale <180, 360)
|
||||||
|
X_REF = Integer.parseInt(ustawienia.getProperty("x_ref")) + 180;
|
||||||
|
// przesuniecie o 90 stop.
|
||||||
|
// rownik ma wartosc 90, zatem wspolrzedne poludniowe (ujemne) zawierają sie w <0, 90)
|
||||||
|
// wspolrzedne polnocne (nieujemne) zawieraja sie w przedziale <90, 180>
|
||||||
|
Y_REF = Integer.parseInt(ustawienia.getProperty("y_ref")) + 90;
|
||||||
|
DX_REF = Integer.parseInt(ustawienia.getProperty("dx_ref"));
|
||||||
|
DY_REF = Integer.parseInt(ustawienia.getProperty("dy_ref"));
|
||||||
|
String val = ustawienia.getProperty("dl_mk");
|
||||||
|
switch (val) {
|
||||||
|
case "20":
|
||||||
|
DL_MK = 20;
|
||||||
|
break;
|
||||||
|
case "25":
|
||||||
|
DL_MK = 25;
|
||||||
|
break;
|
||||||
|
case "50":
|
||||||
|
DL_MK = 50;
|
||||||
|
break;
|
||||||
|
case "100":
|
||||||
|
DL_MK = 100;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DL_MK = 200;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
POW_MK = DL_MK * DL_MK;
|
||||||
|
DROGI_DIR = ustawienia.getProperty("drogi_dir");
|
||||||
|
if (DL_MK == 20) {
|
||||||
|
SS_PER_BS_X = 83 * 10;
|
||||||
|
SS_PER_BS_Y = 93 * 10;
|
||||||
|
DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X);
|
||||||
|
DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y);
|
||||||
|
KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "20m/";
|
||||||
|
} else if (DL_MK == 25) {
|
||||||
|
SS_PER_BS_X = 83 * 8;
|
||||||
|
SS_PER_BS_Y = 93 * 8;
|
||||||
|
DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X);
|
||||||
|
DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y);
|
||||||
|
KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "25m/";
|
||||||
|
} else if (DL_MK == 50) {
|
||||||
|
SS_PER_BS_X = 83 * 4;
|
||||||
|
SS_PER_BS_Y = 93 * 4;
|
||||||
|
DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X);
|
||||||
|
DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y);
|
||||||
|
KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "50m/";
|
||||||
|
} else if (DL_MK == 100) {
|
||||||
|
SS_PER_BS_X = 83 * 2;
|
||||||
|
SS_PER_BS_Y = 93 * 2;
|
||||||
|
DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X);
|
||||||
|
DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y);
|
||||||
|
KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "100m/";
|
||||||
|
} else {
|
||||||
|
// domyslnie dlugosc kwadratu 200m
|
||||||
|
SS_PER_BS_X = 83;
|
||||||
|
SS_PER_BS_Y = 93;
|
||||||
|
DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X);
|
||||||
|
DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y);
|
||||||
|
KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "200m/";
|
||||||
|
}
|
||||||
|
BS_DX = 1.0 / (double) BS_PER_DEG_X;
|
||||||
|
BS_DY = 1.0 / (double) BS_PER_DEG_Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liczba milisekund na stopien.
|
||||||
|
*/
|
||||||
|
public static final int DEG_MS = 3600000;
|
||||||
|
/**
|
||||||
|
* Liczba milisekund na 360 stopni.
|
||||||
|
*/
|
||||||
|
public static final long ANGLE_360_MS = 3600000 * 360;
|
||||||
|
/**
|
||||||
|
* Wielkosc cache'u pola walki (liczba duzych kwadratow trzymanych w RAM).
|
||||||
|
*/
|
||||||
|
public static final int MAX_BIG_SQUARES_IN_MEMORY = 500;
|
||||||
|
/**
|
||||||
|
* Wspolrzedna referencyjna X (dlugosc geograficzna) lewego dolnego rogu mapy w stopniach geograficznych.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int getX_REF() {
|
||||||
|
return X_REF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wspolrzedna referencyjna Y (szerokosc geograficzna) lewego dolnego rogu mapy w stopniach geograficznych.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int getY_REF() {
|
||||||
|
return Y_REF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Szerokosc referencyjna prostokata pola walki w stopniach na osi OX (dlugosc geograficzna).
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int getDX_REF() {
|
||||||
|
return DX_REF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wysokosc referencyjna prostokata pola walki w stopniach na osi OY (szerokosc geograficzna).
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int getDY_REF() {
|
||||||
|
return DY_REF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getKwadratyDir() {
|
||||||
|
return KWADRATY_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDrogiDir() {
|
||||||
|
return DROGI_DIR;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Dlugosci bokow malego kwadratu w milisekundach geograficznych po osi OX (dlugosc geograficzna).
|
||||||
|
*/
|
||||||
|
public static final double SS_DX_MS = DELTA_X * DEG_MS;
|
||||||
|
/**
|
||||||
|
* Dlugosci bokow malego kwadratu w milisekundach geograficznych po osi OY (szerokosc geograficzna).
|
||||||
|
*/
|
||||||
|
public static final double SS_DY_MS = DELTA_Y * DEG_MS;
|
||||||
|
// wspolrzedne dolnego lewego rogu mapy w ms
|
||||||
|
// wspolrzedne geograficzne w milisekundach zawieraja sie w zakresie:
|
||||||
|
// 0 <= x < 360 dlugosc geograficzna
|
||||||
|
// 0 <= y <= 180 szerokosc geograficzna
|
||||||
|
public static final int X_REF_MS = X_REF * DEG_MS;
|
||||||
|
public static final int Y_REF_MS = Y_REF * DEG_MS;
|
||||||
|
public static final int DX_REF_MS = DEG_MS * DX_REF; // szerokosc pola walki w stopniach
|
||||||
|
public static final int DY_REF_MS = DEG_MS * DY_REF; // wysokosc polwa walki w stopniach
|
||||||
|
|
||||||
|
public static final int BS_DX_MS = (int) (BS_DX * DEG_MS);
|
||||||
|
public static final int BS_DY_MS = (int) (BS_DY * DEG_MS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liczba malych kwadratow przypadajaca na bok arkusza mapy drogowej.
|
||||||
|
*/
|
||||||
|
public static final int SS_PER_SHEET = 20;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
640
src/main/java/pl/wat/ms4ds/terenfunkcje/RightBigSquare.java
Normal file
640
src/main/java/pl/wat/ms4ds/terenfunkcje/RightBigSquare.java
Normal file
@@ -0,0 +1,640 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class RightBigSquare extends BigSquare implements Serializable {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(RightBigSquare.class);
|
||||||
|
|
||||||
|
private Kwadrat kwadraty[][];
|
||||||
|
|
||||||
|
Kwadrat getKwadrat(int ssX, int ssY) {
|
||||||
|
return kwadraty[ssX][ssY];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja zapisująca do pliku duży kwadrat.<p>
|
||||||
|
* Zapis następuje w trybie wskazywanym przez atrybut: RightBigSquare.binary.
|
||||||
|
*
|
||||||
|
* @param wymuszony flag informujacy o trybie zapisu pliku
|
||||||
|
* @param fName nazwa pliku
|
||||||
|
* @throws IOException generowany wyjątek
|
||||||
|
*/
|
||||||
|
void updateFile(boolean wymuszony, String fName) throws IOException {
|
||||||
|
if (wymuszony) {
|
||||||
|
if (this.liczbaZmian == 0) {
|
||||||
|
// nie bylo modyfikacji od ostatniego zapisu
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.liczbaZmian = -1;
|
||||||
|
}
|
||||||
|
this.liczbaZmian++;
|
||||||
|
this.liczbaZmian %= LICZBA_ZMIAN_DO_ZAPISU;
|
||||||
|
if (this.liczbaZmian > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fName != null) {
|
||||||
|
fileName = fName;
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder(100);
|
||||||
|
sb.append(MapConsts.KWADRATY_DIR);
|
||||||
|
sb.append(fileName);
|
||||||
|
sb.append(".bin");
|
||||||
|
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString()));
|
||||||
|
for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) {
|
||||||
|
for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) {
|
||||||
|
float f = kwadraty[x][y].stopienZalesienia * 100.0f;
|
||||||
|
int hex = (int) f;
|
||||||
|
hex = (hex > 100) ? 100 : hex;
|
||||||
|
hex = (hex < 0) ? 0 : hex;
|
||||||
|
out.writeByte(hex);
|
||||||
|
f = kwadraty[x][y].stopienZawodnienia * 100.0f;
|
||||||
|
hex = (int) f;
|
||||||
|
hex = (hex > 100) ? 100 : hex;
|
||||||
|
hex = (hex < 0) ? 0 : hex;
|
||||||
|
out.writeByte(hex);
|
||||||
|
f = kwadraty[x][y].stopienZabudowy * 100.0f;
|
||||||
|
hex = (int) f;
|
||||||
|
hex = (hex > 100) ? 100 : hex;
|
||||||
|
hex = (hex < 0) ? 0 : hex;
|
||||||
|
out.writeByte(hex);
|
||||||
|
f = kwadraty[x][y].stopienZabagnienia * 100.0f;
|
||||||
|
hex = (int) f;
|
||||||
|
hex = (hex > 100) ? 100 : hex;
|
||||||
|
hex = (hex < 0) ? 0 : hex;
|
||||||
|
out.writeByte(hex);
|
||||||
|
out.writeInt(kwadraty[x][y].wysokoscSrednia);
|
||||||
|
out.writeInt(kwadraty[x][y].roznicaWzniesien);
|
||||||
|
|
||||||
|
hex = 0;
|
||||||
|
int bit_1 = 1;
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestDroga.length; i++) {
|
||||||
|
// jest odcinek drogi na tym kierunku
|
||||||
|
if (kwadraty[x][y].jestDroga[i]) {
|
||||||
|
hex |= bit_1;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
out.writeByte(hex);
|
||||||
|
|
||||||
|
hex = 0;
|
||||||
|
bit_1 = 1;
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestPrzeszkodaWodna.length; i++) {
|
||||||
|
// jest odcinek przeszkody wodnej na tym kierunku
|
||||||
|
if (kwadraty[x][y].jestPrzeszkodaWodna[i]) {
|
||||||
|
hex |= bit_1;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
out.writeByte(hex);
|
||||||
|
|
||||||
|
hex = 0;
|
||||||
|
bit_1 = 1;
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestRow.length; i++) {
|
||||||
|
// jest odcinek rowu na tym kierunku
|
||||||
|
if (kwadraty[x][y].jestRow[i]) {
|
||||||
|
hex |= bit_1;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
out.writeByte(hex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
logger.debug("Zapisano plik mapy: " + sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
static final int NORTH = 0;
|
||||||
|
static final int NORTH_EAST = 1;
|
||||||
|
static final int EAST = 2;
|
||||||
|
static final int SOUTH_EAST = 3;
|
||||||
|
static final int SOUTH = 4;
|
||||||
|
static final int SOUTH_WEST = 5;
|
||||||
|
static final int WEST = 6;
|
||||||
|
static final int NORTH_WEST = 7;
|
||||||
|
static final byte NORTH_CODE = 1;
|
||||||
|
static final byte NORTH_EAST_CODE = 2;
|
||||||
|
static final byte EAST_CODE = 4;
|
||||||
|
static final byte SOUTH_EAST_CODE = 8;
|
||||||
|
static final byte SOUTH_CODE = 16;
|
||||||
|
static final byte SOUTH_WEST_CODE = 32;
|
||||||
|
static final byte WEST_CODE = 64;
|
||||||
|
static final byte NORTH_WEST_CODE = -128;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja generuje nowy plik z danymi na podstawie danych z pliku referencyjnego (kwadraty o rozm. 200m).
|
||||||
|
* <p>Nowy plik moze byc z danymi w innej skali (kwadraty o rozmiarach: 100m lub 50m) i/lub innym formacie (binarny, tekstowy).
|
||||||
|
*
|
||||||
|
* @param dir katalog docelowy dla nowego pliku
|
||||||
|
* @param dlmk rozmiar kwadratow generownych danych
|
||||||
|
* @throws IOException generowany wyjątek
|
||||||
|
*/
|
||||||
|
public void saveNewFileWithNewScale(String dir, int dlmk) throws IOException {
|
||||||
|
if (MapConsts.DL_MK != 100) {
|
||||||
|
// operacja tylko dla danych terenowych o kwadratach 200m
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int m = 1;
|
||||||
|
String s = "";
|
||||||
|
if (dlmk == 100) {
|
||||||
|
m = 1;
|
||||||
|
s = "100m/";
|
||||||
|
} else if (dlmk == 50) {
|
||||||
|
m = 2;
|
||||||
|
s = "50m/";
|
||||||
|
} else if (dlmk == 25) {
|
||||||
|
m = 4;
|
||||||
|
s = "25m/";
|
||||||
|
} else if (dlmk == 20) {
|
||||||
|
m = 5;
|
||||||
|
s = "20m/";
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder(100);
|
||||||
|
sb.append(dir);
|
||||||
|
sb.append(s);
|
||||||
|
// Utworzenie katalogów, gdyby nie istniały.
|
||||||
|
File directory = new File(sb.toString());
|
||||||
|
directory.mkdirs();
|
||||||
|
sb.append(fileName);
|
||||||
|
sb.append(".bin");
|
||||||
|
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString()));
|
||||||
|
|
||||||
|
SmallSquare[][][][] ss_all = new SmallSquare[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y][][];
|
||||||
|
for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) {
|
||||||
|
for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) {
|
||||||
|
SmallSquare[][] ss = new SmallSquare[m][m];
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
for (int j = 0; j < m; j++) {
|
||||||
|
ss[i][j] = new SmallSquare();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ss_all[x][y] = ss;
|
||||||
|
// jest odcinek drogi na tym kierunku
|
||||||
|
if (kwadraty[x][y].jestDroga[NORTH]) {
|
||||||
|
ss[2][2].majorRoads |= NORTH_CODE;
|
||||||
|
ss[2][3].majorRoads |= NORTH_CODE | SOUTH_CODE;
|
||||||
|
ss[2][4].majorRoads |= NORTH_CODE | SOUTH_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestDroga[NORTH_EAST]) {
|
||||||
|
ss[2][2].majorRoads |= NORTH_EAST_CODE;
|
||||||
|
ss[3][3].majorRoads |= NORTH_EAST_CODE | SOUTH_WEST_CODE;
|
||||||
|
ss[4][4].majorRoads |= NORTH_EAST_CODE | SOUTH_WEST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestDroga[EAST]) {
|
||||||
|
ss[2][2].majorRoads |= EAST_CODE;
|
||||||
|
ss[3][2].majorRoads |= EAST_CODE | WEST_CODE;
|
||||||
|
ss[4][2].majorRoads |= EAST_CODE | WEST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestDroga[SOUTH_EAST]) {
|
||||||
|
ss[2][2].majorRoads |= SOUTH_EAST_CODE;
|
||||||
|
ss[3][1].majorRoads |= SOUTH_EAST_CODE | NORTH_WEST_CODE;
|
||||||
|
ss[4][0].majorRoads |= SOUTH_EAST_CODE | NORTH_WEST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestDroga[SOUTH]) {
|
||||||
|
ss[2][2].majorRoads |= SOUTH_CODE;
|
||||||
|
ss[2][1].majorRoads |= SOUTH_CODE | NORTH_CODE;
|
||||||
|
ss[2][0].majorRoads |= SOUTH_CODE | NORTH_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestDroga[SOUTH_WEST]) {
|
||||||
|
ss[2][2].majorRoads |= SOUTH_WEST_CODE;
|
||||||
|
ss[1][1].majorRoads |= SOUTH_WEST_CODE | NORTH_EAST_CODE;
|
||||||
|
ss[0][0].majorRoads |= SOUTH_WEST_CODE | NORTH_EAST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestDroga[WEST]) {
|
||||||
|
ss[2][2].majorRoads |= WEST_CODE;
|
||||||
|
ss[1][2].majorRoads |= WEST_CODE | EAST_CODE;
|
||||||
|
ss[0][2].majorRoads |= WEST_CODE | EAST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestDroga[NORTH_WEST]) {
|
||||||
|
ss[2][2].majorRoads |= NORTH_WEST_CODE;
|
||||||
|
ss[1][3].majorRoads |= NORTH_WEST_CODE | SOUTH_EAST_CODE;
|
||||||
|
ss[0][4].majorRoads |= NORTH_WEST_CODE | SOUTH_EAST_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// jest odcinek rzeki na tym kierunku
|
||||||
|
if (kwadraty[x][y].jestPrzeszkodaWodna[NORTH]) {
|
||||||
|
ss[2][2].rivers |= NORTH_CODE;
|
||||||
|
ss[2][3].rivers |= NORTH_CODE | SOUTH_CODE;
|
||||||
|
ss[2][4].rivers |= NORTH_CODE | SOUTH_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestPrzeszkodaWodna[NORTH_EAST]) {
|
||||||
|
ss[2][2].rivers |= NORTH_EAST_CODE;
|
||||||
|
ss[3][3].rivers |= NORTH_EAST_CODE | SOUTH_WEST_CODE;
|
||||||
|
ss[4][4].rivers |= NORTH_EAST_CODE | SOUTH_WEST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestPrzeszkodaWodna[EAST]) {
|
||||||
|
ss[2][2].rivers |= EAST_CODE;
|
||||||
|
ss[3][2].rivers |= EAST_CODE | WEST_CODE;
|
||||||
|
ss[4][2].rivers |= EAST_CODE | WEST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestPrzeszkodaWodna[SOUTH_EAST]) {
|
||||||
|
ss[2][2].rivers |= SOUTH_EAST_CODE;
|
||||||
|
ss[3][1].rivers |= SOUTH_EAST_CODE | NORTH_WEST_CODE;
|
||||||
|
ss[4][0].rivers |= SOUTH_EAST_CODE | NORTH_WEST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestPrzeszkodaWodna[SOUTH]) {
|
||||||
|
ss[2][2].rivers |= SOUTH_CODE;
|
||||||
|
ss[2][1].rivers |= SOUTH_CODE | NORTH_CODE;
|
||||||
|
ss[2][0].rivers |= SOUTH_CODE | NORTH_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestPrzeszkodaWodna[SOUTH_WEST]) {
|
||||||
|
ss[2][2].rivers |= SOUTH_WEST_CODE;
|
||||||
|
ss[1][1].rivers |= SOUTH_WEST_CODE | NORTH_EAST_CODE;
|
||||||
|
ss[0][0].rivers |= SOUTH_WEST_CODE | NORTH_EAST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestPrzeszkodaWodna[WEST]) {
|
||||||
|
ss[2][2].rivers |= WEST_CODE;
|
||||||
|
ss[1][2].rivers |= WEST_CODE | EAST_CODE;
|
||||||
|
ss[0][2].rivers |= WEST_CODE | EAST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestPrzeszkodaWodna[NORTH_WEST]) {
|
||||||
|
ss[2][2].rivers |= NORTH_WEST_CODE;
|
||||||
|
ss[1][3].rivers |= NORTH_WEST_CODE | SOUTH_EAST_CODE;
|
||||||
|
ss[0][4].rivers |= NORTH_WEST_CODE | SOUTH_EAST_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// jest odcinek rowu na tym kierunku
|
||||||
|
if (kwadraty[x][y].jestRow[NORTH]) {
|
||||||
|
ss[2][2].drains |= NORTH_CODE;
|
||||||
|
ss[2][3].drains |= NORTH_CODE | SOUTH_CODE;
|
||||||
|
ss[2][4].drains |= NORTH_CODE | SOUTH_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestRow[NORTH_EAST]) {
|
||||||
|
ss[2][2].drains |= NORTH_EAST_CODE;
|
||||||
|
ss[3][3].drains |= NORTH_EAST_CODE | SOUTH_WEST_CODE;
|
||||||
|
ss[4][4].drains |= NORTH_EAST_CODE | SOUTH_WEST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestRow[EAST]) {
|
||||||
|
ss[2][2].drains |= EAST_CODE;
|
||||||
|
ss[3][2].drains |= EAST_CODE | WEST_CODE;
|
||||||
|
ss[4][2].drains |= EAST_CODE | WEST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestRow[SOUTH_EAST]) {
|
||||||
|
ss[2][2].drains |= SOUTH_EAST_CODE;
|
||||||
|
ss[3][1].drains |= SOUTH_EAST_CODE | NORTH_WEST_CODE;
|
||||||
|
ss[4][0].drains |= SOUTH_EAST_CODE | NORTH_WEST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestRow[SOUTH]) {
|
||||||
|
ss[2][2].drains |= SOUTH_CODE;
|
||||||
|
ss[2][1].drains |= SOUTH_CODE | NORTH_CODE;
|
||||||
|
ss[2][0].drains |= SOUTH_CODE | NORTH_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestRow[SOUTH_WEST]) {
|
||||||
|
ss[2][2].drains |= SOUTH_WEST_CODE;
|
||||||
|
ss[1][1].drains |= SOUTH_WEST_CODE | NORTH_EAST_CODE;
|
||||||
|
ss[0][0].drains |= SOUTH_WEST_CODE | NORTH_EAST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestRow[WEST]) {
|
||||||
|
ss[2][2].drains |= WEST_CODE;
|
||||||
|
ss[1][2].drains |= WEST_CODE | EAST_CODE;
|
||||||
|
ss[0][2].drains |= WEST_CODE | EAST_CODE;
|
||||||
|
}
|
||||||
|
if (kwadraty[x][y].jestRow[NORTH_WEST]) {
|
||||||
|
ss[2][2].drains |= NORTH_WEST_CODE;
|
||||||
|
ss[1][3].drains |= NORTH_WEST_CODE | SOUTH_EAST_CODE;
|
||||||
|
ss[0][4].drains |= NORTH_WEST_CODE | SOUTH_EAST_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
for (int j = 0; j < m; j++) {
|
||||||
|
int hex = 0;
|
||||||
|
if (kwadraty[x][y].stopienZalesienia > 0) {
|
||||||
|
hex = TerrainType.FOREST.ID;
|
||||||
|
} else if (kwadraty[x][y].stopienZawodnienia > 0) {
|
||||||
|
hex = TerrainType.WATER.ID;
|
||||||
|
} else if (kwadraty[x][y].stopienZabudowy > 0) {
|
||||||
|
hex = TerrainType.BUILDINGS.ID;
|
||||||
|
} else if (kwadraty[x][y].stopienZabagnienia > 0) {
|
||||||
|
hex = TerrainType.SWAMP.ID;
|
||||||
|
}
|
||||||
|
ss[i][j].terrainType = (byte) hex;
|
||||||
|
ss[i][j].elevation = (short) kwadraty[x][y].wysokoscSrednia;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) {
|
||||||
|
for (int i = 0; i < m; i++) {
|
||||||
|
for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) {
|
||||||
|
for (int j = 0; j < m; j++) {
|
||||||
|
ss_all[x][y][i][j].save(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
logger.debug("Zapisano nowy plik mapy: " + sb + " dla rozmiaru MK= " + dlmk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void load(String FName) throws IOException {
|
||||||
|
try {
|
||||||
|
fileName = FName;
|
||||||
|
StringBuilder sb = new StringBuilder(100);
|
||||||
|
sb.append(MapConsts.KWADRATY_DIR);
|
||||||
|
sb.append(fileName);
|
||||||
|
sb.append(".bin");
|
||||||
|
SmallSquare ss = new SmallSquare();
|
||||||
|
ObjectInputStream in = new ObjectInputStream(new FileInputStream(sb.toString()));
|
||||||
|
kwadraty = new Kwadrat[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y];
|
||||||
|
for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) {
|
||||||
|
for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) {
|
||||||
|
kwadraty[x][y] = new Kwadrat();
|
||||||
|
ss.load(in);
|
||||||
|
switch (ss.terrainType) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
kwadraty[x][y].stopienZabagnienia = 1.f;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
kwadraty[x][y].stopienZawodnienia = 1.f;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
kwadraty[x][y].stopienZabudowy = 1.f;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
kwadraty[x][y].stopienZalesienia = 1.f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
kwadraty[x][y].wysokoscSrednia = ss.elevation;
|
||||||
|
kwadraty[x][y].roznicaWzniesien = 0;
|
||||||
|
|
||||||
|
int bit_1 = 1;
|
||||||
|
int hex = ss.majorRoads;
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestDroga.length; i++) {
|
||||||
|
// jest odcinek rowu na tym kierunku
|
||||||
|
if ((hex & bit_1) != 0) {
|
||||||
|
kwadraty[x][y].jestDroga[i] = true;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
bit_1 = 1;
|
||||||
|
hex = ss.rivers;
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestPrzeszkodaWodna.length; i++) {
|
||||||
|
// jest odcinek rowu na tym kierunku
|
||||||
|
if ((hex & bit_1) != 0) {
|
||||||
|
kwadraty[x][y].jestPrzeszkodaWodna[i] = true;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
bit_1 = 1;
|
||||||
|
hex = ss.drains;
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestRow.length; i++) {
|
||||||
|
// jest odcinek rowu na tym kierunku
|
||||||
|
if ((hex & bit_1) != 0) {
|
||||||
|
kwadraty[x][y].jestRow[i] = true;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
kwadraty[x][y].bs = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in.close();
|
||||||
|
logger.debug("Doczytano plik mapy: " + sb.toString());
|
||||||
|
} catch (IOException e) {
|
||||||
|
kwadraty = null;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja generuje nowy plik z danymi na podstawie danych z pliku referencyjnego (kwadraty o rozm. 200m).
|
||||||
|
* <p>Nowy plik moze byc z danymi w innej skali (kwadraty o rozmiarach: 100m lub 50m) i/lub innym formacie (binarny, tekstowy).
|
||||||
|
*
|
||||||
|
* @param dir katalog docelowy dla nowego pliku
|
||||||
|
* @param dlmk rozmiar kwadratow generownych danych
|
||||||
|
* @throws IOException generowany wyjątek
|
||||||
|
*/
|
||||||
|
public void saveNewFileWithNewScale_old_format(String dir, int dlmk,
|
||||||
|
boolean zalesienie, boolean zawodnienie, boolean zabudowa, boolean zabagnienie,
|
||||||
|
boolean wysokosc, boolean roznicaWzniesien, boolean drogi,
|
||||||
|
boolean rzeki, boolean rowy) throws IOException {
|
||||||
|
if (MapConsts.DL_MK != 200) {
|
||||||
|
// operacja tylko dla danych terenowych o kwadratach 200m
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int m = 1;
|
||||||
|
String s = "";
|
||||||
|
if (dlmk == 200) {
|
||||||
|
m = 1;
|
||||||
|
s = "200m/";
|
||||||
|
} else if (dlmk == 100) {
|
||||||
|
m = 2;
|
||||||
|
s = "100m/";
|
||||||
|
} else if (dlmk == 50) {
|
||||||
|
m = 4;
|
||||||
|
s = "50m/";
|
||||||
|
} else if (dlmk == 25) {
|
||||||
|
m = 8;
|
||||||
|
s = "25m/";
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder(100);
|
||||||
|
sb.append(dir);
|
||||||
|
sb.append(s);
|
||||||
|
// Utworzenie katalogów, gdyby nie istniały.
|
||||||
|
File directory = new File(sb.toString());
|
||||||
|
directory.mkdirs();
|
||||||
|
sb.append(fileName);
|
||||||
|
sb.append(".bin");
|
||||||
|
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString()));
|
||||||
|
for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) {
|
||||||
|
for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) {
|
||||||
|
for (int k = 0; k < m * m; k++) {
|
||||||
|
float f;
|
||||||
|
int hex = 0;
|
||||||
|
if (zalesienie) {
|
||||||
|
f = kwadraty[x][y].stopienZalesienia * 100.0f;
|
||||||
|
hex = (int) f;
|
||||||
|
hex = (hex > 100) ? 100 : hex;
|
||||||
|
hex = (hex < 0) ? 0 : hex;
|
||||||
|
}
|
||||||
|
out.writeByte(hex);
|
||||||
|
hex = 0;
|
||||||
|
if (zawodnienie) {
|
||||||
|
f = kwadraty[x][y].stopienZawodnienia * 100.0f;
|
||||||
|
hex = (int) f;
|
||||||
|
hex = (hex > 100) ? 100 : hex;
|
||||||
|
hex = (hex < 0) ? 0 : hex;
|
||||||
|
}
|
||||||
|
out.writeByte(hex);
|
||||||
|
hex = 0;
|
||||||
|
if (zabudowa) {
|
||||||
|
f = kwadraty[x][y].stopienZabudowy * 100.0f;
|
||||||
|
hex = (int) f;
|
||||||
|
hex = (hex > 100) ? 100 : hex;
|
||||||
|
hex = (hex < 0) ? 0 : hex;
|
||||||
|
}
|
||||||
|
out.writeByte(hex);
|
||||||
|
hex = 0;
|
||||||
|
if (zabagnienie) {
|
||||||
|
f = kwadraty[x][y].stopienZabagnienia * 100.0f;
|
||||||
|
hex = (int) f;
|
||||||
|
hex = (hex > 100) ? 100 : hex;
|
||||||
|
hex = (hex < 0) ? 0 : hex;
|
||||||
|
}
|
||||||
|
out.writeByte(hex);
|
||||||
|
if (wysokosc) {
|
||||||
|
out.writeInt(kwadraty[x][y].wysokoscSrednia);
|
||||||
|
} else {
|
||||||
|
out.writeInt(0);
|
||||||
|
}
|
||||||
|
if (roznicaWzniesien) {
|
||||||
|
out.writeInt(kwadraty[x][y].roznicaWzniesien);
|
||||||
|
} else {
|
||||||
|
out.writeInt(0);
|
||||||
|
}
|
||||||
|
int bit_1;
|
||||||
|
hex = 0;
|
||||||
|
if (drogi) {
|
||||||
|
bit_1 = 1;
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestDroga.length; i++) {
|
||||||
|
// jest odcinek drogi na tym kierunku
|
||||||
|
if (kwadraty[x][y].jestDroga[i]) {
|
||||||
|
hex |= bit_1;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.writeByte(hex);
|
||||||
|
hex = 0;
|
||||||
|
if (rzeki) {
|
||||||
|
bit_1 = 1;
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestPrzeszkodaWodna.length; i++) {
|
||||||
|
// jest odcinek przeszkody wodnej na tym kierunku
|
||||||
|
if (kwadraty[x][y].jestPrzeszkodaWodna[i]) {
|
||||||
|
hex |= bit_1;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.writeByte(hex);
|
||||||
|
hex = 0;
|
||||||
|
if (rowy) {
|
||||||
|
bit_1 = 1;
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestRow.length; i++) {
|
||||||
|
// jest odcinek rowu na tym kierunku
|
||||||
|
if (kwadraty[x][y].jestRow[i]) {
|
||||||
|
hex |= bit_1;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.writeByte(hex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
logger.debug("Zapisano nowy plik mapy: " + sb.toString() + " dla rozmiaru MK= " + dlmk);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public RightBigSquare() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// konstruktor ladujacy duzy kwadrat z pliku binarnego
|
||||||
|
RightBigSquare(String FName) throws IOException {
|
||||||
|
try {
|
||||||
|
fileName = FName;
|
||||||
|
StringBuilder sb = new StringBuilder(100);
|
||||||
|
sb.append(MapConsts.KWADRATY_DIR);
|
||||||
|
sb.append(fileName);
|
||||||
|
sb.append(".bin");
|
||||||
|
ObjectInputStream in = new ObjectInputStream(new FileInputStream(sb.toString()));
|
||||||
|
kwadraty = new Kwadrat[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y];
|
||||||
|
for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) {
|
||||||
|
for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) {
|
||||||
|
kwadraty[x][y] = new Kwadrat();
|
||||||
|
int hex = in.readByte();
|
||||||
|
kwadraty[x][y].stopienZalesienia = (float) hex * (1.0f / 100.f);
|
||||||
|
hex = in.readByte();
|
||||||
|
kwadraty[x][y].stopienZawodnienia = (float) hex * (1.0f / 100.f);
|
||||||
|
hex = in.readByte();
|
||||||
|
kwadraty[x][y].stopienZabudowy = (float) hex * (1.0f / 100.f);
|
||||||
|
hex = in.readByte();
|
||||||
|
kwadraty[x][y].stopienZabagnienia = (float) hex * (1.0f / 100.f);
|
||||||
|
kwadraty[x][y].wysokoscSrednia = in.readInt();
|
||||||
|
kwadraty[x][y].roznicaWzniesien = in.readInt();
|
||||||
|
int bit_1 = 1;
|
||||||
|
hex = in.readByte();
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestDroga.length; i++) {
|
||||||
|
// jest odcinek rowu na tym kierunku
|
||||||
|
if ((hex & bit_1) != 0) {
|
||||||
|
kwadraty[x][y].jestDroga[i] = true;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
bit_1 = 1;
|
||||||
|
hex = in.readByte();
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestPrzeszkodaWodna.length; i++) {
|
||||||
|
// jest odcinek rowu na tym kierunku
|
||||||
|
if ((hex & bit_1) != 0) {
|
||||||
|
kwadraty[x][y].jestPrzeszkodaWodna[i] = true;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
bit_1 = 1;
|
||||||
|
hex = in.readByte();
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestRow.length; i++) {
|
||||||
|
// jest odcinek rowu na tym kierunku
|
||||||
|
if ((hex & bit_1) != 0) {
|
||||||
|
kwadraty[x][y].jestRow[i] = true;
|
||||||
|
}
|
||||||
|
bit_1 <<= 1;
|
||||||
|
}
|
||||||
|
kwadraty[x][y].bs = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in.close();
|
||||||
|
logger.debug("Doczytano plik mapy: " + sb.toString());
|
||||||
|
} catch (IOException e) {
|
||||||
|
kwadraty = null;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetSquares(boolean zalesienie, boolean zawodnienie, boolean zabudowa, boolean zabagnienie,
|
||||||
|
boolean wysokosc, boolean roznicaWzniesien, boolean drogi, boolean rzeki, boolean rowy) {
|
||||||
|
for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) {
|
||||||
|
for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) {
|
||||||
|
kwadraty[x][y].stopienZalesienia = (zalesienie) ? 0 : kwadraty[x][y].stopienZalesienia;
|
||||||
|
kwadraty[x][y].stopienZawodnienia = (zawodnienie) ? 0 : kwadraty[x][y].stopienZawodnienia;
|
||||||
|
kwadraty[x][y].stopienZabudowy = (zabudowa) ? 0 : kwadraty[x][y].stopienZabudowy;
|
||||||
|
kwadraty[x][y].stopienZabagnienia = (zabagnienie) ? 0 : kwadraty[x][y].stopienZabagnienia;
|
||||||
|
kwadraty[x][y].wysokoscSrednia = (wysokosc) ? 0 : kwadraty[x][y].wysokoscSrednia;
|
||||||
|
kwadraty[x][y].roznicaWzniesien = (roznicaWzniesien) ? 0 : kwadraty[x][y].roznicaWzniesien;
|
||||||
|
if (drogi) {
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestDroga.length; i++) {
|
||||||
|
kwadraty[x][y].jestDroga[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rzeki) {
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestPrzeszkodaWodna.length; i++) {
|
||||||
|
kwadraty[x][y].jestPrzeszkodaWodna[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rowy) {
|
||||||
|
for (int i = 0; i < kwadraty[x][y].jestRow.length; i++) {
|
||||||
|
kwadraty[x][y].jestRow[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "RightBigSquare{" + this.fileName + '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
364
src/main/java/pl/wat/ms4ds/terenfunkcje/SiecDrogowa.java
Normal file
364
src/main/java/pl/wat/ms4ds/terenfunkcje/SiecDrogowa.java
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import pl.wat.ms4ds.common.EGeoDirection;
|
||||||
|
|
||||||
|
public class SiecDrogowa {
|
||||||
|
|
||||||
|
static final Logger logger = LoggerFactory.getLogger(SiecDrogowa.class);
|
||||||
|
|
||||||
|
ArrayList<LukDrogowy> luki;
|
||||||
|
ArrayList<WezelDrogowy> wezly;
|
||||||
|
static SiecDrogowa instancja;
|
||||||
|
static String path;
|
||||||
|
|
||||||
|
Arkusz[][] arkusze;
|
||||||
|
|
||||||
|
public int liczbaZmian = 0;
|
||||||
|
static final int LICZBA_ZMIAN = 50;
|
||||||
|
|
||||||
|
SiecDrogowa(String dataPath) {
|
||||||
|
instancja = this;
|
||||||
|
// File wd = new File(".");
|
||||||
|
// PATH = wd.getPath();
|
||||||
|
path = dataPath;
|
||||||
|
this.odczytajWezly(path + "/nodes.txt");
|
||||||
|
logger.debug("wczytano " + this.wezly.size() + " wezlow.");
|
||||||
|
this.odczytajLuki(path + "/arcs.txt");
|
||||||
|
logger.debug("wczytano " + this.luki.size() + " lukow.");
|
||||||
|
stworzArkusze();
|
||||||
|
|
||||||
|
|
||||||
|
// logger.debug("Liczba lukow w arkuszach:");
|
||||||
|
// int ll = 0;
|
||||||
|
// for (int i = 0; i < Arkusz.lx; i++) {
|
||||||
|
// for (int j = 0; j < Arkusz.ly; j++) {
|
||||||
|
// logger.debug(String.format("(%1$2d, %2$2d) - %3$6d", i, j, this.arkusze[i][j].luki.size()));
|
||||||
|
// ll += this.arkusze[i][j].luki.size();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// logger.debug("Sum. liczba lukow w arkuszach:" + ll);
|
||||||
|
}
|
||||||
|
|
||||||
|
void odczytajWezly(String fname) {
|
||||||
|
try {
|
||||||
|
FileReader fis = new FileReader(fname);
|
||||||
|
BufferedReader br = new BufferedReader(fis);
|
||||||
|
if (br.ready()) {
|
||||||
|
String line = br.readLine().trim();
|
||||||
|
int licz = Integer.parseInt(line);
|
||||||
|
this.wezly = new ArrayList<WezelDrogowy>(licz);// + 1000);
|
||||||
|
while (null != (line = br.readLine())) {
|
||||||
|
WezelDrogowy nowyWezel = new WezelDrogowy(line);
|
||||||
|
nowyWezel.id = this.wezly.size(); //Indeksowanie od 0
|
||||||
|
this.wezly.add(nowyWezel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
br.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.warn("Brak pliku z wezlami: " + fname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void odczytajLuki(String fname) {
|
||||||
|
try {
|
||||||
|
FileReader fis = new FileReader(fname);
|
||||||
|
BufferedReader br = new BufferedReader(fis);
|
||||||
|
if (br.ready()) {
|
||||||
|
String line = br.readLine().trim();
|
||||||
|
int licz = Integer.parseInt(line);
|
||||||
|
this.luki = new ArrayList<LukDrogowy>(licz);// + 1000);
|
||||||
|
while (null != (line = br.readLine())) {
|
||||||
|
LukDrogowy nowyLuk = new LukDrogowy(line);
|
||||||
|
nowyLuk.id = this.luki.size(); //Indeksowanie od 0
|
||||||
|
this.luki.add(nowyLuk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
br.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.warn("Brak pliku z lukami: " + fname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stworzArkusze() {
|
||||||
|
// wyznaczenie wymiarow pola walki w malych kwadratach
|
||||||
|
Arkusz.lx = MapConsts.getDX_REF() * MapConsts.BS_PER_DEG_X * MapConsts.SS_PER_BS_X;
|
||||||
|
Arkusz.ly = MapConsts.getDY_REF() * MapConsts.BS_PER_DEG_Y * MapConsts.SS_PER_BS_Y;
|
||||||
|
// wyznacznie liczby arkuszy mapy w obu wymiarach
|
||||||
|
Arkusz.lx = Arkusz.lx / MapConsts.SS_PER_SHEET + 1;
|
||||||
|
Arkusz.ly = Arkusz.ly / MapConsts.SS_PER_SHEET + 1;
|
||||||
|
this.arkusze = new Arkusz[Arkusz.lx][Arkusz.ly];
|
||||||
|
for (int i = 0; i < Arkusz.lx; i++) {
|
||||||
|
for (int j = 0; j < Arkusz.ly; j++) {
|
||||||
|
this.arkusze[i][j] = new Arkusz();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// wspolrzedne arkusza mapy
|
||||||
|
int xa, ya;
|
||||||
|
for (int i = 0; i < this.wezly.size(); i++) {
|
||||||
|
WezelDrogowy wezel = this.wezly.get(i);
|
||||||
|
xa = wezel.idKw.x / MapConsts.SS_PER_SHEET;
|
||||||
|
ya = wezel.idKw.y / MapConsts.SS_PER_SHEET;
|
||||||
|
this.arkusze[xa][ya].wezly.add(wezel);
|
||||||
|
}
|
||||||
|
int xa2, ya2;
|
||||||
|
for (int i = 0; i < this.luki.size(); i++) {
|
||||||
|
LukDrogowy luk = this.luki.get(i);
|
||||||
|
xa = luk.getWezly()[0].idKw.x / MapConsts.SS_PER_SHEET;
|
||||||
|
ya = luk.getWezly()[0].idKw.y / MapConsts.SS_PER_SHEET;
|
||||||
|
xa2 = luk.getWezly()[1].idKw.x / MapConsts.SS_PER_SHEET;
|
||||||
|
ya2 = luk.getWezly()[1].idKw.y / MapConsts.SS_PER_SHEET;
|
||||||
|
boolean b = Arkusz.mniejszeWspolrzedne(xa, ya, xa2, ya2);
|
||||||
|
if (b) {
|
||||||
|
this.arkusze[xa][ya].luki.add(luk);
|
||||||
|
} else {
|
||||||
|
this.arkusze[xa2][ya2].luki.add(luk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void utworzSiecDrogowa(){
|
||||||
|
// if (null == instancja){
|
||||||
|
// instancja = new SiecDrogowa(MapConsts.DROGI_DIR);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LukDrogowy dodajLuk(WezelDrogowy wezel1, WezelDrogowy wezel2) {
|
||||||
|
utworzSiecDrogowa();
|
||||||
|
LukDrogowy nowyLuk = new LukDrogowy();
|
||||||
|
nowyLuk.getWezly()[0] = wezel1;
|
||||||
|
wezel1.luki.add(nowyLuk);
|
||||||
|
nowyLuk.getWezly()[1] = wezel2;
|
||||||
|
wezel2.luki.add(nowyLuk);
|
||||||
|
instancja.luki.add(nowyLuk);
|
||||||
|
nowyLuk.id = instancja.luki.size() - 1;
|
||||||
|
return nowyLuk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WezelDrogowy dodajWezel(String wspUTM) {
|
||||||
|
utworzSiecDrogowa();
|
||||||
|
// TODO dodac weryfikacje poprawnosci wspolrzednych UTM
|
||||||
|
WezelDrogowy nowyWezel = new WezelDrogowy();
|
||||||
|
nowyWezel.setXms(Teren.zamienWspUtmNaWspXms(wspUTM.substring(0, 6)));
|
||||||
|
nowyWezel.setYms(Teren.zamienWspUtmNaWspXms(wspUTM.substring(8, 14)));
|
||||||
|
int x = GridCoord.zamienWspXmsNaIdKwadratuX(nowyWezel.getXms());
|
||||||
|
int y = GridCoord.zamienWspYmsNaIdKwadratuY(nowyWezel.getYms());
|
||||||
|
nowyWezel.idKw = new GridCoord(x, y);
|
||||||
|
nowyWezel.luki = new ArrayList<LukDrogowy>();
|
||||||
|
instancja.wezly.add(nowyWezel);
|
||||||
|
nowyWezel.id = instancja.wezly.size() - 1;
|
||||||
|
return nowyWezel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void usunLuk(LukDrogowy usuwanyLuk) {
|
||||||
|
utworzSiecDrogowa();
|
||||||
|
if (usuwanyLuk.id < 0 || usuwanyLuk.id >= instancja.luki.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int ostatniId = instancja.luki.size() - 1;
|
||||||
|
LukDrogowy lukOstatni = instancja.luki.get(ostatniId);
|
||||||
|
lukOstatni.id = usuwanyLuk.id;
|
||||||
|
instancja.luki.set(lukOstatni.id, lukOstatni);
|
||||||
|
instancja.luki.remove(ostatniId);
|
||||||
|
// aktualizacja wezlow luku
|
||||||
|
usuwanyLuk.getWezly()[0].luki.remove(usuwanyLuk);
|
||||||
|
usuwanyLuk.getWezly()[1].luki.remove(usuwanyLuk);
|
||||||
|
if (usuwanyLuk.getWezly()[0].luki.size() == 0) {
|
||||||
|
usunWezel(usuwanyLuk.getWezly()[0]);
|
||||||
|
}
|
||||||
|
if (usuwanyLuk.getWezly()[1].luki.size() == 0) {
|
||||||
|
usunWezel(usuwanyLuk.getWezly()[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void usunWezel(WezelDrogowy usuwanyWezel) {
|
||||||
|
utworzSiecDrogowa();
|
||||||
|
if (usuwanyWezel.id < 0 || usuwanyWezel.id >= instancja.wezly.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int ostatniId = instancja.wezly.size() - 1;
|
||||||
|
WezelDrogowy wezelOstatni = instancja.wezly.get(ostatniId);
|
||||||
|
wezelOstatni.id = usuwanyWezel.id;
|
||||||
|
instancja.wezly.set(wezelOstatni.id, wezelOstatni);
|
||||||
|
instancja.wezly.remove(ostatniId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void wpiszDrogiWKwadraty() {
|
||||||
|
utworzSiecDrogowa();
|
||||||
|
GridCoord[] kwadratyOdcinka;
|
||||||
|
for (int i = 0; i < instancja.luki.size(); i++) {
|
||||||
|
LukDrogowy luk = instancja.luki.get(i);
|
||||||
|
GridCoord kw1 = luk.getWezly()[0].idKw;
|
||||||
|
GridCoord kw2 = luk.getWezly()[1].idKw;
|
||||||
|
kwadratyOdcinka = GeomUtils.kwadratyOdcinka(kw1, kw2);
|
||||||
|
wpiszOdcinekDrogiWKwadraty(kwadratyOdcinka);
|
||||||
|
}
|
||||||
|
Teren.zapisBuforaMapyDoPliku();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wpiszOdcinekDrogiWKwadraty(GridCoord[] kwadratyOdcinka) {
|
||||||
|
if (null == kwadratyOdcinka) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < kwadratyOdcinka.length - 1; i++) {
|
||||||
|
GridCoord idkw1 = kwadratyOdcinka[i];
|
||||||
|
GridCoord idkw2 = kwadratyOdcinka[i + 1];
|
||||||
|
EGeoDirection kier = GeomUtils.kierunekDlaSasiada(idkw1, idkw2);
|
||||||
|
Kwadrat kw = Teren.getKwadrat(idkw1.x, idkw1.y);
|
||||||
|
if (null != kw) {
|
||||||
|
kw.setJestDroga(kier, true);
|
||||||
|
}
|
||||||
|
kw = Teren.getKwadrat(idkw2.x, idkw2.y);
|
||||||
|
if (null != kw) {
|
||||||
|
// wyznaczam kierunek przeciwny
|
||||||
|
kier = kier.oppositeDirect();
|
||||||
|
kw.setJestDroga(kier, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void aktualizujPliki(boolean wymuszony) throws IOException {
|
||||||
|
if (wymuszony) {
|
||||||
|
if (this.liczbaZmian == 0)
|
||||||
|
// nie bylo modyfikacji od ostatniej zapisu
|
||||||
|
return;
|
||||||
|
this.liczbaZmian = -1;
|
||||||
|
}
|
||||||
|
this.liczbaZmian++;
|
||||||
|
this.liczbaZmian %= LICZBA_ZMIAN;
|
||||||
|
if (0 == this.liczbaZmian) {
|
||||||
|
try {
|
||||||
|
// zapisanie wezlow
|
||||||
|
BufferedWriter bw = new BufferedWriter(new FileWriter(path + "\\nodes.txt"));
|
||||||
|
String linia = Integer.toString(this.wezly.size());
|
||||||
|
bw.write(linia, 0, linia.length());
|
||||||
|
bw.newLine();
|
||||||
|
String s;
|
||||||
|
for (int i = 0; i < this.wezly.size(); i++) {
|
||||||
|
WezelDrogowy wezel = this.wezly.get(i);
|
||||||
|
s = String.format("%07d", wezel.id);
|
||||||
|
linia = s;
|
||||||
|
linia += " ";
|
||||||
|
s = String.format("%010d", wezel.getXms());
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
s = String.format("%010d", wezel.getYms());
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
int most = 0;
|
||||||
|
if (wezel.jestMostem) {
|
||||||
|
most = 1;
|
||||||
|
}
|
||||||
|
s = String.format("%01d", most);
|
||||||
|
linia += s;
|
||||||
|
bw.write(linia, 0, linia.length());
|
||||||
|
bw.newLine();
|
||||||
|
}
|
||||||
|
bw.close();
|
||||||
|
logger.info("Zapisano plik wezlow sieci drogowej: " + path + "\\nodes.txt");
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.warn("Blad zapisu pliku wezlow sieci drogowej: " + path + "\\nodes.txt");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// zapisanie lukow
|
||||||
|
BufferedWriter bw = new BufferedWriter(new FileWriter(path + "\\arcs.txt"));
|
||||||
|
String linia = Integer.toString(this.luki.size());
|
||||||
|
bw.write(linia, 0, linia.length());
|
||||||
|
bw.newLine();
|
||||||
|
String s;
|
||||||
|
for (int i = 0; i < this.luki.size(); i++) {
|
||||||
|
LukDrogowy luk = this.luki.get(i);
|
||||||
|
s = String.format("%07d", luk.getWezly()[0].id);
|
||||||
|
linia = s;
|
||||||
|
linia += " ";
|
||||||
|
s = String.format("%07d", luk.getWezly()[1].id);
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
s = String.format("%05d", luk.dlugosc);
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
s = String.format("%02d", luk.szerokosc);
|
||||||
|
linia += s;
|
||||||
|
linia += " ";
|
||||||
|
int most = 0;
|
||||||
|
if (luk.jestMostem) {
|
||||||
|
most = 1;
|
||||||
|
}
|
||||||
|
s = String.format("%01d", most);
|
||||||
|
linia += s;
|
||||||
|
bw.write(linia, 0, linia.length());
|
||||||
|
bw.newLine();
|
||||||
|
}
|
||||||
|
bw.close();
|
||||||
|
logger.info("Zapisano plik lukow sieci drogowej: " + path + "\\arcs.txt");
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.warn("Blad zapisu pliku lukow sieci drogowej: " + path + "\\arcs.txt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// funkcja zwraca kolekcje lukow wewnatrz prostokata
|
||||||
|
// zawartego miedzy lewym dolnym i prawym gornym punktem
|
||||||
|
public static ArrayList<LukDrogowy> dajLukiWObszarze(String wspUtmLD, String wspUtmPG) {
|
||||||
|
utworzSiecDrogowa();
|
||||||
|
int xms = Teren.zamienWspUtmNaWspXms(wspUtmLD);
|
||||||
|
int yms = Teren.zamienWspUtmNaWspYms(wspUtmLD);
|
||||||
|
int xa_ld = GridCoord.zamienWspXmsNaIdKwadratuX(xms);
|
||||||
|
xa_ld /= MapConsts.SS_PER_SHEET;
|
||||||
|
int ya_ld = GridCoord.zamienWspYmsNaIdKwadratuY(yms);
|
||||||
|
ya_ld /= MapConsts.SS_PER_SHEET;
|
||||||
|
|
||||||
|
xms = Teren.zamienWspUtmNaWspXms(wspUtmPG);
|
||||||
|
yms = Teren.zamienWspUtmNaWspYms(wspUtmPG);
|
||||||
|
int xa_pg = GridCoord.zamienWspXmsNaIdKwadratuX(xms);
|
||||||
|
xa_pg /= MapConsts.SS_PER_SHEET;
|
||||||
|
int ya_pg = GridCoord.zamienWspYmsNaIdKwadratuY(yms);
|
||||||
|
ya_pg /= MapConsts.SS_PER_SHEET;
|
||||||
|
|
||||||
|
//if (xa_ld > xa_pg || ya_ld > ya_pg) {
|
||||||
|
// return null;
|
||||||
|
//}
|
||||||
|
if (xa_ld > xa_pg){
|
||||||
|
int tmp = xa_ld;
|
||||||
|
xa_ld = xa_pg;
|
||||||
|
xa_pg = tmp;
|
||||||
|
}
|
||||||
|
if (ya_ld > ya_pg){
|
||||||
|
int tmp = ya_ld;
|
||||||
|
ya_ld = ya_pg;
|
||||||
|
ya_pg = tmp;
|
||||||
|
}
|
||||||
|
ArrayList<LukDrogowy> luki = new ArrayList<LukDrogowy>();
|
||||||
|
// wspolrzedne arkusza mapy
|
||||||
|
for (int xa = xa_ld; xa <= xa_pg; xa++) {
|
||||||
|
for (int ya = ya_ld; ya <= ya_pg; ya++) {
|
||||||
|
if (instancja.arkusze[xa][ya].luki != null) {
|
||||||
|
luki.addAll(instancja.arkusze[xa][ya].luki);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return luki;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// GridCoord idKw = GridCoord.zamienWspUtmNaIdKwadratu("520101N0160202E");
|
||||||
|
// String utm = GridCoord.zamienIdKwadratuNaWspUtm(idKw);
|
||||||
|
// int xms = GridCoord.zamienIdKwadratuXNaWspXms(idKw.x);
|
||||||
|
// int yms = GridCoord.zamienIdKwadratuYNaWspYms(idKw.y);
|
||||||
|
// utm = Teren.zamienWspXmsYmsNaWspUtm(xms, yms);
|
||||||
|
// float lon = GridCoord.zamienIdKwadratuXNaDlugoscGeo(idKw.x);
|
||||||
|
// float lat = GridCoord.zamienIdKwadratuYNaSzerokoscGeo(idKw.y);
|
||||||
|
// idKw.x = GridCoord.zamienDlugoscGeoNaIdKwadratuX(lon);
|
||||||
|
// idKw.y = GridCoord.zamienSzerokoscGeoNaIdKwadratuY(lat);
|
||||||
|
utworzSiecDrogowa();
|
||||||
|
SiecDrogowa.wpiszDrogiWKwadraty();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
83
src/main/java/pl/wat/ms4ds/terenfunkcje/SmallSquare.java
Normal file
83
src/main/java/pl/wat/ms4ds/terenfunkcje/SmallSquare.java
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
|
||||||
|
public class SmallSquare {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The height above the level of the sea.
|
||||||
|
*/
|
||||||
|
short elevation;
|
||||||
|
/**
|
||||||
|
* 0 - BARE_GROUND
|
||||||
|
* 1 - GRASS
|
||||||
|
* 2 - SWAMP
|
||||||
|
* 3 - WATER
|
||||||
|
* 4 - SCRUB, BUSHES
|
||||||
|
* 5 - BUILDINGS
|
||||||
|
* 6 - FOREST
|
||||||
|
*/
|
||||||
|
byte terrainType;
|
||||||
|
/**
|
||||||
|
* Rodzaj drogi na danym kierunku.
|
||||||
|
* 0 - no road, 1 - small roads, 2 - minor roads, 3 - major roads
|
||||||
|
*/
|
||||||
|
// byte[] roads;
|
||||||
|
byte smallRoads;
|
||||||
|
byte minorRoads;
|
||||||
|
byte majorRoads;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rodzaj przeszkody wodnej na danym kierunku.
|
||||||
|
* 0 - no watercourse, 1 - drain, ditch, 2 - canal, stream, 3 - river
|
||||||
|
*/
|
||||||
|
// byte[] waterWays;
|
||||||
|
byte drains;
|
||||||
|
byte streams;
|
||||||
|
byte rivers;
|
||||||
|
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
elevation = 0;
|
||||||
|
terrainType = 0;
|
||||||
|
smallRoads = 0;
|
||||||
|
minorRoads = 0;
|
||||||
|
majorRoads = 0;
|
||||||
|
drains = 0;
|
||||||
|
streams = 0;
|
||||||
|
rivers = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(ObjectOutputStream out) throws IOException {
|
||||||
|
out.writeShort(elevation);
|
||||||
|
out.writeByte(terrainType);
|
||||||
|
out.writeByte(smallRoads);
|
||||||
|
out.writeByte(minorRoads);
|
||||||
|
out.writeByte(majorRoads);
|
||||||
|
out.writeByte(drains);
|
||||||
|
out.writeByte(streams);
|
||||||
|
out.writeByte(rivers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(ObjectInputStream in) throws IOException {
|
||||||
|
elevation = in.readShort();
|
||||||
|
terrainType = in.readByte();
|
||||||
|
smallRoads = in.readByte();
|
||||||
|
minorRoads = in.readByte();
|
||||||
|
majorRoads = in.readByte();
|
||||||
|
drains = in.readByte();
|
||||||
|
streams = in.readByte();
|
||||||
|
rivers = in.readByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmallSquare(short elevation, byte terrainType) {
|
||||||
|
this.elevation = elevation;
|
||||||
|
this.terrainType = terrainType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmallSquare() {
|
||||||
|
}
|
||||||
|
}
|
||||||
1103
src/main/java/pl/wat/ms4ds/terenfunkcje/Teren.java
Normal file
1103
src/main/java/pl/wat/ms4ds/terenfunkcje/Teren.java
Normal file
File diff suppressed because it is too large
Load Diff
38
src/main/java/pl/wat/ms4ds/terenfunkcje/TerrainType.java
Normal file
38
src/main/java/pl/wat/ms4ds/terenfunkcje/TerrainType.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
public enum TerrainType {
|
||||||
|
BARE_GROUND(0),
|
||||||
|
GRASS(1),
|
||||||
|
SWAMP(2),
|
||||||
|
WATER(3),
|
||||||
|
SCRUB_BUSHES(4),
|
||||||
|
BUILDINGS(5),
|
||||||
|
FOREST(6);
|
||||||
|
|
||||||
|
static {
|
||||||
|
BARE_GROUND.height = 0;
|
||||||
|
BARE_GROUND.passability = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight(byte terrainType) {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int ID;
|
||||||
|
private int height;
|
||||||
|
/**
|
||||||
|
* Zdolność przekraczania
|
||||||
|
*/
|
||||||
|
private boolean passability;
|
||||||
|
|
||||||
|
TerrainType(int id) {
|
||||||
|
this.ID = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
TerrainType(int id, int height, boolean passability) {
|
||||||
|
this.ID = id;
|
||||||
|
this.height = height;
|
||||||
|
this.passability = passability;
|
||||||
|
}
|
||||||
|
}
|
||||||
166
src/main/java/pl/wat/ms4ds/terenfunkcje/TerrainUtils.java
Normal file
166
src/main/java/pl/wat/ms4ds/terenfunkcje/TerrainUtils.java
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
import pl.wat.ms4ds.common.EGeoDirection;
|
||||||
|
import pl.wat.ms4ds.common.ERodzajPodwozia;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
||||||
|
public class TerrainUtils {
|
||||||
|
|
||||||
|
// ========================================================================
|
||||||
|
|
||||||
|
public static float widocznoscOptyczna(float wysokoscObserwatora, float wysokoscCelu,
|
||||||
|
int x1, int y1, int x2, int y2) {
|
||||||
|
if ((x1 == x2) && (y1 == y2)) {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
Kwadrat kwDo = Teren.getKwadrat(x1, y1);
|
||||||
|
Kwadrat kwOd = Teren.getKwadrat(x2, y2);
|
||||||
|
if (kwDo == Kwadrat.EMPTY_SQUARE || kwOd == Kwadrat.EMPTY_SQUARE) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
// roznica wysokosci miedzy skrajnymi kwadratami
|
||||||
|
float roznicaWysokosci = kwDo.wysokoscSrednia + wysokoscCelu - kwOd.wysokoscSrednia - wysokoscObserwatora;
|
||||||
|
float wysBezwzgObserwatora;
|
||||||
|
if (roznicaWysokosci < 0) {
|
||||||
|
// sprawdzanie kwOd -> kwDo
|
||||||
|
int swap = x1;
|
||||||
|
x1 = x2;
|
||||||
|
x2 = swap;
|
||||||
|
swap = y1;
|
||||||
|
y1 = y2;
|
||||||
|
y2 = swap;
|
||||||
|
roznicaWysokosci = -roznicaWysokosci;
|
||||||
|
wysBezwzgObserwatora = kwDo.wysokoscSrednia + wysokoscCelu;
|
||||||
|
} else {
|
||||||
|
wysBezwzgObserwatora = kwOd.wysokoscSrednia + wysokoscObserwatora;
|
||||||
|
}
|
||||||
|
GridCoord[] kwadratyNaOdcinku = Bresenham.generateSegment(x1, y1, x2, y2);
|
||||||
|
float dlugoscOdcinka = GridCoord.odleglosc(x1, y1, x2, y2);
|
||||||
|
float tangAlfa0 = roznicaWysokosci / dlugoscOdcinka;
|
||||||
|
|
||||||
|
float dh_max = 0;
|
||||||
|
for (int i = 1; i < kwadratyNaOdcinku.length - 1; i++) {
|
||||||
|
// badanie wewnetrznych kwadratow nalezacych do odcinka,
|
||||||
|
// czy nie sa powyzej linii widocznosci dla kwadratow skrajnych
|
||||||
|
float wysokoscPrzeszkody = 0.0f;
|
||||||
|
Kwadrat kwAkt = Teren.getKwadrat(kwadratyNaOdcinku[i].x, kwadratyNaOdcinku[i].y);
|
||||||
|
if (kwAkt.stopienZalesienia > 0.5f) {
|
||||||
|
wysokoscPrzeszkody = 10.0f;
|
||||||
|
}
|
||||||
|
if (kwAkt.stopienZabudowy > 0.5f) {
|
||||||
|
wysokoscPrzeszkody = 10.0f;
|
||||||
|
}
|
||||||
|
// wyznaczenie roznicy wysokosci kwadratu badanego i docelowego
|
||||||
|
// uwzgledniajac wysokosc obserwatora oraz wysokosc przeszkody
|
||||||
|
float roznWysAkt = kwAkt.wysokoscSrednia + wysokoscPrzeszkody - wysBezwzgObserwatora;
|
||||||
|
if (dh_max >= roznWysAkt) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float odleg = GridCoord.odleglosc(kwadratyNaOdcinku[i].x, kwadratyNaOdcinku[i].y, x1, y1);
|
||||||
|
// float tangAlfa = roznWysAkt / odleg;
|
||||||
|
// if (tangAlfa0 < tangAlfa) {
|
||||||
|
if (tangAlfa0 * odleg < roznWysAkt) {
|
||||||
|
// wysokosc aktualnie badanego kwadratu jest powyzej/ponizej
|
||||||
|
// linii poprowadzonej z kwadratu startowego do docelowego (z uwzglednieniem wysokosci obserwatora i celu)
|
||||||
|
// odpowiednio dla katow dodatnich/ujemnych
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
dh_max = roznWysAkt;
|
||||||
|
}
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float widocznoscOptyczna(int x, int y) {
|
||||||
|
Kwadrat kw = Teren.getKwadrat(x, y);
|
||||||
|
if (kw.stopienZabudowy > 0.25f || kw.stopienZalesienia > 0.25f) {
|
||||||
|
return 0.3f;
|
||||||
|
}
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float widocznoscOptyczna2(float wysokoscObserwatora, float wysokoscCelu,
|
||||||
|
int x1, int y1, int x2, int y2) {
|
||||||
|
if ((x1 == x2) && (y1 == y2)) {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
Kwadrat kwDo = Teren.getKwadrat(x1, y1);
|
||||||
|
Kwadrat kwOd = Teren.getKwadrat(x2, y2);
|
||||||
|
if (kwDo == Kwadrat.EMPTY_SQUARE || kwOd == Kwadrat.EMPTY_SQUARE) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
// roznica wysokosci miedzy skrajnymi kwadratami
|
||||||
|
float roznicaWysokosci = kwDo.wysokoscSrednia + wysokoscCelu - kwOd.wysokoscSrednia - wysokoscObserwatora;
|
||||||
|
GridCoord[] kwadratyNaOdcinku = GeomUtils.kwadratyOdcinka(x1, y1, x2, y2);
|
||||||
|
float dlugoscOdcinka = GridCoord.odleglosc(x1, y1, x2, y2);
|
||||||
|
float tangAlfa0 = roznicaWysokosci / dlugoscOdcinka;
|
||||||
|
for (int i = 1; i < kwadratyNaOdcinku.length - 1; i++) {
|
||||||
|
// badanie wewnetrznych kwadratow nalezacych do odcinka,
|
||||||
|
// czy nie sa powyzej linii widocznosci dla kwadratow skrajnych
|
||||||
|
float wysokoscPrzeszkody = 0.0f;
|
||||||
|
Kwadrat kwAkt = Teren.getKwadrat(kwadratyNaOdcinku[i].x, kwadratyNaOdcinku[i].y);
|
||||||
|
if (kwAkt.stopienZalesienia > 0.5f) {
|
||||||
|
wysokoscPrzeszkody = 10.0f;
|
||||||
|
}
|
||||||
|
if (kwAkt.stopienZabudowy > 0.5f) {
|
||||||
|
wysokoscPrzeszkody = 10.0f;
|
||||||
|
}
|
||||||
|
// wyznaczenie roznicy wysokosci kwadratu badanego i docelowego
|
||||||
|
// uwzgledniajac wysokosc obserwatora oraz wysokosc przeszkody
|
||||||
|
float roznWysAkt = kwAkt.wysokoscSrednia + wysokoscPrzeszkody - kwOd.wysokoscSrednia - wysokoscObserwatora;
|
||||||
|
float odleg = GridCoord.odleglosc(kwadratyNaOdcinku[i].x, kwadratyNaOdcinku[i].y, x1, y1);
|
||||||
|
float tangAlfa = roznWysAkt / odleg;
|
||||||
|
if (tangAlfa0 < tangAlfa) {
|
||||||
|
// wysokosc aktualnie badanego kwadratu jest powyzej/ponizej
|
||||||
|
// linii poprowadzonej z kwadratu startowego do docelowego (z uwzglednieniem wysokosci obserwatora i celu)
|
||||||
|
// odpowiednio dla katow dodatnich/ujemnych
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (kwDo.stopienZabudowy > 0.25f || kwDo.stopienZalesienia > 0.25f) {
|
||||||
|
return 0.3f;
|
||||||
|
}
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float sredStopienWidoczOptycznej(float wysokoscObserwatora, float wysokoscCelu,
|
||||||
|
GridCoord kwadratOd, int dl1, GridCoord kwadratDo, int dl2) {
|
||||||
|
float stop = 0.0f;
|
||||||
|
for (int x1 = kwadratOd.x; x1 < kwadratOd.x + dl1; x1++)
|
||||||
|
for (int y1 = kwadratOd.y; y1 < kwadratOd.y + dl1; y1++)
|
||||||
|
for (int x2 = kwadratDo.x; x2 < kwadratDo.x + dl2; x2++)
|
||||||
|
for (int y2 = kwadratDo.y; y2 < kwadratDo.y + dl2; y2++)
|
||||||
|
stop += widocznoscOptyczna(wysokoscObserwatora, wysokoscCelu, x1, y1, x2, y2);
|
||||||
|
|
||||||
|
stop /= (dl1 * dl1 * dl2 * dl2);
|
||||||
|
return stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float sredStopienWidoczOptycznej2(float wysokoscObserwatora, float wysokoscCelu,
|
||||||
|
GridCoord kwadratOd, int dl1, GridCoord kwadratDo, int dl2) {
|
||||||
|
float stop = 0.0f;
|
||||||
|
for (int x1 = kwadratOd.x; x1 < kwadratOd.x + dl1; x1++)
|
||||||
|
for (int y1 = kwadratOd.y; y1 < kwadratOd.y + dl1; y1++)
|
||||||
|
for (int x2 = kwadratDo.x; x2 < kwadratDo.x + dl2; x2++)
|
||||||
|
for (int y2 = kwadratDo.y; y2 < kwadratDo.y + dl2; y2++)
|
||||||
|
stop += widocznoscOptyczna2(wysokoscObserwatora, wysokoscCelu, x1, y1, x2, y2);
|
||||||
|
|
||||||
|
stop /= (dl1 * dl1 * dl2 * dl2);
|
||||||
|
return stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float stopienPrzejezdnosciAktualOdcinkaDrogi(ArrayList<GridCoord> droga, int pozycja,
|
||||||
|
EGeoDirection zkierunku, ERodzajPodwozia podwozie) {
|
||||||
|
if ((droga == null) || (droga.size() == 0) || (pozycja < 0) || (pozycja >= droga.size() - 1)) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
GridCoord idKw1 = droga.get(pozycja);
|
||||||
|
GridCoord idKw2 = droga.get(pozycja + 1);
|
||||||
|
return (float) Teren.getStopienPrzejezdnosci(idKw1.x, idKw1.y, idKw2.x, idKw2.y, zkierunku, podwozie);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
96
src/main/java/pl/wat/ms4ds/terenfunkcje/WezelDrogowy.java
Normal file
96
src/main/java/pl/wat/ms4ds/terenfunkcje/WezelDrogowy.java
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
public class WezelDrogowy {
|
||||||
|
int id = -1;
|
||||||
|
private int xms = 0;
|
||||||
|
private int yms = 0;
|
||||||
|
boolean jestMostem = false;
|
||||||
|
GridCoord idKw;
|
||||||
|
ArrayList<LukDrogowy> luki = new ArrayList<LukDrogowy>();
|
||||||
|
|
||||||
|
WezelDrogowy() {
|
||||||
|
}
|
||||||
|
|
||||||
|
WezelDrogowy(String opis) {
|
||||||
|
if (null == opis || opis.length() == 0){
|
||||||
|
SiecDrogowa.logger.debug("Pusty ciag opis w konstruktorze Wezla Drogowego.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StringTokenizer st = new StringTokenizer(opis, " \t");
|
||||||
|
String[] tokenTable = new String[st.countTokens()];
|
||||||
|
for (int i = 0; st.hasMoreTokens(); i++) {
|
||||||
|
tokenTable[i] = st.nextToken();
|
||||||
|
}
|
||||||
|
if (tokenTable.length == 3) {
|
||||||
|
try {
|
||||||
|
this.xms = Integer.parseInt(tokenTable[0]);
|
||||||
|
//TODO KONSULTACJA WYWALAMY/ ODKOMENTOWUJEMY
|
||||||
|
// //Zabezpieczenie przed zaokraglaniem na krawedziach mapy
|
||||||
|
// if (this.xms < MapConsts.X_REF_MS)
|
||||||
|
// this.xms = MapConsts.X_REF_MS;
|
||||||
|
// if (this.xms > MapConsts.X_REF_MS + MapConsts.DX_REF_MS)
|
||||||
|
// this.xms = MapConsts.X_REF_MS + MapConsts.DX_REF_MS;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
SiecDrogowa.logger.warn("Bledne dane w pliku z wezlami [Wezel: " + this.id + " X].");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.yms = Integer.parseInt(tokenTable[1]);
|
||||||
|
// //Zabezpieczenie przed zaokraglaniem na krawedziach mapy
|
||||||
|
// if (this.yms < MapConsts.Y_REF_MS)
|
||||||
|
// this.yms = MapConsts.Y_REF_MS;
|
||||||
|
// if (this.yms > MapConsts.Y_REF_MS + MapConsts.DY_REF_MS)
|
||||||
|
// this.yms = MapConsts.Y_REF_MS + MapConsts.DY_REF_MS;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
SiecDrogowa.logger.warn("Bledne dane w pliku z wezlami [Wezel: " + this.id + " Y].");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.jestMostem = Integer.parseInt(tokenTable[2]) != 0 ? true : false;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
SiecDrogowa.logger.warn("Bledne dane w pliku z wezlami [Wezel: " + this.id + " czyJestMost].");
|
||||||
|
}
|
||||||
|
int x = GridCoord.zamienWspXmsNaIdKwadratuX(getXms());
|
||||||
|
int y = GridCoord.zamienWspYmsNaIdKwadratuY(getYms());
|
||||||
|
this.idKw = new GridCoord(x, y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SiecDrogowa.logger.warn("Bledne ilosc tokenow w linii [" + opis + "].");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isJestMostem() {
|
||||||
|
return jestMostem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJestMostem(boolean jestMostem) {
|
||||||
|
this.jestMostem = jestMostem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridCoord getIdKw() {
|
||||||
|
return idKw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdKw(GridCoord idKw) {
|
||||||
|
this.idKw = new GridCoord(idKw);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXms(int xms) {
|
||||||
|
this.xms = xms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getXms() {
|
||||||
|
return xms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYms(int yms) {
|
||||||
|
this.yms = yms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getYms() {
|
||||||
|
return yms;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,485 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.GeoCoord;
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.GridCoord;
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.Kwadrat;
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.Teren;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Odczyt danych wysokościowych z numerycznego modelu terenu (NMT_100).
|
||||||
|
* <p>
|
||||||
|
* Kod źródłowy funkcji do transformacji współrzędnych elipsoidalnych na płaskie odwzorowań kartograficznych UTM, 1992, 2000
|
||||||
|
*/
|
||||||
|
public class CoordUtils {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(CoordUtils.class);
|
||||||
|
|
||||||
|
static String dataDir = "d:/Workspace2/dane_wysok/";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
HashMap<GridCoord, DaneWysok> daneWysokHashMap = new HashMap<GridCoord, DaneWysok>();
|
||||||
|
if (args.length > 0) {
|
||||||
|
dataDir = args[0];
|
||||||
|
}
|
||||||
|
for (int i = 1; i < args.length; i++) {
|
||||||
|
String nmt_fn = args[i];
|
||||||
|
daneWysokHashMap.clear();
|
||||||
|
readData(nmt_fn, daneWysokHashMap);
|
||||||
|
for (DaneWysok daneWysok : daneWysokHashMap.values()) {
|
||||||
|
Kwadrat kw = Teren.getKwadrat(daneWysok.idKw.x, daneWysok.idKw.y);
|
||||||
|
kw.setWysokoscSrednia((int) (daneWysok.suma / daneWysok.licz + 0.5));
|
||||||
|
}
|
||||||
|
logger.debug("Poczatek zapisu danych dla regionu " + nmt_fn + " >> " + i + "/" + (args.length - 1));
|
||||||
|
Teren.zapisBuforaMapyDoPliku();
|
||||||
|
logger.debug("Koniec zapisu danych dla regionu " + nmt_fn + " >> " + i + "/" + (args.length - 1));
|
||||||
|
Teren.reset();
|
||||||
|
}
|
||||||
|
logger.debug("Start: poprawy danych wysokosciowych");
|
||||||
|
Teren.poprawDaneWysokosciowe();
|
||||||
|
logger.debug("Koniec: poprawy danych wysokosciowych");
|
||||||
|
|
||||||
|
|
||||||
|
// GeoCoord latLon = new GeoCoord();
|
||||||
|
// PUWGCoord puwgCoord = new PUWGCoord();
|
||||||
|
// puwgCoord.easting = 542800.0;
|
||||||
|
// puwgCoord.northing = 732200.0;
|
||||||
|
// puwgCoord.proj = 1;
|
||||||
|
//
|
||||||
|
// convertPuwgToLatLon(puwgCoord, latLon);
|
||||||
|
// logger.debug("latLon= (" + latLon.lat + ", " + latLon.lon + ")");
|
||||||
|
// puwgCoord.easting = 718500.0;
|
||||||
|
// puwgCoord.northing = 663500.0;
|
||||||
|
// convertPuwgToLatLon(puwgCoord, latLon);
|
||||||
|
// logger.debug("latLon= (" + latLon.lat + ", " + latLon.lon + ")");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readData(String fileName, HashMap<GridCoord, DaneWysok> daneWysokHashMap) throws IOException {
|
||||||
|
try {
|
||||||
|
StringBuilder sb = new StringBuilder(100);
|
||||||
|
sb.append(dataDir);
|
||||||
|
sb.append(fileName);
|
||||||
|
sb.append(".txt");
|
||||||
|
FileReader fis = new FileReader(sb.toString());
|
||||||
|
// PUWG 1992
|
||||||
|
PUWGCoord puwgCoord = new PUWGCoord();
|
||||||
|
GeoCoord latLon = new GeoCoord();
|
||||||
|
double wysokosc = 0.0;
|
||||||
|
StringTokenizer st = null;
|
||||||
|
String line = null;
|
||||||
|
BufferedReader br = new BufferedReader(fis);
|
||||||
|
if (br.ready()) {
|
||||||
|
line = br.readLine();
|
||||||
|
int m = 1;
|
||||||
|
while (line != null) {
|
||||||
|
st = new StringTokenizer(line, " ");
|
||||||
|
if (st.countTokens() != 3) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String[] tokTable = new String[st.countTokens()];
|
||||||
|
for (int i = 0; st.hasMoreTokens(); i++) {
|
||||||
|
tokTable[i] = st.nextToken();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
puwgCoord.easting = Double.parseDouble(tokTable[0]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
logger.warn("Bledne dane w pliku: " + fileName);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
puwgCoord.northing = Double.parseDouble(tokTable[1]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
logger.warn("Bledne dane w pliku: " + fileName);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
wysokosc = Double.parseDouble(tokTable[2]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
logger.warn("Bledne dane w pliku: " + fileName);
|
||||||
|
}
|
||||||
|
convertPuwgToLatLon(puwgCoord, latLon);
|
||||||
|
GridCoord idKw = new GridCoord(latLon.lon, latLon.lat);
|
||||||
|
DaneWysok daneWysok = daneWysokHashMap.get(idKw);
|
||||||
|
if (daneWysok == null) {
|
||||||
|
daneWysok = new DaneWysok(idKw, wysokosc, 1);
|
||||||
|
daneWysokHashMap.put(idKw, daneWysok);
|
||||||
|
} else {
|
||||||
|
daneWysok.suma += wysokosc;
|
||||||
|
daneWysok.licz++;
|
||||||
|
}
|
||||||
|
line = br.readLine();
|
||||||
|
if (m++ % 100000 == 0) {
|
||||||
|
System.out.print('-');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
br.close();
|
||||||
|
System.out.println();
|
||||||
|
logger.debug("Koniec odczytu pliku: " + fileName);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final double fe = 500000.0;
|
||||||
|
|
||||||
|
//Deklaracja tablicy stref rownoleżnikowych
|
||||||
|
private static final char[] cArray = {'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R',
|
||||||
|
'S', 'T', 'U', 'V', 'W', 'X'};
|
||||||
|
// private static final String LITERALS = "CDEFGHJKLMNPQRSTUVWX";
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//Funkcje pomocnicze
|
||||||
|
|
||||||
|
/// /////////////////////////////////////////////////////////////////////////////
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
static double calculateESquared(double a, double b) {
|
||||||
|
a *= a;
|
||||||
|
b *= b;
|
||||||
|
return (a - b) / a;
|
||||||
|
// return ((a * a) - (b * b)) / (a * a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double calculateE2Squared(double a, double b) {
|
||||||
|
a *= a;
|
||||||
|
b *= b;
|
||||||
|
return (a - b) / b;
|
||||||
|
// return ((a * a) - (b * b)) / (b * b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double denom(double es, double sphi) {
|
||||||
|
double sinSphi = Math.sin(sphi);
|
||||||
|
return Math.sqrt(1.0 - es * (sinSphi * sinSphi));
|
||||||
|
}
|
||||||
|
|
||||||
|
static double sphsr(double a, double es, double sphi) {
|
||||||
|
double dn = denom(es, sphi);
|
||||||
|
return a * (1.0 - es) / (dn * dn * dn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double sphsn(double a, double es, double sphi) {
|
||||||
|
double sinSphi = Math.sin(sphi);
|
||||||
|
return a / Math.sqrt(1.0 - es * (sinSphi * sinSphi));
|
||||||
|
}
|
||||||
|
|
||||||
|
static double sphtmd(double ap, double bp, double cp, double dp, double ep, double sphi) {
|
||||||
|
return (ap * sphi) - (bp * Math.sin(2.0 * sphi)) + (cp * Math.sin(4.0 * sphi))
|
||||||
|
- (dp * Math.sin(6.0 * sphi)) + (ep * Math.sin(8.0 * sphi));
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Funkcja służy do konwersji współrzednych elipsoidalnych B, L (lat/lon) WGS84 na płaskie X-northing, Y-easting odwzorowania kartograficznego UTM
|
||||||
|
//=======================================================================
|
||||||
|
// Argumenty wejściowe i wyjściowe:
|
||||||
|
// --------------------------------
|
||||||
|
// int& utmXZone: nr strefy UTM wg. podziału południkowego (zwracane numery od 1 do 60, każda strefa ma sześć stopni)
|
||||||
|
// char& utmYZone: nr strefy wg. podziału równoleżnikowego (zwracane wartości: CDEFGHJKLMNPQRSTUVWX)
|
||||||
|
// double& easting: współrzędna Y UTM, w metrach po konwersji [metry]
|
||||||
|
// double& northing: współrzędna X UTM, w metrach po konwersji [metry]
|
||||||
|
// double lat, double lon: współrzędne lat/lon do konwersji [stopnie]
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param lat współrzędna lat (szerokość geograficzna) do konwersji [stopnie] (układ WGS84)
|
||||||
|
* @param lon współrzędna lon (długość geograficzna) do konwersji [stopnie] (układ WGS84)
|
||||||
|
* @param utmCoord współrzędne UTM
|
||||||
|
*/
|
||||||
|
public static void convertLatLonToUtm(double lat, double lon, UTMCoord utmCoord) {
|
||||||
|
// Współczynnik zniekształcenia skali w południku osiowym
|
||||||
|
double tmd;
|
||||||
|
double nfn;
|
||||||
|
if (lon <= 0.0) {
|
||||||
|
utmCoord.xZone = 30 + (int) (lon / 6.0);
|
||||||
|
} else {
|
||||||
|
utmCoord.xZone = 31 + (int) (lon / 6.0);
|
||||||
|
}
|
||||||
|
if (lat < 84.0 && lat >= 72.0) {
|
||||||
|
// Specjalne zatrzymanie: strefa X ma 12 stopni od północy do południa, nie 8
|
||||||
|
utmCoord.yZone = cArray[19];
|
||||||
|
} else {
|
||||||
|
utmCoord.yZone = cArray[(int) ((lat + 80.0) / 8.0)];
|
||||||
|
}
|
||||||
|
if (lat >= 84.0 || lat < -80.0) {
|
||||||
|
// Błędna wartość szerokości geograficznej (zwracany znak gwiazdki)
|
||||||
|
utmCoord.yZone = '*';
|
||||||
|
}
|
||||||
|
double latRad = lat * DEG_2_RAD;
|
||||||
|
double lonRad = lon * DEG_2_RAD;
|
||||||
|
double olam = (utmCoord.xZone * 6 - 183) * DEG_2_RAD;
|
||||||
|
double dlam = lonRad - olam;
|
||||||
|
double s = Math.sin(latRad);
|
||||||
|
double c = Math.cos(latRad);
|
||||||
|
double t = s / c;
|
||||||
|
double eta = e2Squared * (c * c);
|
||||||
|
double sn = sphsn(a, eSquared, latRad);
|
||||||
|
tmd = sphtmd(ap, bp, cp, dp, ep, latRad);
|
||||||
|
double t1, t2, t3, t4, t5, t6, t7, t8, t9;
|
||||||
|
t1 = tmd * ok;
|
||||||
|
t2 = sn * s * c * ok / 2.0;
|
||||||
|
t3 = sn * s * (c * c * c) * ok * (5.0 - (t * t) + 9.0 * eta + 4.0 * (eta * eta)) / 24.0;
|
||||||
|
t4 = sn * s * (c * c * c * c * c) * ok * (61.0 - 58.0 * (t * t) + (t * t * t * t) + 270.0 * eta - 330.0 * (t * t) * eta + 445.0 * (eta * eta) + 324.0 * (eta * eta * eta) - 680.0 * (t * t) * (eta * eta) + 88.0 * (eta * eta * eta * eta) - 600.0 * (t * t) * (eta * eta * eta) - 192.0 * (t * t) * (eta * eta * eta * eta)) / 720.0;
|
||||||
|
t5 = sn * s * (c * c * c * c * c * c * c) * ok * (1385.0 - 3111.0 * (t * t) + 543.0 * (t * t * t * t) - (t * t * t * t * t * t)) / 40320.0;
|
||||||
|
if (latRad < 0.0) nfn = 10000000.0;
|
||||||
|
else nfn = 0;
|
||||||
|
utmCoord.northing = nfn + t1 + (dlam * dlam) * t2 + (dlam * dlam * dlam * dlam) * t3 + (dlam * dlam * dlam * dlam * dlam * dlam) * t4 + (dlam * dlam * dlam * dlam * dlam * dlam * dlam * dlam) * t5;
|
||||||
|
t6 = sn * c * ok;
|
||||||
|
t7 = sn * (c * c * c) * ok * (1.0 - (t * t) + eta) / 6.0;
|
||||||
|
t8 = sn * (c * c * c * c * c) * ok * (5.0 - 18.0 * (t * t) + (t * t * t * t) + 14.0 * eta - 58.0 * (t * t) * eta + 13.0 * (eta * eta) + 4.0 * (eta * eta * eta) - 64.0 * (t * t) * (eta * eta) - 24.0 * (t * t) * (eta * eta * eta)) / 120.0;
|
||||||
|
t9 = sn * (c * c * c * c * c * c * c) * ok * (61.0 - 479.0 * (t * t) + 179.0 * (t * t * t * t) - (t * t * t * t * t * t)) / 5040.0;
|
||||||
|
utmCoord.easting = fe + dlam * t6 + (dlam * dlam * dlam) * t7 + (dlam * dlam * dlam * dlam * dlam) * t8 + (dlam * dlam * dlam * dlam * dlam * dlam * dlam) * t9;
|
||||||
|
if (utmCoord.northing >= 9999999.0) utmCoord.northing = 9999999.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Funkcja służy do konwersji współrzednych elipsoidalnych WGS84 B, L (lat/lon) na płaskie X-northing, Y-easting odwzorowania kartograficznego 1992 i 2000
|
||||||
|
//=======================================================================
|
||||||
|
// --------------------------------
|
||||||
|
// int& utmXZone: nr strefy UTM wg. podziału południkowego (zwracane numery od 1 do 60, każda strefa ma sześć stopni)
|
||||||
|
// char& utmYZone: nr strefy wg. podziału równoleżnikowego (zwracane wartości: CDEFGHJKLMNPQRSTUVWX)
|
||||||
|
// double& easting: współrzędna Y UTM, w metrach po konwersji [metry]
|
||||||
|
// double& northing: współrzędna X UTM, w metrach po konwersji [metry]
|
||||||
|
// double lat, double lon: współrzędne lat/lon do konwersji [stopnie]
|
||||||
|
// int proj: odwzorowanie kartograficzne (proj = 1 odpowiada odwzorowaniu 1992, natomiast każda inna odwzorowaniu 2000)
|
||||||
|
//=======================================================================
|
||||||
|
public static void convertLatLonToPUWG(PUWGCoord puwgCoord, double lat, double lon) {
|
||||||
|
// Współczynnik zniekształcenia skli mapy w południku osiowym dla odwzorowania kartograficznego 2000
|
||||||
|
//Współczynnik zniekształcenia skli mapy w południku osiowym dla odwzorowania kartograficznego 1992
|
||||||
|
double ok_new = (puwgCoord.proj != 1) ? 0.999923 : 0.9993;
|
||||||
|
double olam = 0.0;
|
||||||
|
double tmd;
|
||||||
|
double nfn;
|
||||||
|
double strf = 0.0;
|
||||||
|
if (lon < 13.5 || lon > 25.5) {
|
||||||
|
//Błędna wartość długości geograficznej (zwracana wartość 99999999999999)
|
||||||
|
puwgCoord.easting = 999999999999999.0;
|
||||||
|
puwgCoord.northing = 999999999999999.0;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (puwgCoord.proj == 1) {
|
||||||
|
olam = 19.0 * DEG_2_RAD;
|
||||||
|
strf = 0.0;
|
||||||
|
nfn = -5300000.0;
|
||||||
|
} else {
|
||||||
|
nfn = 0;
|
||||||
|
if (lon >= 13.5 && lon < 16.5) {
|
||||||
|
olam = 15.0 * DEG_2_RAD;
|
||||||
|
strf = 5000000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lon >= 16.5 && lon < 19.5) {
|
||||||
|
olam = 18.0 * DEG_2_RAD;
|
||||||
|
strf = 6000000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lon >= 19.5 && lon < 22.5) {
|
||||||
|
olam = 21.0 * DEG_2_RAD;
|
||||||
|
strf = 7000000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lon >= 22.5 && lon < 25.5) {
|
||||||
|
olam = 24.0 * DEG_2_RAD;
|
||||||
|
strf = 8000000.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double latRad = lat * DEG_2_RAD;
|
||||||
|
double lonRad = lon * DEG_2_RAD;
|
||||||
|
double dlam = lonRad - olam;
|
||||||
|
double s = Math.sin(latRad);
|
||||||
|
double c = Math.cos(latRad);
|
||||||
|
double t = s / c;
|
||||||
|
double eta = e2Squared * (c * c);
|
||||||
|
double sn = sphsn(a, eSquared, latRad);
|
||||||
|
tmd = sphtmd(ap, bp, cp, dp, ep, latRad);
|
||||||
|
double t1, t2, t3, t4, t5, t6, t7, t8, t9;
|
||||||
|
t1 = tmd * ok_new;
|
||||||
|
t2 = sn * s * c * ok_new / 2.0;
|
||||||
|
t3 = sn * s * (c * c * c) * ok_new * (5.0 - (t * t) + 9.0 * eta + 4.0 * (eta * eta)) / 24.0;
|
||||||
|
t4 = sn * s * (c * c * c * c * c) * ok_new * (61.0 - 58.0 * (t * t) + (t * t * t * t) + 270.0 * eta - 330.0 * (t * t) * eta + 445.0 * (eta * eta) + 324.0 * (eta * eta * eta) - 680.0 * (t * t) * (eta * eta) + 88.0 * (eta * eta * eta * eta) - 600.0 * (t * t) * (eta * eta * eta) - 192.0 * (t * t) * (eta * eta * eta * eta)) / 720.0;
|
||||||
|
t5 = sn * s * (c * c * c * c * c * c * c) * ok_new * (1385.0 - 3111.0 * (t * t) + 543.0 * (t * t * t * t) - (t * t * t * t * t * t)) / 40320.0;
|
||||||
|
puwgCoord.northing = nfn + t1 + (dlam * dlam) * t2 + (dlam * dlam * dlam * dlam) * t3 + (dlam * dlam * dlam * dlam * dlam * dlam) * t4 + (dlam * dlam * dlam * dlam * dlam * dlam * dlam * dlam) * t5;
|
||||||
|
t6 = sn * c * ok_new;
|
||||||
|
t7 = sn * (c * c * c) * ok_new * (1.0 - (t * t) + eta) / 6.0;
|
||||||
|
t8 = sn * (c * c * c * c * c) * ok_new * (5.0 - 18.0 * (t * t) + (t * t * t * t) + 14.0 * eta - 58.0 * (t * t) * eta + 13.0 * (eta * eta) + 4.0 * (eta * eta * eta) - 64.0 * (t * t) * (eta * eta) - 24.0 * (t * t) * (eta * eta * eta)) / 120.0;
|
||||||
|
t9 = sn * (c * c * c * c * c * c * c) * ok_new * (61.0 - 479.0 * (t * t) + 179.0 * (t * t * t * t) - (t * t * t * t * t * t)) / 5040.0;
|
||||||
|
puwgCoord.easting = fe + strf + dlam * t6 + (dlam * dlam * dlam) * t7 + (dlam * dlam * dlam * dlam * dlam) * t8 + (dlam * dlam * dlam * dlam * dlam * dlam * dlam) * t9;// + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Funkcja do konwersji współrzędnych płaskich X/Y UTM na elipsoidalne lat/lon (dla dowolnej elipsoidy)
|
||||||
|
//=======================================================================
|
||||||
|
// Wymagania:
|
||||||
|
// -------------------------------------
|
||||||
|
// utmXZone musi być wartością w garanicach od 1 do 60
|
||||||
|
// utmYZone musi być jedną z liter: CDEFGHJKLMNPQRSTUVWX
|
||||||
|
// Argumenty wejściowe i wyjściowe:
|
||||||
|
// ------------------------------------
|
||||||
|
// double a: długość dużej półosi, w metrach (np. dla elipsoidy WGS 84, 6378137.0)
|
||||||
|
// double f: spłaszczenie elipsoidalne (np. dla elipsoidy WGS 84, 1 / 298.257223563)
|
||||||
|
// int utmXZone: nr strefy UTM wg. podziału południkowego (zwracane numery od 1 do 60, każda strefa ma sześć stopni)
|
||||||
|
// char utmYZone: nr strefy wg. podziału równoleżnikowego (zwracane wartości: CDEFGHJKLMNPQRSTUVWX)
|
||||||
|
// double easting, double northing: współrzędna X, Y UTM do konwersji [metry]
|
||||||
|
// double& lat, double& lon: współrzędne elipsoidalne lat/lon po konwersji [stopnie]
|
||||||
|
//=======================================================================
|
||||||
|
public static void convertUtmToLatLon(UTMCoord utmCoord, GeoCoord geoCoord) {
|
||||||
|
double nfn;
|
||||||
|
utmCoord.yZone = Character.toUpperCase(utmCoord.yZone);
|
||||||
|
if (utmCoord.yZone <= 'M' && utmCoord.yZone >= 'C') {
|
||||||
|
nfn = 10000000.0;
|
||||||
|
} else {
|
||||||
|
nfn = 0;
|
||||||
|
}
|
||||||
|
double tmd = (utmCoord.northing - nfn) / ok;
|
||||||
|
double sr = sphsr(a, eSquared, 0.0);
|
||||||
|
double ftphi = tmd / sr;
|
||||||
|
double t10, t11, t12, t13, t14, t15, t16, t17;
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
t10 = sphtmd(ap, bp, cp, dp, ep, ftphi);
|
||||||
|
sr = sphsr(a, eSquared, ftphi);
|
||||||
|
ftphi = ftphi + (tmd - t10) / sr;
|
||||||
|
}
|
||||||
|
sr = sphsr(a, eSquared, ftphi);
|
||||||
|
double sn = sphsn(a, eSquared, ftphi);
|
||||||
|
double s = Math.sin(ftphi);
|
||||||
|
double c = Math.cos(ftphi);
|
||||||
|
double t = s / c;
|
||||||
|
double eta = e2Squared * (c * c);
|
||||||
|
double de = utmCoord.easting - fe;
|
||||||
|
t10 = t / (2.0 * sr * sn * (ok * ok));
|
||||||
|
t11 = t * (5.0 + 3.0 * (t * t) + eta - 4.0 * (eta * eta) - 9.0 * (t * t) * eta) / (24.0 * sr * (sn * sn * sn) * (ok * ok * ok * ok));
|
||||||
|
t12 = t * (61.0 + 90.0 * (t * t) + 46.0 * eta + 45.0 * (t * t * t * t) - 252.0 * (t * t) * eta - 3.0 * (eta * eta) + 100.0 * (eta * eta * eta) - 66.0 * (t * t) * (eta * eta) - 90.0 * (t * t * t * t) * eta + 88.0 * (eta * eta * eta * eta) + 225.0 * (t * t * t * t) * (eta * eta) + 84.0 * (t * t) * (eta * eta * eta) - 192.0 * (t * t) * (eta * eta * eta * eta)) / (720.0 * sr * (sn * sn * sn * sn * sn) * (ok * ok * ok * ok * ok * ok));
|
||||||
|
t13 = t * (1385.0 + 3633 * (t * t) + 4095.0 * (t * t * t * t) + 1575.0 * (t * t * t * t * t * t)) / (40320 * sr * (sn * sn * sn * sn * sn * sn * sn) * (ok * ok * ok * ok * ok * ok * ok * ok));
|
||||||
|
geoCoord.lat = ftphi - (de * de) * t10 + (de * de * de * de) * t11 - (de * de * de * de * de * de) * t12 + (de * de * de * de * de * de * de * de) * t13;
|
||||||
|
t14 = 1.0 / (sn * c * ok);
|
||||||
|
t15 = (1.0 + 2.0 * (t * t) + eta) / (6.0 * (sn * sn * sn) * c * (ok * ok * ok));
|
||||||
|
t16 = 1.0 * (5.0 + 6.0 * eta + 28.0 * (t * t) - 3.0 * (eta * eta) + 8.0 * (t * t) * eta + 24.0 * (t * t * t * t) - 4.0 * (eta * eta * eta) + 4.0 * (t * t) * (eta * eta) + 24.0 * (t * t) * (eta * eta * eta)) / (120.0 * (sn * sn * sn * sn * sn) * c * (ok * ok * ok * ok * ok));
|
||||||
|
t17 = 1.0 * (61.0 + 662.0 * (t * t) + 1320.0 * (t * t * t * t) + 720.0 * (t * t * t * t * t * t)) / (5040.0 * (sn * sn * sn * sn * sn * sn * sn) * c * (ok * ok * ok * ok * ok * ok * ok));
|
||||||
|
double dlam = de * t14 - (de * de * de) * t15 + (de * de * de * de * de) * t16 - (de * de * de * de * de * de * de) * t17;
|
||||||
|
double olam = (utmCoord.xZone * 6 - 183.0) * DEG_2_RAD;
|
||||||
|
geoCoord.lon = olam + dlam;
|
||||||
|
geoCoord.lon *= RAD_2_DEG;
|
||||||
|
geoCoord.lat *= RAD_2_DEG;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Współczynnik zniekształcenia skali mapy w południku osiowym dla odwzorowania kartograficznego UTM
|
||||||
|
private static final double ok = 0.9996;
|
||||||
|
private static final double DEG_2_RAD = Math.PI / 180.0;
|
||||||
|
private static final double RAD_2_DEG = 180.0 / Math.PI;
|
||||||
|
/**
|
||||||
|
* double a: dlługość dużej półsi, w metrach dla elipsoidy WGS-84, 6378137.0
|
||||||
|
*/
|
||||||
|
private static final double a = 6378137.0;
|
||||||
|
|
||||||
|
private static final double recf = 298.257223563;
|
||||||
|
/**
|
||||||
|
* double f: spłaszczenie elipsoidalne dla elipsoidy WGS-84, 1 / 298.257223563
|
||||||
|
*/
|
||||||
|
private static final double f = 1.0 / recf;
|
||||||
|
// private static final double b = a * (recf - 1) / recf;
|
||||||
|
private static final double b = a * (1.0 - f);
|
||||||
|
private static final double eSquared = calculateESquared(a, b);
|
||||||
|
private static final double e2Squared = calculateE2Squared(a, b);
|
||||||
|
private static final double tn = (a - b) / (a + b);
|
||||||
|
private static final double ap = a * (1.0 - tn + 5.0 * ((tn * tn) - (tn * tn * tn)) / 4.0 + 81.0 * ((tn * tn * tn * tn) - (tn * tn * tn * tn * tn)) / 64.0);
|
||||||
|
private static final double bp = 3.0 * a * (tn - (tn * tn) + 7.0 * ((tn * tn * tn) - (tn * tn * tn * tn)) / 8.0 + 55.0 * (tn * tn * tn * tn * tn) / 64.0) / 2.0;
|
||||||
|
private static final double cp = 15.0 * a * ((tn * tn) - (tn * tn * tn) + 3.0 * ((tn * tn * tn * tn) - (tn * tn * tn * tn * tn)) / 4.0) / 16.0;
|
||||||
|
private static final double dp = 35.0 * a * ((tn * tn * tn) - (tn * tn * tn * tn) + 11.0 * (tn * tn * tn * tn * tn) / 16.0) / 48.0;
|
||||||
|
private static final double ep = 315.0 * a * ((tn * tn * tn * tn) - (tn * tn * tn * tn * tn)) / 512.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funkcja do konwersji współrzędnych płaskich X/Y odwzorowania kartograficznego 1992 i 2000 na elipsoidalne lat/lon elipsoide WGS84.
|
||||||
|
* <p>
|
||||||
|
* PUWGCoord.proj: odwzorowanie kartograficzne (proj = 1 odpowiada odwzorowaniu 1992, natomiast każda inna odwzorowaniu 2000)
|
||||||
|
*
|
||||||
|
* @param puwgCoord współrzędne odwzorowania kartograficznego PUWG-1992 lub PUWG-2000 do konwersji [metry]
|
||||||
|
* @param geoCoord współrzędne geograficzne odwzorowania WGS-84 po konwersji [stopnie]
|
||||||
|
*/
|
||||||
|
public static void convertPuwgToLatLon(PUWGCoord puwgCoord, GeoCoord geoCoord) {
|
||||||
|
double ok = (puwgCoord.proj != 1) ? 0.999923 : 0.9993;
|
||||||
|
double nfn;
|
||||||
|
double tmd;
|
||||||
|
double ftphi;
|
||||||
|
double eta;
|
||||||
|
double dlam;
|
||||||
|
double olam = 0.0;
|
||||||
|
double strf = 0.0;
|
||||||
|
|
||||||
|
if (puwgCoord.proj == 1) {
|
||||||
|
olam = 19.0 * DEG_2_RAD;
|
||||||
|
strf = 0.0;
|
||||||
|
nfn = -5300000.0;
|
||||||
|
} else {
|
||||||
|
nfn = 0;
|
||||||
|
if (puwgCoord.easting < 6000000.0 && puwgCoord.easting > 5000000.0) {
|
||||||
|
strf = 5000000.0;
|
||||||
|
olam = 15.0 * DEG_2_RAD;
|
||||||
|
}
|
||||||
|
if (puwgCoord.easting < 7000000.0 && puwgCoord.easting > 6000000.0) {
|
||||||
|
strf = 6000000.0;
|
||||||
|
olam = 18.0 * DEG_2_RAD;
|
||||||
|
}
|
||||||
|
if (puwgCoord.easting < 8000000.0 && puwgCoord.easting > 7000000.0) {
|
||||||
|
strf = 7000000.0;
|
||||||
|
olam = 21.0 * DEG_2_RAD;
|
||||||
|
}
|
||||||
|
if (puwgCoord.easting < 9000000.0 && puwgCoord.easting > 8000000.0) {
|
||||||
|
strf = 8000000.0;
|
||||||
|
olam = 24.0 * DEG_2_RAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmd = (puwgCoord.northing - nfn) / ok;
|
||||||
|
double sr = sphsr(a, eSquared, 0.0);
|
||||||
|
ftphi = tmd / sr;
|
||||||
|
double t10, t11, t12, t13, t14, t15, t16, t17;
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
t10 = sphtmd(ap, bp, cp, dp, ep, ftphi);
|
||||||
|
sr = sphsr(a, eSquared, ftphi);
|
||||||
|
ftphi = ftphi + (tmd - t10) / sr;
|
||||||
|
}
|
||||||
|
sr = sphsr(a, eSquared, ftphi);
|
||||||
|
double sn = sphsn(a, eSquared, ftphi);
|
||||||
|
double sn_pow_2 = sn * sn;
|
||||||
|
double sn_pow_3 = sn_pow_2 * sn;
|
||||||
|
double sn_pow_4 = sn_pow_3 * sn;
|
||||||
|
double sn_pow_5 = sn_pow_4 * sn;
|
||||||
|
double sn_pow_7 = sn_pow_5 * sn_pow_2;
|
||||||
|
double s = Math.sin(ftphi);
|
||||||
|
double c = Math.cos(ftphi);
|
||||||
|
double t = s / c;
|
||||||
|
double t_pow_2 = t * t;
|
||||||
|
double t_pow_4 = t_pow_2 * t_pow_2;
|
||||||
|
double t_pow_6 = t_pow_4 * t_pow_2;
|
||||||
|
eta = e2Squared * (c * c);
|
||||||
|
double eta_pow_2 = eta * eta;
|
||||||
|
double eta_pow_3 = eta_pow_2 * eta;
|
||||||
|
double eta_pow_4 = eta_pow_2 * eta_pow_2;
|
||||||
|
double de = puwgCoord.easting - fe - strf;
|
||||||
|
double de_pow_2 = de * de;
|
||||||
|
double de_pow_3 = de_pow_2 * de;
|
||||||
|
double de_pow_4 = de_pow_3 * de;
|
||||||
|
t10 = t / (2.0 * sr * sn * (ok * ok));
|
||||||
|
t11 = t * (5.0 + 3.0 * t_pow_2 + eta - 4.0 * eta_pow_2 - 9.0 * t_pow_2 * eta) / (24.0 * sr * sn_pow_3 * (ok * ok * ok * ok));
|
||||||
|
t12 = t * (61.0 + 90.0 * t_pow_2 + 46.0 * eta + 45.0 * t_pow_4 - 252.0 * t_pow_2 * eta - 3.0 * eta_pow_2 + 100.0 * eta_pow_3 - 66.0 * t_pow_2 * eta_pow_2 - 90.0 * t_pow_4 * eta + 88.0 * eta_pow_4 + 225.0 * t_pow_4 * eta_pow_2 + 84.0 * t_pow_2 * eta_pow_3 - 192.0 * t_pow_2 * eta_pow_4) / (720.0 * sr * sn_pow_5 * (ok * ok * ok * ok * ok * ok));
|
||||||
|
t13 = t * (1385.0 + 3633 * t_pow_2 + 4095.0 * t_pow_4 + 1575.0 * t_pow_6) / (40320 * sr * sn_pow_7 * (ok * ok * ok * ok * ok * ok * ok * ok));
|
||||||
|
geoCoord.lat = ftphi - de_pow_2 * t10 + de_pow_4 * t11 - de_pow_3 * de_pow_3 * t12 + de_pow_4 * de_pow_3 * t13;
|
||||||
|
t14 = 1.0 / (sn * c * ok);
|
||||||
|
t15 = (1.0 + 2.0 * t_pow_2 + eta) / (6.0 * sn_pow_3 * c * (ok * ok * ok));
|
||||||
|
t16 = 1.0 * (5.0 + 6.0 * eta + 28.0 * t_pow_2 - 3.0 * eta_pow_2 + 8.0 * t_pow_2 * eta + 24.0 * t_pow_4 - 4.0 * eta_pow_3 + 4.0 * t_pow_2 * eta_pow_2 + 24.0 * t_pow_2 * eta_pow_3) / (120.0 * sn_pow_5 * c * (ok * ok * ok * ok * ok));
|
||||||
|
t17 = 1.0 * (61.0 + 662.0 * t_pow_2 + 1320.0 * t_pow_4 + 720.0 * t_pow_6) / (5040.0 * sn_pow_7 * c * (ok * ok * ok * ok * ok * ok * ok));
|
||||||
|
dlam = de * t14 - de_pow_3 * t15 + de_pow_3 * de_pow_2 * t16 - de_pow_3 * de_pow_4 * t17;
|
||||||
|
geoCoord.lon = olam + dlam;
|
||||||
|
geoCoord.lon *= RAD_2_DEG;
|
||||||
|
geoCoord.lat *= RAD_2_DEG;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.GridCoord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DaneWysok {
|
||||||
|
|
||||||
|
GridCoord idKw;
|
||||||
|
|
||||||
|
double suma;
|
||||||
|
|
||||||
|
int licz;
|
||||||
|
|
||||||
|
public DaneWysok(GridCoord idKw, double suma, int licz) {
|
||||||
|
this.idKw = idKw;
|
||||||
|
this.suma = suma;
|
||||||
|
this.licz = licz;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
public enum EAreaFeature {
|
||||||
|
|
||||||
|
FOREST,
|
||||||
|
SWAMP,
|
||||||
|
WATER,
|
||||||
|
BUILDINGS
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
public enum ELinearFeature {
|
||||||
|
|
||||||
|
ROAD,
|
||||||
|
WATER_WAY,
|
||||||
|
DITCH
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
public enum EOSMAmenity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v="hospital" | v="school" | v="post_office" | v="police" | v="marketplace" | v="fire_station" |
|
||||||
|
* v="theatre" | v="cinema" | v="pharmacy" | v="nursing_home" | v="bank" | v="fuel"
|
||||||
|
* v="university" | v="library" | v="clinic"
|
||||||
|
*/
|
||||||
|
HOSPITAL,
|
||||||
|
SCHOOL,
|
||||||
|
POST_OFFICE,
|
||||||
|
POLICE,
|
||||||
|
MARKETPLACE,
|
||||||
|
FIRE_STATION,
|
||||||
|
THEATRE,
|
||||||
|
CINEMA,
|
||||||
|
PHARMACY,
|
||||||
|
NURSING_HOME,
|
||||||
|
BANK,
|
||||||
|
FUEL,
|
||||||
|
UNIVERSITY,
|
||||||
|
LIBRARY,
|
||||||
|
CLINIC;
|
||||||
|
|
||||||
|
public static EOSMAmenity getValue(String str) {
|
||||||
|
switch (str) {
|
||||||
|
case "hospital": return HOSPITAL;
|
||||||
|
case "school": return SCHOOL;
|
||||||
|
case "post_office": return POST_OFFICE;
|
||||||
|
case "police": return POLICE;
|
||||||
|
case "marketplace": return MARKETPLACE;
|
||||||
|
case "fire_station": return FIRE_STATION;
|
||||||
|
case "theatre": return THEATRE;
|
||||||
|
case "cinema": return CINEMA;
|
||||||
|
case "pharmacy": return PHARMACY;
|
||||||
|
case "nursing_home": return NURSING_HOME;
|
||||||
|
case "bank": return BANK;
|
||||||
|
case "fuel": return FUEL;
|
||||||
|
case "university": return UNIVERSITY;
|
||||||
|
case "library": return LIBRARY;
|
||||||
|
case "clinic": return CLINIC;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
public enum EOSMBridge {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v="yes" | "viaduct"
|
||||||
|
*/
|
||||||
|
YES,
|
||||||
|
VIADUCT;
|
||||||
|
|
||||||
|
public static EOSMBridge getValue(String str) {
|
||||||
|
switch (str) {
|
||||||
|
case "yes": return YES;
|
||||||
|
case "viaduct": return VIADUCT;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
public enum EOSMBuilding {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v="yes" | v="chapel" | v="church" | v="house" | v="office" | v="manufacture" | v="industrial"
|
||||||
|
*/
|
||||||
|
YES,
|
||||||
|
CHAPEL,
|
||||||
|
CHURCH,
|
||||||
|
HOUSE,
|
||||||
|
OFFICE,
|
||||||
|
MANUFACTURE,
|
||||||
|
INDUSTRIAL;
|
||||||
|
|
||||||
|
|
||||||
|
public static EOSMBuilding getValue(String str) {
|
||||||
|
switch (str) {
|
||||||
|
case "yes": return YES;
|
||||||
|
case "chapel": return CHAPEL;
|
||||||
|
case "church": return CHURCH;
|
||||||
|
case "house": return HOUSE;
|
||||||
|
case "office": return OFFICE;
|
||||||
|
case "manufacture": return MANUFACTURE;
|
||||||
|
case "industrial": return INDUSTRIAL;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
public enum EOSMHighway {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v="motorway" | v="trunk" | v="primary" | v="secondary" | v="tertiary" | v="unclassified"
|
||||||
|
* | v="residential" | v="pedestrian" | v="track"
|
||||||
|
* | v="motorway_link" | v="trunk_link" | v="primary_link" | v="secondary_link" | v="tertiary_link"
|
||||||
|
* | v="living_street" | v="service"
|
||||||
|
*/
|
||||||
|
MOTORWAY,
|
||||||
|
TRUNCK,
|
||||||
|
PRIMARY,
|
||||||
|
SECONDARY,
|
||||||
|
TERTIARY,
|
||||||
|
UNCLASSIFIED,
|
||||||
|
RESIDENTIAL,
|
||||||
|
PEDESTRIAN,
|
||||||
|
TRACK,
|
||||||
|
MOTORWAY_LINK,
|
||||||
|
TRUNCK_LINK,
|
||||||
|
PRIMARY_LINK,
|
||||||
|
SECONDARY_LINK,
|
||||||
|
TERTIARY_LINK,
|
||||||
|
LIVING_STREET,
|
||||||
|
SERVICE;
|
||||||
|
|
||||||
|
public static EOSMHighway getValue(String str) {
|
||||||
|
switch (str) {
|
||||||
|
case "motorway": return MOTORWAY;
|
||||||
|
case "trunk": return TRUNCK;
|
||||||
|
case "primary": return PRIMARY;
|
||||||
|
case "secondary": return SECONDARY;
|
||||||
|
case "tertiary": return TERTIARY;
|
||||||
|
case "unclassified": return UNCLASSIFIED;
|
||||||
|
case "residential": return RESIDENTIAL;
|
||||||
|
case "pedestrian": return PEDESTRIAN;
|
||||||
|
case "track": return TRACK;
|
||||||
|
case "motorway_link": return MOTORWAY_LINK;
|
||||||
|
case "trunk_link": return TRUNCK_LINK;
|
||||||
|
case "primary_link": return PRIMARY_LINK;
|
||||||
|
case "secondary_link": return SECONDARY_LINK;
|
||||||
|
case "tertiary_link": return TERTIARY_LINK;
|
||||||
|
case "living_street": return LIVING_STREET;
|
||||||
|
case "service": return SERVICE;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
public enum EOSMLandcover {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v="trees" | v="water" | v="grass"
|
||||||
|
*/
|
||||||
|
TREES,
|
||||||
|
WATER,
|
||||||
|
GRASS;
|
||||||
|
|
||||||
|
public static EOSMLandcover getValue(String str) {
|
||||||
|
switch (str) {
|
||||||
|
case "trees": return TREES;
|
||||||
|
case "water": return WATER;
|
||||||
|
case "grass": return GRASS;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
public enum EOSMLanduse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v="forest" | v="residential" | v="commercial"
|
||||||
|
*/
|
||||||
|
FOREST,
|
||||||
|
RESIDENTIAL,
|
||||||
|
COMMERCIAL;
|
||||||
|
|
||||||
|
public static EOSMLanduse getValue(String str) {
|
||||||
|
switch (str) {
|
||||||
|
case "forest": return FOREST;
|
||||||
|
case "residential": return RESIDENTIAL;
|
||||||
|
case "commercial": return COMMERCIAL;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
public enum EOSMNatural {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v="water" | v="reservoir" | v="wetland" | v="wood"
|
||||||
|
*/
|
||||||
|
WATER,
|
||||||
|
RESERVOIR,
|
||||||
|
WETLAND,
|
||||||
|
WOOD;
|
||||||
|
|
||||||
|
public static EOSMNatural getValue(String str) {
|
||||||
|
switch (str) {
|
||||||
|
case "water": return WATER;
|
||||||
|
case "reservoir": return RESERVOIR;
|
||||||
|
case "wetland": return WETLAND;
|
||||||
|
case "wood": return WOOD;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
public enum EOSMWater {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v="lake" | v="reservoir" | v="river" | v="canal" | v="cove" | v="lagoon" | v="pond"
|
||||||
|
*/
|
||||||
|
LAKE,
|
||||||
|
RESERVOIR,
|
||||||
|
RIVER,
|
||||||
|
CANAL,
|
||||||
|
COVE,
|
||||||
|
LAGOON,
|
||||||
|
POND;
|
||||||
|
|
||||||
|
public static EOSMWater getValue(String str) {
|
||||||
|
switch (str) {
|
||||||
|
case "lake": return LAKE;
|
||||||
|
case "reservoir": return RESERVOIR;
|
||||||
|
case "river": return RIVER;
|
||||||
|
case "canal": return CANAL;
|
||||||
|
case "cove": return COVE;
|
||||||
|
case "lagoon": return LAGOON;
|
||||||
|
case "pond": return POND;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
public enum EOSMWaterway {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v="river" | v="riverbank" | v="stream" | v="canal" | v="drain" | v="ditch"
|
||||||
|
*/
|
||||||
|
RIVER,
|
||||||
|
RIVERBANK,
|
||||||
|
STREAM,
|
||||||
|
CANAL,
|
||||||
|
DRAIN,
|
||||||
|
DITCH;
|
||||||
|
|
||||||
|
public static EOSMWaterway getValue(String str) {
|
||||||
|
switch (str) {
|
||||||
|
case "river": return RIVER;
|
||||||
|
case "riverbank": return RIVERBANK;
|
||||||
|
case "stream": return STREAM;
|
||||||
|
case "canal": return CANAL;
|
||||||
|
case "drain": return DRAIN;
|
||||||
|
case "ditch": return DITCH;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
import org.nocrala.tools.gis.data.esri.shapefile.ShapeFileReader;
|
||||||
|
import org.nocrala.tools.gis.data.esri.shapefile.ValidationPreferences;
|
||||||
|
import org.nocrala.tools.gis.data.esri.shapefile.exception.InvalidShapeFileException;
|
||||||
|
import org.nocrala.tools.gis.data.esri.shapefile.header.ShapeFileHeader;
|
||||||
|
import org.nocrala.tools.gis.data.esri.shapefile.shape.AbstractShape;
|
||||||
|
import org.nocrala.tools.gis.data.esri.shapefile.shape.PointData;
|
||||||
|
import org.nocrala.tools.gis.data.esri.shapefile.shape.shapes.MultiPointZShape;
|
||||||
|
import org.nocrala.tools.gis.data.esri.shapefile.shape.shapes.PointShape;
|
||||||
|
import org.nocrala.tools.gis.data.esri.shapefile.shape.shapes.PolygonShape;
|
||||||
|
import org.nocrala.tools.gis.data.esri.shapefile.shape.shapes.PolylineShape;
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.GridCoord;
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.MapConsts;
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.Teren;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class EsriFileReader {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(EsriFileReader.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, InvalidShapeFileException {
|
||||||
|
String fn = "C:/Workspace/osm/dolnoslaskie-251217-free.shp/gis_osm_water_a_free_1.shp";
|
||||||
|
if (args.length > 0) {
|
||||||
|
fn = args[0];
|
||||||
|
}
|
||||||
|
FileInputStream is = new FileInputStream(fn);
|
||||||
|
ValidationPreferences prefs = new ValidationPreferences();
|
||||||
|
prefs.setMaxNumberOfPointsPerShape(50000);
|
||||||
|
// ShapeFileReader r = new ShapeFileReader(is);
|
||||||
|
ShapeFileReader r = new ShapeFileReader(is, prefs);
|
||||||
|
|
||||||
|
ShapeFileHeader h = r.getHeader();
|
||||||
|
// System.out.println("The shape type of this files is " + h.getShapeType());
|
||||||
|
|
||||||
|
HashMap<String, Relation> relationsMap = new HashMap<>();
|
||||||
|
HashMap<String, Way> waysMap = new HashMap<>();
|
||||||
|
|
||||||
|
LOGGER.debug("Poczatek odczytu danych o pokryciu wodami z pliku: " + fn);
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
AbstractShape s;
|
||||||
|
int relId = 0;
|
||||||
|
int wayId = 0;
|
||||||
|
int nodeId = 0;
|
||||||
|
while ((s = r.next()) != null) {
|
||||||
|
count++;
|
||||||
|
switch (s.getShapeType()) {
|
||||||
|
case POINT:
|
||||||
|
PointShape aPoint = (PointShape) s;
|
||||||
|
// Do something with the point shape...
|
||||||
|
break;
|
||||||
|
case MULTIPOINT_Z:
|
||||||
|
MultiPointZShape aMultiPointZ = (MultiPointZShape) s;
|
||||||
|
// Do something with the MultiPointZ shape...
|
||||||
|
break;
|
||||||
|
case POLYLINE:
|
||||||
|
if (s instanceof PolylineShape) {
|
||||||
|
PolylineShape aPolyline = (PolylineShape) s;
|
||||||
|
if (aPolyline.getBoxMinX() > 10 && aPolyline.getBoxMaxX() < 30
|
||||||
|
&& aPolyline.getBoxMinY() > 40 && aPolyline.getBoxMaxY() < 58) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case POLYGON:
|
||||||
|
PolygonShape aPolygon = (PolygonShape) s;
|
||||||
|
if (aPolygon.getBoxMinX() > 10 && aPolygon.getBoxMaxX() < 30
|
||||||
|
&& aPolygon.getBoxMinY() > 40 && aPolygon.getBoxMaxY() < 58) {
|
||||||
|
// System.out.println("I read a Polygon with "
|
||||||
|
// + aPolygon.getNumberOfParts() + " parts and "
|
||||||
|
// + aPolygon.getNumberOfPoints() + " points");
|
||||||
|
Relation currRelation = new Relation("" + relId);
|
||||||
|
currRelation.natural = EOSMNatural.WATER;
|
||||||
|
relId++;
|
||||||
|
for (int i = 0; i < aPolygon.getNumberOfParts(); i++) {
|
||||||
|
PointData[] points = aPolygon.getPointsOfPart(i);
|
||||||
|
Way currWay = new Way("" + wayId);
|
||||||
|
wayId++;
|
||||||
|
boolean jest_wezel_z_obszaru = false;
|
||||||
|
for (int j = 0; j < points.length; j++) {
|
||||||
|
Node currNode = new Node("" + nodeId);
|
||||||
|
nodeId++;
|
||||||
|
currNode.lon = points[j].getX() + 180;
|
||||||
|
currNode.lat = points[j].getY() + 90;
|
||||||
|
if (currNode.lon >= MapConsts.X_REF && currNode.lon <= MapConsts.X_REF + MapConsts.DX_REF
|
||||||
|
&& currNode.lat >= MapConsts.Y_REF && currNode.lat <= MapConsts.Y_REF + MapConsts.DY_REF) {
|
||||||
|
jest_wezel_z_obszaru = true;
|
||||||
|
}
|
||||||
|
currNode.lon = Math.max(currNode.lon, MapConsts.X_REF);
|
||||||
|
currNode.lon = Math.min(currNode.lon, MapConsts.X_REF + MapConsts.DX_REF);
|
||||||
|
currNode.lon -= 180;
|
||||||
|
currNode.lat = Math.max(currNode.lat, MapConsts.Y_REF);
|
||||||
|
currNode.lat = Math.min(currNode.lat, MapConsts.Y_REF + MapConsts.DY_REF);
|
||||||
|
currNode.lat -= 90;
|
||||||
|
|
||||||
|
currNode.idX = GridCoord.zamienDlugoscGeoNaIdKwadratuX(currNode.lon);
|
||||||
|
currNode.idY = GridCoord.zamienSzerokoscGeoNaIdKwadratuY(currNode.lat);
|
||||||
|
if (currNode.idX > 0 || currNode.idY > 0) {
|
||||||
|
currWay.nodes.add(currNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (jest_wezel_z_obszaru) {
|
||||||
|
boolean clockwise = clockwiseOrientedPolygon(points);
|
||||||
|
if (clockwise) {
|
||||||
|
if (currWay.nodes.size() > 0) {
|
||||||
|
currRelation.outerWays.add(currWay);
|
||||||
|
currWay.natural = EOSMNatural.WATER;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currRelation.innerWays.add(currWay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// String orient = clockwise ? clockwiseStr : counterclockwiseStr;
|
||||||
|
// System.out.println("- part " + i + " has " + points.length
|
||||||
|
// + " points. - orientation= " + orient);
|
||||||
|
}
|
||||||
|
if (currRelation.outerWays.size() > 0) {
|
||||||
|
relationsMap.put(currRelation.id, currRelation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// System.out.println("Read other type of shape.");
|
||||||
|
}
|
||||||
|
if (count % 1000 == 0) {
|
||||||
|
LOGGER.debug("shape count= " + count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// System.out.println("Total shapes read: " + total);
|
||||||
|
is.close();
|
||||||
|
LOGGER.debug("Koniec odczytu danych o pokryciu wodami z pliku: " + fn);
|
||||||
|
try {
|
||||||
|
LOGGER.debug("Poczatek przetwarzania danych o pokryciu wodami");
|
||||||
|
OpenStreetMapReader.generujDaneTerenowe("wody", relationsMap, waysMap, null);
|
||||||
|
LOGGER.debug("Koniec przetwarzania danych o pokryciu wodami");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < Worker.workers.size(); i++) {
|
||||||
|
try {
|
||||||
|
Worker.workers.get(i).join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOGGER.debug("Poczatek zapisu danych o pokryciu wodami");
|
||||||
|
Teren.zapisBuforaMapyDoPliku();
|
||||||
|
// Teren.setBinarnyFormatPliku(false);
|
||||||
|
// Teren.zapisBuforaMapyDoPliku();
|
||||||
|
Teren.reset();
|
||||||
|
LOGGER.debug("Koniec zapisu danych o pokryciu wodami");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean clockwiseOrientedPolygon(PointData[] points) {
|
||||||
|
PointData[] vertices = new PointData[points.length - 1];
|
||||||
|
for (int i = 0; i < vertices.length; i++) {
|
||||||
|
vertices[i] = points[i];
|
||||||
|
}
|
||||||
|
int smallest = 0;
|
||||||
|
for (int i = 1; i < vertices.length; i++) {
|
||||||
|
if (lexicographicalCompare(vertices[i].getX(), vertices[i].getY(),
|
||||||
|
vertices[smallest].getX(), vertices[smallest].getY()) == -1) {
|
||||||
|
smallest = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PointData center = vertices[smallest];
|
||||||
|
PointData first = vertices[(smallest - 1 + vertices.length) % vertices.length];
|
||||||
|
PointData last = vertices[(smallest + 1) % vertices.length];
|
||||||
|
// first == a, center == b, last == c
|
||||||
|
// (xb - xa) * (yc - ya) - (xc - xa) * (yb - ya)
|
||||||
|
double det = (center.getX() - first.getX()) * (last.getY() - first.getY())
|
||||||
|
- (last.getX() - first.getX()) * (center.getY() - first.getY());
|
||||||
|
|
||||||
|
return (det < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Porównuje dwa punkty leksykograficznie.
|
||||||
|
* <p>Jeżeli (x1, y1) mniejsze od (x2, y2) to zwraca -1
|
||||||
|
* <p>Jeżeli (x1, y1) rowne (x2, y2) to zwraca 0
|
||||||
|
* <p>Jeżeli (x1, y1) wieksze od (x2, y2) to zwraca 1
|
||||||
|
*
|
||||||
|
* @param x1 współrzędna x pierwszego punktu
|
||||||
|
* @param y1 współrzędna y pierwszego punktu
|
||||||
|
* @param x2 współrzędna x drugiego punktu
|
||||||
|
* @param y2 współrzędna y drugiego punktu
|
||||||
|
* @return -1 gdy pierwszy punkt mniejszy, 0 gdy punkty rowne, 1 gdy pierwszy punkt wiekszy
|
||||||
|
*/
|
||||||
|
public static int lexicographicalCompare(double x1, double y1, double x2, double y2) {
|
||||||
|
if (x1 < x2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (x1 > x2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (y1 < y2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (y1 > y2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MapBounds {
|
||||||
|
double minLat;
|
||||||
|
double minLon;
|
||||||
|
double maxLat;
|
||||||
|
double maxLon;
|
||||||
|
}
|
||||||
107
src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Node.java
Normal file
107
src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Node.java
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.Kwadrat;
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.MapConsts;
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.Teren;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Node {
|
||||||
|
String id;
|
||||||
|
double lon = 0; // x
|
||||||
|
double lat = 0; // y
|
||||||
|
int idX = -1;
|
||||||
|
int idY = -1;
|
||||||
|
int buildingsCount = 0;
|
||||||
|
|
||||||
|
// GridCoord idKw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* k="amenity" - v="hospital" | v="school" | v="post_office" | v="police" | v="marketplace" | v="fire_station" |
|
||||||
|
* v="theatre" | v="cinema" | v="pharmacy" | v="nursing_home" | v="bank" | v="fuel"
|
||||||
|
* v="university" | v="library"
|
||||||
|
*/
|
||||||
|
public EOSMAmenity amenity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* k="building" - v="yes" | v="chapel" | v="church" | v="house" | v="office" | v="manufacture" | v="industrial"
|
||||||
|
*/
|
||||||
|
public EOSMBuilding building;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* k="bridge" - v="yes" | "viaduct"
|
||||||
|
*/
|
||||||
|
public EOSMBridge bridge;
|
||||||
|
|
||||||
|
public Node(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node(Node oryg) {
|
||||||
|
this.id = oryg.id;
|
||||||
|
lon = oryg.lon;
|
||||||
|
lat = oryg.lat;
|
||||||
|
idX = oryg.idX;
|
||||||
|
idY = oryg.idY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static final int BUILDINGS_COUNT;
|
||||||
|
static {
|
||||||
|
switch (MapConsts.DL_MK) {
|
||||||
|
case 200:
|
||||||
|
BUILDINGS_COUNT = 8;
|
||||||
|
break;
|
||||||
|
case 100:
|
||||||
|
BUILDINGS_COUNT = 4;
|
||||||
|
break;
|
||||||
|
case 50:
|
||||||
|
BUILDINGS_COUNT = 2;
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
BUILDINGS_COUNT = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BUILDINGS_COUNT = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeAreaFeatureIntoSquare(EAreaFeature type) {
|
||||||
|
if (buildingsCount >= BUILDINGS_COUNT) {
|
||||||
|
Kwadrat kw = Teren.getKwadrat(idX, idY);
|
||||||
|
kw.setStopienZabudowy(1.0f);
|
||||||
|
} else if (buildingsCount > 0) {
|
||||||
|
Kwadrat kw = Teren.getKwadrat(idX, idY);
|
||||||
|
kw.setStopienZabudowy(0.5f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Node{" +
|
||||||
|
"id=" + id + '\'' +
|
||||||
|
", lat='" + lat + '\'' +
|
||||||
|
", lon='" + lon + '\'' +
|
||||||
|
", idKw=(" + idX + ", " + idY + ")}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
Node node = (Node) o;
|
||||||
|
|
||||||
|
if (idX != node.idX) return false;
|
||||||
|
return idY == node.idY;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = idX;
|
||||||
|
result = 31 * result + idY;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,979 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.GridCoord;
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.Teren;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import javax.xml.stream.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OpenStreetMapReader {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(OpenStreetMapReader.class);
|
||||||
|
|
||||||
|
private static final String DATA_DIR = "c:/Workspace/openstreetmap-data-20160925/";
|
||||||
|
|
||||||
|
static final Object synch = new Object();
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
System.out.println("OpenStreetMapReader - Working Directory = " +
|
||||||
|
System.getProperty("user.dir"));
|
||||||
|
String osm_fn = DATA_DIR + args[0] + "-latest.osm";
|
||||||
|
HashMap<String, Relation> relationsMap = new HashMap<>(8000);
|
||||||
|
HashMap<String, Way> relationWaysMap = new HashMap<>(50000);
|
||||||
|
HashMap<String, Node> nodesMap = new HashMap<>(5000000);
|
||||||
|
HashMap<String, Node> buildingNodesMap = new HashMap<>(500000);
|
||||||
|
HashMap<String, Way> waysMap = new HashMap<>(800000);
|
||||||
|
String[] goals = {"lasy", "wody", "bagna", "zabudowa", "drogi", "rzeki", "rowy"};
|
||||||
|
ArrayList<String> toDo = new ArrayList<>();
|
||||||
|
for (int i = 1; i < args.length; i++) {
|
||||||
|
for (int j = 0; j < goals.length; j++) {
|
||||||
|
if (goals[j].equals(args[i])) {
|
||||||
|
toDo.add(goals[j]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MapBounds mapBounds = new MapBounds();
|
||||||
|
// readMapBounds(mapBounds, osm_fn);
|
||||||
|
for (int i = 0; i < toDo.size(); i++) {
|
||||||
|
relationsMap.clear();
|
||||||
|
relationWaysMap.clear();
|
||||||
|
nodesMap.clear();
|
||||||
|
buildingNodesMap.clear();
|
||||||
|
waysMap.clear();
|
||||||
|
readRelations(relationsMap, relationWaysMap, osm_fn, toDo.get(i));
|
||||||
|
readWays(nodesMap, relationWaysMap, waysMap, osm_fn, toDo.get(i));
|
||||||
|
readNodes(nodesMap, buildingNodesMap, mapBounds, osm_fn, toDo.get(i));
|
||||||
|
if (nodesMap.size() > 0) {
|
||||||
|
String nodes_poland_fn = DATA_DIR + "poland-latest_nodes.osm";
|
||||||
|
readNodes(nodesMap, null, mapBounds, nodes_poland_fn, toDo.get(i));
|
||||||
|
}
|
||||||
|
for (Relation rel : relationsMap.values()) {
|
||||||
|
rel.outerWays = rel.generatePolygons(rel.outerWays);
|
||||||
|
rel.innerWays = rel.generatePolygons(rel.innerWays);
|
||||||
|
}
|
||||||
|
LOGGER.debug("Poczatek przetwarzania danych dla regionu " + osm_fn + " - cel: " + toDo.get(i));
|
||||||
|
generujDaneTerenowe(toDo.get(i), relationsMap, waysMap, buildingNodesMap);
|
||||||
|
LOGGER.debug("Koniec przetwarzania danych dla regionu " + osm_fn + " - cel: " + toDo.get(i));
|
||||||
|
// Teren.setBinarnyFormatPliku(false);
|
||||||
|
// Teren.zapisBuforaMapyDoPliku();
|
||||||
|
// Teren.reset();
|
||||||
|
// Teren.setBinarnyFormatPliku(true);
|
||||||
|
}
|
||||||
|
LOGGER.debug("Poczatek zapisu danych dla regionu " + osm_fn);
|
||||||
|
Teren.zapisBuforaMapyDoPliku();
|
||||||
|
LOGGER.debug("Koniec zapisu danych dla regionu " + osm_fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// XMLOutputFactory outFactory = XMLOutputFactory.newInstance();
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
// XMLStreamWriter writer = outFactory.createXMLStreamWriter(new FileWriter("au2data\\output2.xml"));
|
||||||
|
//
|
||||||
|
// writer.writeStartDocument();
|
||||||
|
// writer.writeStartElement("document");
|
||||||
|
// writer.writeStartElement("data");
|
||||||
|
// writer.writeAttribute("name", "value");
|
||||||
|
// writer.writeEndElement();
|
||||||
|
// writer.writeEndElement();
|
||||||
|
// writer.writeEndDocument();
|
||||||
|
//
|
||||||
|
// writer.flush();
|
||||||
|
// writer.close();
|
||||||
|
//
|
||||||
|
// } catch (XMLStreamException e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
|
||||||
|
private static void readMapBounds(MapBounds mapBounds, String fn) throws Exception {
|
||||||
|
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||||
|
// FileInputStream is = new FileInputStream(fn);
|
||||||
|
FileInputStream is = new FileInputStream(fn);
|
||||||
|
// XMLStreamReader reader = factory.createXMLStreamReader(ClassLoader.getSystemResourceAsStream(fn));
|
||||||
|
XMLStreamReader reader = factory.createXMLStreamReader(is);
|
||||||
|
String val;
|
||||||
|
while (reader.hasNext()) {
|
||||||
|
int eventType = reader.next();
|
||||||
|
switch (eventType) {
|
||||||
|
case XMLStreamConstants.START_ELEMENT:
|
||||||
|
if ("bounds".equals(reader.getLocalName())) {
|
||||||
|
for (int i = 0; i < reader.getAttributeCount(); i++) {
|
||||||
|
val = reader.getAttributeLocalName(i);
|
||||||
|
switch (val) {
|
||||||
|
case "minlat":
|
||||||
|
val = reader.getAttributeValue(i);
|
||||||
|
mapBounds.minLat = Double.parseDouble(val);
|
||||||
|
break;
|
||||||
|
case "minlon":
|
||||||
|
val = reader.getAttributeValue(i);
|
||||||
|
mapBounds.minLon = Double.parseDouble(val);
|
||||||
|
break;
|
||||||
|
case "maxlat":
|
||||||
|
val = reader.getAttributeValue(i);
|
||||||
|
mapBounds.maxLat = Double.parseDouble(val);
|
||||||
|
break;
|
||||||
|
case "maxlon":
|
||||||
|
val = reader.getAttributeValue(i);
|
||||||
|
mapBounds.maxLon = Double.parseDouble(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readNodes(HashMap<String, Node> nodesMap, HashMap<String, Node> buildingNodesMap, MapBounds mapBounds, String fn, String genGoal) throws Exception {
|
||||||
|
Node currNode = null;
|
||||||
|
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||||
|
FileInputStream is = new FileInputStream(fn);
|
||||||
|
// XMLStreamReader reader = factory.createXMLStreamReader(ClassLoader.getSystemResourceAsStream(fn));
|
||||||
|
XMLStreamReader reader = factory.createXMLStreamReader(is);
|
||||||
|
String val;
|
||||||
|
int count = 1;
|
||||||
|
LOGGER.debug("Poczatek odczytu wezlow z pliku: " + fn);
|
||||||
|
while (reader.hasNext()) {
|
||||||
|
int eventType = reader.next();
|
||||||
|
switch (eventType) {
|
||||||
|
case XMLStreamConstants.START_ELEMENT:
|
||||||
|
if ("node".equals(reader.getLocalName())) {
|
||||||
|
val = reader.getAttributeValue(0);
|
||||||
|
// if ("3206180317".equals(val)) {
|
||||||
|
// logger.debug("!!!!!!!!!!! niepoprawny wezel id= " + val);
|
||||||
|
// }
|
||||||
|
if (count % 100000 == 0) {
|
||||||
|
LOGGER.debug("+-+-+-+-+-+-+-+- liczba odczytanych wezlow= " + count / 1000 + " [tys.], ostatni wezel id= " + val);
|
||||||
|
}
|
||||||
|
currNode = nodesMap.remove(val);
|
||||||
|
if (!"zabudowa".equals(genGoal)) {
|
||||||
|
if (currNode != null) {
|
||||||
|
int c = 0;
|
||||||
|
for (int i = 1; i < reader.getAttributeCount() && c < 2; i++) {
|
||||||
|
val = reader.getAttributeLocalName(i);
|
||||||
|
switch (val) {
|
||||||
|
case "lat":
|
||||||
|
val = reader.getAttributeValue(i);
|
||||||
|
currNode.lat = Double.parseDouble(val);
|
||||||
|
c++;
|
||||||
|
break;
|
||||||
|
case "lon":
|
||||||
|
val = reader.getAttributeValue(i);
|
||||||
|
currNode.lon = Double.parseDouble(val);
|
||||||
|
c++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (buildingNodesMap != null) {
|
||||||
|
if (currNode == null) {
|
||||||
|
currNode = buildingNodesMap.get(val);
|
||||||
|
if (currNode == null) {
|
||||||
|
currNode = new Node(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int c = 0;
|
||||||
|
for (int i = 1; i < reader.getAttributeCount() && c < 2; i++) {
|
||||||
|
val = reader.getAttributeLocalName(i);
|
||||||
|
switch (val) {
|
||||||
|
case "lat":
|
||||||
|
val = reader.getAttributeValue(i);
|
||||||
|
currNode.lat = Double.parseDouble(val);
|
||||||
|
c++;
|
||||||
|
break;
|
||||||
|
case "lon":
|
||||||
|
val = reader.getAttributeValue(i);
|
||||||
|
currNode.lon = Double.parseDouble(val);
|
||||||
|
c++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("tag".equals(reader.getLocalName())) {
|
||||||
|
if (currNode != null) {
|
||||||
|
String k = reader.getAttributeValue(0);
|
||||||
|
String v = reader.getAttributeValue(1);
|
||||||
|
switch (k) {
|
||||||
|
case "building":
|
||||||
|
currNode.building = EOSMBuilding.getValue(v);
|
||||||
|
break;
|
||||||
|
case "amenity":
|
||||||
|
currNode.amenity = EOSMAmenity.getValue(v);
|
||||||
|
break;
|
||||||
|
case "addr:housenumber":
|
||||||
|
currNode.buildingsCount++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("way".equals(reader.getLocalName())) {
|
||||||
|
reader.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XMLStreamConstants.CHARACTERS:
|
||||||
|
// tagContent = reader.getText().trim();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XMLStreamConstants.END_ELEMENT:
|
||||||
|
switch (reader.getLocalName()) {
|
||||||
|
case "node":
|
||||||
|
if (currNode != null) {
|
||||||
|
currNode.idX = GridCoord.zamienDlugoscGeoNaIdKwadratuX(currNode.lon);
|
||||||
|
currNode.idY = GridCoord.zamienSzerokoscGeoNaIdKwadratuY(currNode.lat);
|
||||||
|
if ("zabudowa".equals(genGoal) && currNode.buildingsCount > 0) {
|
||||||
|
buildingNodesMap.put(currNode.id, currNode);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
currNode = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readWays(HashMap<String, Node> nodesMap, HashMap<String, Way> relationWaysMap,
|
||||||
|
HashMap<String, Way> goalWaysMap, String fn, String genGoal) throws Exception {
|
||||||
|
Way currWay = null;
|
||||||
|
String tagContent = null;
|
||||||
|
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||||
|
// FileInputStream is = new FileInputStream(fn);
|
||||||
|
FileInputStream is = new FileInputStream(fn);
|
||||||
|
// XMLStreamReader reader = factory.createXMLStreamReader(ClassLoader.getSystemResourceAsStream(fn));
|
||||||
|
XMLStreamReader reader = factory.createXMLStreamReader(is);
|
||||||
|
String val;
|
||||||
|
int count = 0;
|
||||||
|
LOGGER.debug("Poczatek odczytu lamanych z pliku: " + fn + " - cel: " + genGoal);
|
||||||
|
while (reader.hasNext()) {
|
||||||
|
int eventType = reader.next();
|
||||||
|
switch (eventType) {
|
||||||
|
case XMLStreamConstants.START_ELEMENT:
|
||||||
|
if ("way".equals(reader.getLocalName())) {
|
||||||
|
val = reader.getAttributeValue(0);
|
||||||
|
currWay = relationWaysMap.get(val);
|
||||||
|
if (currWay == null) {
|
||||||
|
currWay = new Way(val);
|
||||||
|
}
|
||||||
|
// if ("314575560".equals(val)) {
|
||||||
|
// logger.debug("!!!!!");
|
||||||
|
// }
|
||||||
|
count++;
|
||||||
|
if (count % 10000 == 0) {
|
||||||
|
LOGGER.debug("=================== liczba odczytanych lamanych= " + count / 1000 + " [tys.], ostatnia lamana id= " + val);
|
||||||
|
LOGGER.debug("=>liczba lamanych celu=" + goalWaysMap.size() + ", liczba lamanych relacji=" + relationWaysMap.size() + ", liczba wezlow=" + nodesMap.size());
|
||||||
|
}
|
||||||
|
} else if ("nd".equals(reader.getLocalName())) {
|
||||||
|
if (currWay != null) {
|
||||||
|
// odczyt id wezla wchodzacego w sklad lamanej
|
||||||
|
val = reader.getAttributeValue(0);
|
||||||
|
Node node = nodesMap.get(val);
|
||||||
|
if (node == null) {
|
||||||
|
for (int i = 0; i < currWay.nodes.size(); i++) {
|
||||||
|
if (val.equals(currWay.nodes.get(i).id)) {
|
||||||
|
node = currWay.nodes.get(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node == null) {
|
||||||
|
node = new Node(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currWay.nodes.add(node);
|
||||||
|
}
|
||||||
|
} else if ("tag".equals(reader.getLocalName())) {
|
||||||
|
if (currWay != null) {
|
||||||
|
String k = reader.getAttributeValue(0);
|
||||||
|
String v = reader.getAttributeValue(1);
|
||||||
|
switch (k) {
|
||||||
|
case "highway":
|
||||||
|
currWay.highway = EOSMHighway.getValue(v);
|
||||||
|
break;
|
||||||
|
case "waterway":
|
||||||
|
currWay.waterway = EOSMWaterway.getValue(v);
|
||||||
|
break;
|
||||||
|
case "natural":
|
||||||
|
currWay.natural = EOSMNatural.getValue(v);
|
||||||
|
break;
|
||||||
|
case "water":
|
||||||
|
currWay.water = EOSMWater.getValue(v);
|
||||||
|
break;
|
||||||
|
case "landuse":
|
||||||
|
currWay.landuse = EOSMLanduse.getValue(v);
|
||||||
|
break;
|
||||||
|
case "landcover":
|
||||||
|
currWay.landcover = EOSMLandcover.getValue(v);
|
||||||
|
break;
|
||||||
|
case "bridge":
|
||||||
|
currWay.bridge = EOSMBridge.getValue(v);
|
||||||
|
break;
|
||||||
|
case "building":
|
||||||
|
currWay.building = EOSMBuilding.getValue(v);
|
||||||
|
break;
|
||||||
|
case "amenity":
|
||||||
|
currWay.amenity = EOSMAmenity.getValue(v);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XMLStreamConstants.CHARACTERS:
|
||||||
|
// tagContent = reader.getText().trim();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XMLStreamConstants.END_ELEMENT:
|
||||||
|
if (currWay != null) {
|
||||||
|
switch (reader.getLocalName()) {
|
||||||
|
case "way":
|
||||||
|
if ("lasy".equals(genGoal)) {
|
||||||
|
// LASY
|
||||||
|
if (relationWaysMap.containsKey(currWay.id)) {
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
} else if ((currWay.landuse != null) && currWay.landuse == EOSMLanduse.FOREST) {
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
} else if ((currWay.landcover != null) && currWay.landcover == EOSMLandcover.TREES) {
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
} else if ((currWay.natural != null) && currWay.natural == EOSMNatural.WOOD) {
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("wody".equals(genGoal)) {
|
||||||
|
// SZEROKIE RZEKI, JEZIORA I ZBIORNIKI WODNE
|
||||||
|
if (relationWaysMap.containsKey(currWay.id)) {
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
} else if (currWay.natural != null && currWay.natural == EOSMNatural.WATER) {
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
} else if (currWay.waterway != null && currWay.waterway == EOSMWaterway.RIVERBANK) {
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("drogi".equals(genGoal)) {
|
||||||
|
// DROGI
|
||||||
|
if (currWay.highway != null) {
|
||||||
|
switch (currWay.highway) {
|
||||||
|
case MOTORWAY:
|
||||||
|
case TRUNCK:
|
||||||
|
case PRIMARY:
|
||||||
|
case SECONDARY:
|
||||||
|
case TERTIARY:
|
||||||
|
case UNCLASSIFIED:
|
||||||
|
case RESIDENTIAL:
|
||||||
|
case PEDESTRIAN:
|
||||||
|
case TRACK:
|
||||||
|
case MOTORWAY_LINK:
|
||||||
|
case TRUNCK_LINK:
|
||||||
|
case PRIMARY_LINK:
|
||||||
|
case SECONDARY_LINK:
|
||||||
|
case TERTIARY_LINK:
|
||||||
|
case SERVICE:
|
||||||
|
case LIVING_STREET:
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// case "footway":
|
||||||
|
// case "bridleway":
|
||||||
|
// case "steps":
|
||||||
|
// case "cycleway":
|
||||||
|
// case "PATH":
|
||||||
|
// case "proposed":
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("rzeki".equals(genGoal)) {
|
||||||
|
// RZEKI (LINIOWE, NIESZEROKIE)
|
||||||
|
if (currWay.waterway != null) {
|
||||||
|
switch (currWay.waterway) {
|
||||||
|
case RIVER:
|
||||||
|
case CANAL:
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("rowy".equals(genGoal)) {
|
||||||
|
// ROWY
|
||||||
|
if (currWay.waterway != null) {
|
||||||
|
switch (currWay.waterway) {
|
||||||
|
case STREAM:
|
||||||
|
case DRAIN:
|
||||||
|
case DITCH:
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("bagna".equals(genGoal)) {
|
||||||
|
// BAGNA
|
||||||
|
if (currWay.natural != null) {
|
||||||
|
switch (currWay.natural) {
|
||||||
|
case WETLAND:
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("zabudowa".equals(genGoal)) {
|
||||||
|
// ZABUDOWA
|
||||||
|
if (currWay.landuse != null) {
|
||||||
|
switch (currWay.landuse) {
|
||||||
|
case RESIDENTIAL:
|
||||||
|
case COMMERCIAL:
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
} else if (currWay.building != null) {
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
} else if (currWay.amenity != null) {
|
||||||
|
switch (currWay.amenity) {
|
||||||
|
case HOSPITAL:
|
||||||
|
case CLINIC:
|
||||||
|
case POST_OFFICE:
|
||||||
|
case POLICE:
|
||||||
|
case FIRE_STATION:
|
||||||
|
case MARKETPLACE:
|
||||||
|
goalWaysMap.put(currWay.id, currWay);
|
||||||
|
for (Node node : currWay.nodes) {
|
||||||
|
nodesMap.put(node.id, node);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currWay = null;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readRelations(HashMap<String, Relation> relationsMap, HashMap<String, Way> relationWaysMap,
|
||||||
|
String fn, String genGoal) throws Exception {
|
||||||
|
Relation currRelation = null;
|
||||||
|
String tagContent = null;
|
||||||
|
if (!("lasy".equals(genGoal)) && !("wody".equals(genGoal))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// fn += "-latest_relations.osm";
|
||||||
|
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||||
|
// XMLStreamReader reader = factory.createXMLStreamReader(ClassLoader.getSystemResourceAsStream(fn));
|
||||||
|
// BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(fn));
|
||||||
|
// XMLStreamReader reader = factory.createXMLStreamReader(inputStream);
|
||||||
|
|
||||||
|
FileInputStream is = new FileInputStream(fn);
|
||||||
|
// XMLStreamReader reader = factory.createXMLStreamReader(ClassLoader.getSystemResourceAsStream(fn));
|
||||||
|
XMLStreamReader reader = factory.createXMLStreamReader(is);
|
||||||
|
|
||||||
|
String val;
|
||||||
|
int count = 0;
|
||||||
|
LOGGER.debug("Poczatek odczytu relacji z pliku: " + fn + " - cel: " + genGoal);
|
||||||
|
while (reader.hasNext()) {
|
||||||
|
int eventType = reader.next();
|
||||||
|
switch (eventType) {
|
||||||
|
case XMLStreamConstants.START_ELEMENT:
|
||||||
|
if ("relation".equals(reader.getLocalName())) {
|
||||||
|
val = reader.getAttributeValue(0);
|
||||||
|
currRelation = new Relation(val);
|
||||||
|
count++;
|
||||||
|
if (count % 1000 == 0) {
|
||||||
|
LOGGER.debug("+-+-+-+-+-+-+-+- liczba odczytanych relacji= " + count / 1000 + " [tys.], ostatnia relacja id= " + val);
|
||||||
|
}
|
||||||
|
} else if ("member".equals(reader.getLocalName())) {
|
||||||
|
if (currRelation != null) {
|
||||||
|
String v = reader.getAttributeValue(0);
|
||||||
|
if ("way".equals(v)) {
|
||||||
|
// identyfikator łamanej
|
||||||
|
String v1 = reader.getAttributeValue(1);
|
||||||
|
// rola łamanej w relacji
|
||||||
|
String v2 = reader.getAttributeValue(2);
|
||||||
|
if ("outer".equals(v2)) {
|
||||||
|
Way way = new Way(v1);
|
||||||
|
if (way != null) {
|
||||||
|
currRelation.outerWays.add(way);
|
||||||
|
}
|
||||||
|
} else if ("inner".equals(v2)) {
|
||||||
|
Way way = new Way(v1);
|
||||||
|
if (way != null) {
|
||||||
|
currRelation.innerWays.add(way);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("tag".equals(reader.getLocalName())) {
|
||||||
|
if (currRelation != null) {
|
||||||
|
String k = reader.getAttributeValue(0);
|
||||||
|
String v = reader.getAttributeValue(1);
|
||||||
|
switch (k) {
|
||||||
|
case "waterway":
|
||||||
|
currRelation.waterway = EOSMWaterway.getValue(v);
|
||||||
|
break;
|
||||||
|
case "natural":
|
||||||
|
currRelation.natural = EOSMNatural.getValue(v);
|
||||||
|
break;
|
||||||
|
case "landuse":
|
||||||
|
currRelation.landuse = EOSMLanduse.getValue(v);
|
||||||
|
break;
|
||||||
|
case "landcover":
|
||||||
|
currRelation.landcover = EOSMLandcover.getValue(v);
|
||||||
|
break;
|
||||||
|
case "type":
|
||||||
|
if (!"multipolygon".equals(v)) {
|
||||||
|
currRelation = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XMLStreamConstants.CHARACTERS:
|
||||||
|
// tagContent = reader.getText().trim();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XMLStreamConstants.END_ELEMENT:
|
||||||
|
switch (reader.getLocalName()) {
|
||||||
|
case "relation":
|
||||||
|
if (currRelation != null) {
|
||||||
|
if (currRelation.outerWays.size() > 0) {
|
||||||
|
if ("lasy".equals(genGoal)) {
|
||||||
|
if (((currRelation.landuse != null) && currRelation.landuse == EOSMLanduse.FOREST)
|
||||||
|
|| ((currRelation.natural != null) && currRelation.natural == EOSMNatural.WOOD)) {
|
||||||
|
|
||||||
|
relationsMap.put(currRelation.id, currRelation);
|
||||||
|
for (Way way : currRelation.outerWays) {
|
||||||
|
// kopiuje tagi dla lamanych zewnetrznych
|
||||||
|
way.copyTags(currRelation);
|
||||||
|
relationWaysMap.put(way.id, way);
|
||||||
|
}
|
||||||
|
for (Way way : currRelation.innerWays) {
|
||||||
|
relationWaysMap.put(way.id, way);
|
||||||
|
// nie kopiuje tagow dla lamanych wewnetrznych, gdyz one maja wlasne tagi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("wody".equals(genGoal)) {
|
||||||
|
if (((currRelation.natural != null) && currRelation.natural == EOSMNatural.WATER)
|
||||||
|
|| ((currRelation.waterway != null) && currRelation.waterway == EOSMWaterway.RIVERBANK)) {
|
||||||
|
|
||||||
|
relationsMap.put(currRelation.id, currRelation);
|
||||||
|
for (Way way : currRelation.outerWays) {
|
||||||
|
// kopiuje tagi dla lamanych zewnetrznych
|
||||||
|
way.copyTags(currRelation);
|
||||||
|
relationWaysMap.put(way.id, way);
|
||||||
|
}
|
||||||
|
for (Way way : currRelation.innerWays) {
|
||||||
|
relationWaysMap.put(way.id, way);
|
||||||
|
// nie kopiuje tagow dla lamanych wewnetrznych, gdyz one maja wlasne tagi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currRelation = null;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void generujDaneTerenowe(String genGoal, HashMap<String, Relation> relationsMap,
|
||||||
|
HashMap<String, Way> waysMap, HashMap<String, Node> buildingNodesMap) {
|
||||||
|
int count = 0;
|
||||||
|
int m1 = relationsMap.size() / 100;
|
||||||
|
m1 = (m1 == 0) ? 1 : m1;
|
||||||
|
int m2 = waysMap.size() / 100;
|
||||||
|
m2 = (m2 == 0) ? 1 : m2;
|
||||||
|
ArrayList<Way> wayList = new ArrayList<>(waysMap.values());
|
||||||
|
// określenie formatu odczytu danych terenowych przed uaktualnieniem
|
||||||
|
if ("lasy".equals(genGoal)) {
|
||||||
|
for (Relation rel : relationsMap.values()) {
|
||||||
|
count++;
|
||||||
|
rel.removeLastNodes();
|
||||||
|
rel.removeSimilarNodes();
|
||||||
|
rel.removeCollinearNodes(true);
|
||||||
|
rel.writeAreaFeatureIntoSquares(EAreaFeature.FOREST);
|
||||||
|
if (count % m1 == 0) {
|
||||||
|
LOGGER.debug(">><<>><<>><<: rel count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
// usunięcie powtórzenia węzła z łamanej definiującej obszar
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.nodes.remove(way.nodes.size() - 1);
|
||||||
|
}
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(true);
|
||||||
|
way.writeAreaFeatureIntoSquares(EAreaFeature.FOREST, false);
|
||||||
|
if (count % m2 == 0) {
|
||||||
|
LOGGER.debug("<><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("wody".equals(genGoal)) {
|
||||||
|
for (Relation rel : relationsMap.values()) {
|
||||||
|
count++;
|
||||||
|
rel.removeLastNodes();
|
||||||
|
rel.removeSimilarNodes();
|
||||||
|
rel.removeCollinearNodes(true);
|
||||||
|
rel.writeAreaFeatureIntoSquares(EAreaFeature.WATER);
|
||||||
|
if (count % m1 == 0) {
|
||||||
|
LOGGER.debug(">><<>><<>><<: rel count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
// usunięcie powtórzenia węzła z łamanej definiującej obszar
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.nodes.remove(way.nodes.size() - 1);
|
||||||
|
}
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(true);
|
||||||
|
way.writeAreaFeatureIntoSquares(EAreaFeature.WATER, false);
|
||||||
|
if (count % m2 == 0) {
|
||||||
|
LOGGER.debug("<><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("bagna".equals(genGoal)) {
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
// usunięcie powtórzenia węzła z łamanej definiującej obszar
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.nodes.remove(way.nodes.size() - 1);
|
||||||
|
}
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(true);
|
||||||
|
way.writeAreaFeatureIntoSquares(EAreaFeature.SWAMP, false);
|
||||||
|
if (count % m2 == 0) {
|
||||||
|
LOGGER.debug("<><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("zabudowa".equals(genGoal)) {
|
||||||
|
// wygenerowanie danych o stopniu zabudowy na podstawie danych adresowych
|
||||||
|
// HashMap<Node, Node> newNodesMap = new HashMap<>();
|
||||||
|
// for (Node node : buildingNodesMap.values()) {
|
||||||
|
// Node node1 = newNodesMap.get(node);
|
||||||
|
// if (node1 != null) {
|
||||||
|
// node1.buildingsCount += node.buildingsCount;
|
||||||
|
// } else {
|
||||||
|
// newNodesMap.put(node, node);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// buildingNodesMap.clear();
|
||||||
|
|
||||||
|
for (Node node : buildingNodesMap.values()) {
|
||||||
|
node.writeAreaFeatureIntoSquare(EAreaFeature.BUILDINGS);
|
||||||
|
}
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
// usunięcie powtórzenia węzła z łamanej definiującej obszar
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.nodes.remove(way.nodes.size() - 1);
|
||||||
|
}
|
||||||
|
// for (int i = 0; i < way.nodes.size(); i++) {
|
||||||
|
// Node node = way.nodes.get(i);
|
||||||
|
// if (node.idX <= 0 || node.idY <= 0) {
|
||||||
|
// logger.debug("!!!! niepoprawny wezel id= " + node.id + ", lamana id= " + way.id);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(true);
|
||||||
|
way.writeAreaFeatureIntoSquares(EAreaFeature.BUILDINGS, false);
|
||||||
|
if (count % m2 == 0) {
|
||||||
|
LOGGER.debug("<><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("drogi".equals(genGoal)) {
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
// if ("249908111".equals(way.id) || "238353558".equals(way.id)) {
|
||||||
|
// logger.debug("!!!!!");
|
||||||
|
// }
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(false);
|
||||||
|
way.removeSteps();
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.writeLinearFeatureIntoSquares(ELinearFeature.ROAD);
|
||||||
|
}
|
||||||
|
// if (count % 10000 == 0) {
|
||||||
|
// logger.debug("-*-*-*-*-");
|
||||||
|
// logger.debug("maxMemory=" + java.lang.Runtime.getRuntime().maxMemory()
|
||||||
|
// + ", totalMemory=" + java.lang.Runtime.getRuntime().totalMemory()
|
||||||
|
// + ", freeMemory=" + java.lang.Runtime.getRuntime().freeMemory());
|
||||||
|
// }
|
||||||
|
// count++;
|
||||||
|
if (count % m2 == 0) {
|
||||||
|
LOGGER.debug("<><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("rzeki".equals(genGoal)) {
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(false);
|
||||||
|
way.removeSteps();
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.writeLinearFeatureIntoSquares(ELinearFeature.WATER_WAY);
|
||||||
|
}
|
||||||
|
if (count % m2 == 0) {
|
||||||
|
LOGGER.debug("<><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("rowy".equals(genGoal)) {
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(false);
|
||||||
|
way.removeSteps();
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.writeLinearFeatureIntoSquares(ELinearFeature.DITCH);
|
||||||
|
}
|
||||||
|
if (count % m2 == 0) {
|
||||||
|
LOGGER.debug("<><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void generujDaneTerenowe2(String genGoal, HashMap<String, Relation> relationsMap,
|
||||||
|
HashMap<String, Way> waysMap, HashMap<String, Node> buildingNodesMap) {
|
||||||
|
int count = 0;
|
||||||
|
int m1 = relationsMap.size() / 100;
|
||||||
|
m1 = (m1 == 0) ? 1 : m1;
|
||||||
|
ArrayList<Way> wayList = new ArrayList<>(waysMap.values());
|
||||||
|
// określenie formatu odczytu danych terenowych przed uaktualnieniem
|
||||||
|
if ("lasy".equals(genGoal)) {
|
||||||
|
for (Relation rel : relationsMap.values()) {
|
||||||
|
count++;
|
||||||
|
rel.removeLastNodes();
|
||||||
|
rel.removeSimilarNodes();
|
||||||
|
rel.removeCollinearNodes(true);
|
||||||
|
rel.writeAreaFeatureIntoSquares(EAreaFeature.FOREST);
|
||||||
|
if (count % m1 == 0) {
|
||||||
|
synchronized (synch) {
|
||||||
|
LOGGER.debug(Thread.currentThread().getName() + " >><<>><<>><<: rel count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
// usunięcie powtórzenia węzła z łamanej definiującej obszar
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.nodes.remove(way.nodes.size() - 1);
|
||||||
|
}
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(true);
|
||||||
|
way.writeAreaFeatureIntoSquares(EAreaFeature.FOREST, false);
|
||||||
|
synchronized (synch) {
|
||||||
|
LOGGER.debug(Thread.currentThread().getName() + " <><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("wody".equals(genGoal)) {
|
||||||
|
for (Relation rel : relationsMap.values()) {
|
||||||
|
count++;
|
||||||
|
rel.removeLastNodes();
|
||||||
|
rel.removeSimilarNodes();
|
||||||
|
rel.removeCollinearNodes(true);
|
||||||
|
rel.writeAreaFeatureIntoSquares(EAreaFeature.WATER);
|
||||||
|
synchronized (synch) {
|
||||||
|
LOGGER.debug(Thread.currentThread().getName() + " >><<>><<>><<: rel count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
// usunięcie powtórzenia węzła z łamanej definiującej obszar
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.nodes.remove(way.nodes.size() - 1);
|
||||||
|
}
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(true);
|
||||||
|
way.writeAreaFeatureIntoSquares(EAreaFeature.WATER, false);
|
||||||
|
synchronized (synch) {
|
||||||
|
LOGGER.debug(Thread.currentThread().getName() + " <><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("bagna".equals(genGoal)) {
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
// usunięcie powtórzenia węzła z łamanej definiującej obszar
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.nodes.remove(way.nodes.size() - 1);
|
||||||
|
}
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(true);
|
||||||
|
way.writeAreaFeatureIntoSquares(EAreaFeature.SWAMP, false);
|
||||||
|
synchronized (synch) {
|
||||||
|
LOGGER.debug(Thread.currentThread().getName() + " <><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("zabudowa".equals(genGoal)) {
|
||||||
|
// wygenerowanie danych o stopniu zabudowy na podstawie danych adresowych
|
||||||
|
// HashMap<Node, Node> newNodesMap = new HashMap<>();
|
||||||
|
// for (Node node : buildingNodesMap.values()) {
|
||||||
|
// Node node1 = newNodesMap.get(node);
|
||||||
|
// if (node1 != null) {
|
||||||
|
// node1.buildingsCount += node.buildingsCount;
|
||||||
|
// } else {
|
||||||
|
// newNodesMap.put(node, node);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// buildingNodesMap.clear();
|
||||||
|
|
||||||
|
for (Node node : buildingNodesMap.values()) {
|
||||||
|
node.writeAreaFeatureIntoSquare(EAreaFeature.BUILDINGS);
|
||||||
|
}
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
// usunięcie powtórzenia węzła z łamanej definiującej obszar
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.nodes.remove(way.nodes.size() - 1);
|
||||||
|
}
|
||||||
|
// for (int i = 0; i < way.nodes.size(); i++) {
|
||||||
|
// Node node = way.nodes.get(i);
|
||||||
|
// if (node.idX <= 0 || node.idY <= 0) {
|
||||||
|
// logger.debug("!!!! niepoprawny wezel id= " + node.id + ", lamana id= " + way.id);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(true);
|
||||||
|
way.writeAreaFeatureIntoSquares(EAreaFeature.BUILDINGS, false);
|
||||||
|
synchronized (synch) {
|
||||||
|
LOGGER.debug(Thread.currentThread().getName() + " <><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("drogi".equals(genGoal)) {
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
// if ("249908111".equals(way.id) || "238353558".equals(way.id)) {
|
||||||
|
// logger.debug("!!!!!");
|
||||||
|
// }
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(false);
|
||||||
|
way.removeSteps();
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.writeLinearFeatureIntoSquares(ELinearFeature.ROAD);
|
||||||
|
}
|
||||||
|
// if (count % 10000 == 0) {
|
||||||
|
// logger.debug("-*-*-*-*-");
|
||||||
|
// logger.debug("maxMemory=" + java.lang.Runtime.getRuntime().maxMemory()
|
||||||
|
// + ", totalMemory=" + java.lang.Runtime.getRuntime().totalMemory()
|
||||||
|
// + ", freeMemory=" + java.lang.Runtime.getRuntime().freeMemory());
|
||||||
|
// }
|
||||||
|
// count++;
|
||||||
|
synchronized (synch) {
|
||||||
|
LOGGER.debug(Thread.currentThread().getName() + " <><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("rzeki".equals(genGoal)) {
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(false);
|
||||||
|
way.removeSteps();
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.writeLinearFeatureIntoSquares(ELinearFeature.WATER_WAY);
|
||||||
|
}
|
||||||
|
synchronized (synch) {
|
||||||
|
LOGGER.debug(Thread.currentThread().getName() + " <><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("rowy".equals(genGoal)) {
|
||||||
|
for (Way way : wayList) {
|
||||||
|
count++;
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
way.removeCollinearNodes(false);
|
||||||
|
way.removeSteps();
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.writeLinearFeatureIntoSquares(ELinearFeature.DITCH);
|
||||||
|
}
|
||||||
|
synchronized (synch) {
|
||||||
|
LOGGER.debug(Thread.currentThread().getName() + " <><><><><><>: way count= " + count + ", " + genGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Współrzędne punktu odwzorowania kartograficznego PUWG 1992 lub 2000.
|
||||||
|
* <p>
|
||||||
|
* Wartośći współrzędnych [metry].
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PUWGCoord {
|
||||||
|
/**
|
||||||
|
* Współrzędna X (oś odcietych) odwzorowania kartograficznego [metry].
|
||||||
|
*/
|
||||||
|
public double easting;
|
||||||
|
/**
|
||||||
|
* Współrzędna Y (oś rzędnych) odwzorowania kartograficznego [metry].
|
||||||
|
*/
|
||||||
|
public double northing;
|
||||||
|
/**
|
||||||
|
* proj = 1 odpowiada odwzorowaniu 1992, natomiast każda inna odwzorowaniu 2000
|
||||||
|
*/
|
||||||
|
public int proj;
|
||||||
|
|
||||||
|
public PUWGCoord() {
|
||||||
|
this.easting = 0;
|
||||||
|
this.northing = 0;
|
||||||
|
// PUWG 1992
|
||||||
|
this.proj = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PUWGCoord(double easting, double northing, int proj) {
|
||||||
|
this.easting = easting;
|
||||||
|
this.northing = northing;
|
||||||
|
this.proj = proj;
|
||||||
|
}
|
||||||
|
}
|
||||||
204
src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Relation.java
Normal file
204
src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Relation.java
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bazowa klasa dla obiektów OpenStreetMap.
|
||||||
|
*/
|
||||||
|
public class Relation {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(Relation.class);
|
||||||
|
|
||||||
|
public String id;
|
||||||
|
/**
|
||||||
|
* Tag oznacza obiekt obszarowy. <p>
|
||||||
|
* k="natural" - v="water" | v="reservoir" | v="wetland" | v="wood"
|
||||||
|
*/
|
||||||
|
public EOSMNatural natural;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag ten oznacza rzekę lub ciek wodny opisywany liniowo.
|
||||||
|
* <p> Wyjątek: waterway=riverbank, który opisuje obszar.
|
||||||
|
* <p> k="waterway" - v="river" | v="riverbank" | v="stream" | v="canal" | v="drain" | v="ditch"
|
||||||
|
*/
|
||||||
|
public EOSMWaterway waterway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag stosowany w połączeniu z tagiem obszarowym: natural=water. <p>
|
||||||
|
* k="water" - v="lake" | v="reservoir" | v="river" | v="canal" | v="cove" | v="lagoon" | v="pond"
|
||||||
|
*/
|
||||||
|
public EOSMWater water;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag oznacza obiekt obszarowy. <p>
|
||||||
|
* k="landuse" - v="forest" | v="residential" | v="commercial"
|
||||||
|
*/
|
||||||
|
public EOSMLanduse landuse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag oznacza obiekt obszarowy. <p>
|
||||||
|
* k="landcover" - v="trees" | v="water" | v="grass"
|
||||||
|
*/
|
||||||
|
public EOSMLandcover landcover;
|
||||||
|
|
||||||
|
ArrayList<Way> outerWays = new ArrayList<Way>();
|
||||||
|
ArrayList<Way> innerWays = new ArrayList<Way>();
|
||||||
|
|
||||||
|
public Relation(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Relation(Relation oryg) {
|
||||||
|
this.id = oryg.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyTags(Relation oryg) {
|
||||||
|
this.id = oryg.id;
|
||||||
|
this.natural = oryg.natural;
|
||||||
|
this.waterway = oryg.waterway;
|
||||||
|
this.water = oryg.water;
|
||||||
|
this.landuse = oryg.landuse;
|
||||||
|
this.landcover = oryg.landcover;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<Way> generatePolygons(ArrayList<Way> wayList) {
|
||||||
|
ArrayList<Way> polygons = new ArrayList<Way>();
|
||||||
|
Way newPolygon = new Way((String)null);
|
||||||
|
int prevLast = -1;
|
||||||
|
for (int iWay = 0; iWay < wayList.size(); iWay++) {
|
||||||
|
Way testWay = wayList.get(iWay);
|
||||||
|
if (testWay.nodes.size() < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int currLast = testWay.nodes.size() - 1;
|
||||||
|
Node currFirstNode = testWay.nodes.get(0);
|
||||||
|
Node currLastNode = testWay.nodes.get(currLast);
|
||||||
|
if (prevLast < 0) {
|
||||||
|
// biezacy wielokat jeszcze nie zawiera wezlow
|
||||||
|
// newPolygon = new Way((String)null);
|
||||||
|
newPolygon.nodes = testWay.nodes;
|
||||||
|
newPolygon.copyTags(testWay);
|
||||||
|
if (currFirstNode == currLastNode) {
|
||||||
|
// lamana jest wielokatem
|
||||||
|
polygons.add(newPolygon);
|
||||||
|
prevLast = -1;
|
||||||
|
newPolygon = new Way((String)null);
|
||||||
|
} else {
|
||||||
|
prevLast = newPolygon.nodes.size() - 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (currFirstNode == currLastNode) {
|
||||||
|
// !! Blad w danych - brak ciaglosci lamanych: poprzedni wielokat sie nie zamknal
|
||||||
|
// lamana jest wielokatem,
|
||||||
|
// newPolygon = new Way((String)null);
|
||||||
|
newPolygon.nodes = testWay.nodes;
|
||||||
|
newPolygon.copyTags(testWay);
|
||||||
|
polygons.add(newPolygon);
|
||||||
|
prevLast = -1;
|
||||||
|
newPolygon = new Way((String)null);
|
||||||
|
} else {
|
||||||
|
// biezacy wielokat zawiera juz wezly
|
||||||
|
Node prevFirstNode = newPolygon.nodes.get(0);
|
||||||
|
Node prevLastNode = newPolygon.nodes.get(prevLast);
|
||||||
|
if (currFirstNode == prevLastNode) {
|
||||||
|
for (int jNode = 1; jNode < testWay.nodes.size(); jNode++) {
|
||||||
|
newPolygon.nodes.add(testWay.nodes.get(jNode));
|
||||||
|
}
|
||||||
|
if (currLastNode == prevFirstNode) {
|
||||||
|
// lamana zamyka wielokat
|
||||||
|
polygons.add(newPolygon);
|
||||||
|
prevLast = -1;
|
||||||
|
newPolygon = new Way((String)null);
|
||||||
|
} else {
|
||||||
|
// lamana nie zamyka jeszcze wielokata
|
||||||
|
prevLast = newPolygon.nodes.size() - 1;
|
||||||
|
}
|
||||||
|
} else if (currLastNode == prevFirstNode) {
|
||||||
|
// odwracam kolejnosc dodawanych wezlow z biezacej lamanej
|
||||||
|
for (int jNode = 1; jNode < newPolygon.nodes.size(); jNode++) {
|
||||||
|
testWay.nodes.add(newPolygon.nodes.get(jNode));
|
||||||
|
}
|
||||||
|
newPolygon.nodes = testWay.nodes;
|
||||||
|
// for (int jNode = currLast - 1; jNode >= 0; jNode--) {
|
||||||
|
// newPolygon.nodes.add(testWay.nodes.get(jNode));
|
||||||
|
// }
|
||||||
|
if (currFirstNode == prevLastNode) {
|
||||||
|
// lamana zamyka wielokat
|
||||||
|
polygons.add(newPolygon);
|
||||||
|
prevLast = -1;
|
||||||
|
newPolygon = new Way((String)null);
|
||||||
|
} else {
|
||||||
|
// lamana nie zamyka jeszcze wielokata
|
||||||
|
prevLast = newPolygon.nodes.size() - 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// !! Blad w danych - brak ciaglosci lamanych: poprzedni wielokat sie nie zamknal
|
||||||
|
// lamana nowego obszaru
|
||||||
|
// newPolygon = new Way((String)null);
|
||||||
|
newPolygon.nodes = testWay.nodes;
|
||||||
|
newPolygon.copyTags(testWay);
|
||||||
|
prevLast = newPolygon.nodes.size() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return polygons;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeAreaFeatureIntoSquares(EAreaFeature type) {
|
||||||
|
for (Way way : outerWays) {
|
||||||
|
// wpisanie w kwadraty danej cechy dla wielokatow opisujacych zewnetrzna powloke obszaru
|
||||||
|
way.writeAreaFeatureIntoSquares(type, false);
|
||||||
|
}
|
||||||
|
for (Way way : innerWays) {
|
||||||
|
// wykreslenie z kwadratow danej cechy dla wielokatow opisujacych wewnetrzne podobszary
|
||||||
|
way.writeAreaFeatureIntoSquares(type, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeSimilarNodes() {
|
||||||
|
for (Way way : outerWays) {
|
||||||
|
// wpisanie w kwadraty danej cechy dla wielokatow opisujacych zewnetrzna powloke obszaru
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
}
|
||||||
|
for (Way way : innerWays) {
|
||||||
|
// wykreslenie z kwadratow danej cechy dla wielokatow opisujacych wewnetrzne podobszary
|
||||||
|
way.removeSimilarNodes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeCollinearNodes(boolean isPolygon) {
|
||||||
|
for (Way way : outerWays) {
|
||||||
|
// wpisanie w kwadraty danej cechy dla wielokatow opisujacych zewnetrzna powloke obszaru
|
||||||
|
way.removeCollinearNodes(isPolygon);
|
||||||
|
}
|
||||||
|
for (Way way : innerWays) {
|
||||||
|
// wykreslenie z kwadratow danej cechy dla wielokatow opisujacych wewnetrzne podobszary
|
||||||
|
way.removeCollinearNodes(isPolygon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeLastNodes() {
|
||||||
|
for (Way way : outerWays) {
|
||||||
|
// usunięcie powtórzenia węzła z wielokata definiującego obszar
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.nodes.remove(way.nodes.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Way way : innerWays) {
|
||||||
|
// usunięcie powtórzenia węzła z wielokata definiującego obszar
|
||||||
|
if (way.nodes.size() > 1) {
|
||||||
|
way.nodes.remove(way.nodes.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Relation{id=" + id +
|
||||||
|
", outerWays.len=" + outerWays.size() +
|
||||||
|
", innerWays.len=" + innerWays.size() +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Współrzędna w układzie UTM. <p>
|
||||||
|
* Przykład: 17T 630084 4833438,
|
||||||
|
* gdzie: xZone = 17, yZone = T, easting = 630084, northing = 4833438
|
||||||
|
* <p>
|
||||||
|
* xZone - nr strefy UTM wg. podziału południkowego (zwracane numery od 1 do 60, każda strefa ma sześć stopni);
|
||||||
|
* <p>
|
||||||
|
* yZone - nr strefy wg. podziału równoleżnikowego (zwracane wartości: CDEFGHJKLMNPQRSTUVWX).
|
||||||
|
* <p>
|
||||||
|
* easting - odległość w kierunku wschodnim od początku układu współrzędnych w danej strefie UTM [metr].
|
||||||
|
* <p>
|
||||||
|
* northing - odległość w kierunku północnym od początku układu współrzędnych w danej strefie UTM [metr].
|
||||||
|
*/
|
||||||
|
public class UTMCoord {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nr strefy UTM wg. podziału południkowego (zwracane numery od 1 do 60, każda strefa ma sześć stopni).
|
||||||
|
*/
|
||||||
|
public int xZone;
|
||||||
|
/**
|
||||||
|
* Nr strefy wg. podziału równoleżnikowego (zwracane wartości: CDEFGHJKLMNPQRSTUVWX).
|
||||||
|
*/
|
||||||
|
public char yZone;
|
||||||
|
/**
|
||||||
|
* Odległość w kierunku wschodnim od początku układu współrzędnych w danej strefie UTM [metr].
|
||||||
|
*/
|
||||||
|
public double easting;
|
||||||
|
/**
|
||||||
|
* Odległość w kierunku północnym od początku układu współrzędnych w danej strefie UTM [metr].
|
||||||
|
*/
|
||||||
|
public double northing;
|
||||||
|
}
|
||||||
603
src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Way.java
Normal file
603
src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Way.java
Normal file
@@ -0,0 +1,603 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
import pl.wat.ms4ds.common.EGeoDirection;
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.*;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bazowa klasa dla obiektów OpenStreetMap.
|
||||||
|
*/
|
||||||
|
public class Way {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(Way.class);
|
||||||
|
|
||||||
|
public String id;
|
||||||
|
|
||||||
|
ArrayList<Node> nodes = new ArrayList<Node>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* k="highway" - v="motorway" | v="trunk" | v="primary" | v="secondary" | v="tertiary" | v="unclassified"
|
||||||
|
* | v="residential" | v="pedestrian" | v="track"
|
||||||
|
* | v="motorway_link" | v="trunk_link" | v="primary_link" | v="secondary_link" | v="tertiary_link"
|
||||||
|
*/
|
||||||
|
public EOSMHighway highway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag oznacza obiekt obszarowy. <p>
|
||||||
|
* k="natural" - v="water" | v="reservoir" | v="wetland" | v="wood"
|
||||||
|
*/
|
||||||
|
public EOSMNatural natural;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag ten oznacza rzekę lub ciek wodny opisywany liniowo.
|
||||||
|
* <p> Wyjątek: waterway=riverbank, który opisuje obszar.
|
||||||
|
* <p> k="waterway" - v="river" | v="riverbank" | v="stream" | v="canal" | v="drain" | v="ditch"
|
||||||
|
*/
|
||||||
|
public EOSMWaterway waterway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag stosowany w połączeniu z tagiem obszarowym: natural=water. <p>
|
||||||
|
* k="water" - v="lake" | v="reservoir" | v="river" | v="canal" | v="cove" | v="lagoon" | v="pond"
|
||||||
|
*/
|
||||||
|
public EOSMWater water;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag oznacza obiekt obszarowy. <p>
|
||||||
|
* k="landuse" - v="forest" | v="residential" | v="commercial"
|
||||||
|
*/
|
||||||
|
public EOSMLanduse landuse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* k="amenity" - v="hospital" | v="school" | v="post_office" | v="police" | v="marketplace" | v="fire_station" |
|
||||||
|
* v="theatre" | v="cinema" | v="pharmacy" | v="nursing_home" | v="bank" | v="fuel"
|
||||||
|
* v="university" | v="library"
|
||||||
|
*/
|
||||||
|
public EOSMAmenity amenity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* k="building" - v="yes" | v="chapel" | v="church" | v="house" | v="office" | v="manufacture" | v="industrial"
|
||||||
|
*/
|
||||||
|
public EOSMBuilding building;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* k="bridge" - v="yes" | "viaduct"
|
||||||
|
*/
|
||||||
|
public EOSMBridge bridge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag oznacza obiekt obszarowy. <p>
|
||||||
|
* k="landcover" - v="trees" | v="water" | v="grass"
|
||||||
|
*/
|
||||||
|
public EOSMLandcover landcover;
|
||||||
|
|
||||||
|
public Way(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Way(Way oryg) {
|
||||||
|
this.id = oryg.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyTags(Way oryg) {
|
||||||
|
this.highway = oryg.highway;
|
||||||
|
this.natural = oryg.natural;
|
||||||
|
this.waterway = oryg.waterway;
|
||||||
|
this.water = oryg.water;
|
||||||
|
this.landuse = oryg.landuse;
|
||||||
|
this.amenity = oryg.amenity;
|
||||||
|
this.building = oryg.building;
|
||||||
|
this.bridge = oryg.bridge;
|
||||||
|
this.landcover = oryg.landcover;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyTags(Relation oryg) {
|
||||||
|
this.natural = oryg.natural;
|
||||||
|
this.waterway = oryg.waterway;
|
||||||
|
this.water = oryg.water;
|
||||||
|
this.landuse = oryg.landuse;
|
||||||
|
this.landcover = oryg.landcover;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean tagged() {
|
||||||
|
if (landuse != null || natural != null || landcover != null
|
||||||
|
|| highway != null || waterway != null
|
||||||
|
|| building != null || amenity != null || bridge != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeSimilarNodes() {
|
||||||
|
if (nodes.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Node node_i;
|
||||||
|
Node node_j;
|
||||||
|
Node similarToNode[] = new Node[nodes.size()];
|
||||||
|
boolean similarFound = false;
|
||||||
|
for (int i = 0; i < nodes.size() - 1; i++) {
|
||||||
|
node_i = nodes.get(i);
|
||||||
|
if (similarToNode[i] != null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int j = i + 1; j < nodes.size(); j++) {
|
||||||
|
node_j = nodes.get(j);
|
||||||
|
if (node_i.idX == node_j.idX && node_i.idY == node_j.idY) {
|
||||||
|
similarToNode[j] = node_i;
|
||||||
|
node_i.buildingsCount += node_j.buildingsCount;
|
||||||
|
similarFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (similarFound) {
|
||||||
|
ArrayList<Node> newList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
node_i = nodes.get(i);
|
||||||
|
if (similarToNode[i] == null) {
|
||||||
|
newList.add(node_i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodes = newList;
|
||||||
|
removeSimilarNodes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeCollinearNodes(boolean isPolygon) {
|
||||||
|
if (nodes.size() < 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean toDelete[] = new boolean[nodes.size()];
|
||||||
|
Node node_i;
|
||||||
|
Node node_i_next;
|
||||||
|
Node node_i_prev;
|
||||||
|
boolean collinearFound = false;
|
||||||
|
int dlMax = nodes.size();
|
||||||
|
int iStart = 0;
|
||||||
|
if (!isPolygon) {
|
||||||
|
// łamana otwarta
|
||||||
|
dlMax = nodes.size() - 1;
|
||||||
|
iStart = 1;
|
||||||
|
}
|
||||||
|
for (int i = iStart; i < dlMax; i++) {
|
||||||
|
int i_plus_1 = (i + 1) % nodes.size();
|
||||||
|
int i_minus_1 = (i + nodes.size() - 1) % nodes.size();
|
||||||
|
node_i = nodes.get(i);
|
||||||
|
node_i_next = nodes.get(i_plus_1);
|
||||||
|
node_i_prev = nodes.get(i_minus_1);
|
||||||
|
if (GeomUtils.include(node_i_prev.idX, node_i_prev.idY, node_i_next.idX, node_i_next.idY,
|
||||||
|
node_i.idX, node_i.idY)) {
|
||||||
|
// i-ty do usuniecia
|
||||||
|
toDelete[i] = true;
|
||||||
|
collinearFound = true;
|
||||||
|
} else if (GeomUtils.include(node_i.idX, node_i.idY, node_i_next.idX, node_i_next.idY,
|
||||||
|
node_i_prev.idX, node_i_prev.idY)) {
|
||||||
|
// i-1-ty do usuniecia
|
||||||
|
toDelete[i_minus_1] = true;
|
||||||
|
collinearFound = true;
|
||||||
|
} else if (GeomUtils.include(node_i_prev.idX, node_i_prev.idY, node_i.idX, node_i.idY,
|
||||||
|
node_i_next.idX, node_i_next.idY)) {
|
||||||
|
// i+1-ty do usuniecia
|
||||||
|
toDelete[i_plus_1] = true;
|
||||||
|
collinearFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (collinearFound) {
|
||||||
|
ArrayList<Node> newList = new ArrayList<Node>();
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
node_i = nodes.get(i);
|
||||||
|
if (!toDelete[i]) {
|
||||||
|
newList.add(node_i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// logger.trace("Liczba oryg. wezlow= {}, liczba niewspolliniowych wezlow= {}, roznica= {}", nodes.size(), newList.size(), nodes.size() - newList.size());
|
||||||
|
nodes = newList;
|
||||||
|
removeCollinearNodes(isPolygon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeSteps() {
|
||||||
|
if (nodes.size() < 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean toDelete[] = new boolean[nodes.size()];
|
||||||
|
Node node_i;
|
||||||
|
Node node_j;
|
||||||
|
Node node_k;
|
||||||
|
boolean bylSchodek = false;
|
||||||
|
for (int i = 0; i < nodes.size() - 2; i++) {
|
||||||
|
node_i = nodes.get(i);
|
||||||
|
node_j = nodes.get(i + 1);
|
||||||
|
node_k = nodes.get(i + 2);
|
||||||
|
int absX_i_j = Math.abs(node_j.idX - node_i.idX);
|
||||||
|
int absY_i_j = Math.abs(node_j.idY - node_i.idY);
|
||||||
|
int absX_j_k = Math.abs(node_k.idX - node_j.idX);
|
||||||
|
int absY_j_k = Math.abs(node_k.idY - node_j.idY);
|
||||||
|
if (absX_i_j + absY_i_j + absX_j_k + absY_j_k == 2) {
|
||||||
|
// wezly moga tworzyc schodek
|
||||||
|
if (absX_i_j + absX_j_k == 1) {
|
||||||
|
// wezly tworza schodek, zatem srodkowy wezel schodka do usuniecia
|
||||||
|
toDelete[i + 1] = true;
|
||||||
|
bylSchodek = true;
|
||||||
|
// przeskok o usuwany wezel
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bylSchodek) {
|
||||||
|
ArrayList<Node> newList = new ArrayList<Node>();
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
if (!toDelete[i]) {
|
||||||
|
newList.add(nodes.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nodes.size() > newList.size()) {
|
||||||
|
// logger.trace("Liczba oryg. wezlow= {}, liczba roznych wezlow= {}, roznica= {}", nodes.size(), newList.size(), nodes.size() - newList.size());
|
||||||
|
}
|
||||||
|
nodes = newList;
|
||||||
|
removeSteps();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeLinearFeatureIntoSquares(ELinearFeature type) {
|
||||||
|
if (nodes.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GridCoord[] punktyLamanej = new GridCoord[nodes.size()];
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
punktyLamanej[i] = new GridCoord(nodes.get(i).idX, nodes.get(i).idY);
|
||||||
|
}
|
||||||
|
Kwadrat kw0;
|
||||||
|
Kwadrat kw1;
|
||||||
|
GridCoord id0;
|
||||||
|
GridCoord id1;
|
||||||
|
EGeoDirection kier;
|
||||||
|
GridCoord[] kwadraty = GeomUtils.kwadratyLamanej2(punktyLamanej);
|
||||||
|
// float dlug = GeomUtils.dlugoscDrogiPoKwadratch(kwadraty);
|
||||||
|
for (int i = 0; i < kwadraty.length - 1; i++) {
|
||||||
|
try {
|
||||||
|
id0 = kwadraty[i];
|
||||||
|
kw0 = Teren.getKwadrat(id0.x, id0.y);
|
||||||
|
id1 = kwadraty[i + 1];
|
||||||
|
kw1 = Teren.getKwadrat(id1.x, id1.y);
|
||||||
|
kier = GeomUtils.kierunekDlaSasiada(id0, id1);
|
||||||
|
switch (type) {
|
||||||
|
case ROAD:
|
||||||
|
kw0.setJestDroga(kier, true);
|
||||||
|
kw1.setJestDroga(kier.oppositeDirect(), true);
|
||||||
|
break;
|
||||||
|
case WATER_WAY:
|
||||||
|
kw0.setJestPrzeszkodaWodna(kier, true);
|
||||||
|
kw1.setJestPrzeszkodaWodna(kier.oppositeDirect(), true);
|
||||||
|
break;
|
||||||
|
case DITCH:
|
||||||
|
kw0.setJestRow(kier, true);
|
||||||
|
kw1.setJestRow(kier.oppositeDirect(), true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warn(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeAreaFeatureIntoSquares2(EAreaFeature type, boolean clearFeature, GridCoord[] polygon) {
|
||||||
|
if (polygon.length > 20) {
|
||||||
|
// podział wielokata na dwa mniejsze
|
||||||
|
int m = 2;
|
||||||
|
GridCoord pocz = polygon[0];
|
||||||
|
boolean poprawnyPodzial = false;
|
||||||
|
while (m < polygon.length - 1 && !poprawnyPodzial) {
|
||||||
|
// sprawdzenie, czy punkty wielokata po podziale sa po jednej stronie wektora podzialu
|
||||||
|
poprawnyPodzial = true;
|
||||||
|
GridCoord kon = polygon[m];
|
||||||
|
for (int i = 0; i < polygon.length; i++) {
|
||||||
|
int i_puls_1 = (i + 1) % polygon.length;
|
||||||
|
boolean przeciecie = GeomUtils.intersection(pocz, kon, polygon[i], polygon[i_puls_1]);
|
||||||
|
if (przeciecie) {
|
||||||
|
// sprawdzenie, czy jakiś koniec jednego odcinka jest równy końcowi drugiego odcinka
|
||||||
|
boolean b = pocz.rowne(polygon[i].x, polygon[i].y) ||
|
||||||
|
pocz.rowne(polygon[i_puls_1].x, polygon[i_puls_1].y) ||
|
||||||
|
kon.rowne(polygon[i].x, polygon[i].y) ||
|
||||||
|
kon.rowne(polygon[i_puls_1].x, polygon[i_puls_1].y);
|
||||||
|
if (!b) {
|
||||||
|
poprawnyPodzial = false;
|
||||||
|
m++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (poprawnyPodzial) {
|
||||||
|
// punkt podziału wielokąta jest poprawny, zatem dzielę wielokąt na dwa
|
||||||
|
GridCoord[] polygon1 = new GridCoord[m + 1];
|
||||||
|
for (int i = 0; i < polygon1.length; i++) {
|
||||||
|
polygon1[i] = polygon[i];
|
||||||
|
}
|
||||||
|
writeAreaFeatureIntoSquares2(type, clearFeature, polygon1);
|
||||||
|
|
||||||
|
GridCoord[] polygon2 = new GridCoord[polygon.length - m + 1];
|
||||||
|
polygon2[0] = polygon[0];
|
||||||
|
for (int i = m; i < polygon.length; i++) {
|
||||||
|
polygon2[i - m + 1] = polygon[i];
|
||||||
|
}
|
||||||
|
writeAreaFeatureIntoSquares2(type, clearFeature, polygon2);
|
||||||
|
} else {
|
||||||
|
// nie udało się poprawnie podzielić wielokąta, zatem przesuwam wierzchołki, aby zmienić wierzchołek
|
||||||
|
// startowy, który jest wierchołkiem referencyjnym podziału (drugi wierzchołek podziału jest szukany)
|
||||||
|
GridCoord temp = polygon[0];
|
||||||
|
for (int i = 0; i < polygon.length - 1; i++) {
|
||||||
|
polygon[i] = polygon[i + 1];
|
||||||
|
}
|
||||||
|
polygon[polygon.length - 1] = temp;
|
||||||
|
writeAreaFeatureIntoSquares2(type, clearFeature, polygon);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float val = (clearFeature) ? 0.0f : 1.0f;
|
||||||
|
int minX = polygon[0].x;
|
||||||
|
int minY = polygon[0].y;
|
||||||
|
int maxX = polygon[0].x;
|
||||||
|
int maxY = polygon[0].y;
|
||||||
|
for (int i = 1; i < polygon.length; i++) {
|
||||||
|
minX = (polygon[i].x < minX) ? polygon[i].x : minX;
|
||||||
|
minY = (polygon[i].y < minY) ? polygon[i].y : minY;
|
||||||
|
maxX = (polygon[i].x > maxX) ? polygon[i].x : maxX;
|
||||||
|
maxY = (polygon[i].y > maxY) ? polygon[i].y : maxY;
|
||||||
|
}
|
||||||
|
GridCoord idTest = new GridCoord();
|
||||||
|
boolean inside;
|
||||||
|
for (int j = maxY; j >= minY; j--) {
|
||||||
|
for (int i = minX; i <= maxX; i++) {
|
||||||
|
idTest.x = i;
|
||||||
|
idTest.y = j;
|
||||||
|
Kwadrat kw = Teren.getKwadrat(idTest.x, idTest.y);
|
||||||
|
if (kw == Kwadrat.EMPTY_SQUARE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
inside = GeomUtils.insidePolygon(polygon, idTest);
|
||||||
|
if (inside) {
|
||||||
|
switch (type) {
|
||||||
|
case FOREST:
|
||||||
|
kw.setStopienZalesienia(val);
|
||||||
|
break;
|
||||||
|
case WATER:
|
||||||
|
kw.setStopienZawodnienia(val);
|
||||||
|
break;
|
||||||
|
case SWAMP:
|
||||||
|
kw.setStopienZabagnienia(val);
|
||||||
|
break;
|
||||||
|
case BUILDINGS:
|
||||||
|
kw.setStopienZabudowy(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeAreaFeatureIntoSquares(EAreaFeature type, boolean clearFeature, GridCoord[] polygon,
|
||||||
|
int minX,int maxX, int minY, int maxY) {
|
||||||
|
float val = (clearFeature) ? 0.0f : 1.0f;
|
||||||
|
GridCoord idTest = new GridCoord();
|
||||||
|
boolean inside;
|
||||||
|
for (int i = minX; i <= maxX; i++) {
|
||||||
|
for (int j = minY; j <= maxY; j++) {
|
||||||
|
idTest.x = i;
|
||||||
|
idTest.y = j;
|
||||||
|
Kwadrat kw = Teren.getKwadrat(idTest.x, idTest.y);
|
||||||
|
if (kw == Kwadrat.EMPTY_SQUARE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
inside = GeomUtils.insidePolygon(polygon, idTest);
|
||||||
|
if (inside) {
|
||||||
|
switch (type) {
|
||||||
|
case FOREST:
|
||||||
|
kw.setStopienZalesienia(val);
|
||||||
|
break;
|
||||||
|
case WATER:
|
||||||
|
kw.setStopienZawodnienia(val);
|
||||||
|
break;
|
||||||
|
case SWAMP:
|
||||||
|
kw.setStopienZabagnienia(val);
|
||||||
|
break;
|
||||||
|
case BUILDINGS:
|
||||||
|
kw.setStopienZabudowy(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeAreaFeatureIntoSquares2(EAreaFeature type, boolean clearFeature) {
|
||||||
|
if (nodes.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Kwadrat kw;
|
||||||
|
float val = (clearFeature) ? 0.0f : 1.0f;
|
||||||
|
if (nodes.size() == 1) {
|
||||||
|
kw = Teren.getKwadrat(nodes.get(0).idX, nodes.get(0).idY);
|
||||||
|
switch (type) {
|
||||||
|
case FOREST:
|
||||||
|
kw.setStopienZalesienia(val);
|
||||||
|
break;
|
||||||
|
case WATER:
|
||||||
|
kw.setStopienZawodnienia(val);
|
||||||
|
break;
|
||||||
|
case SWAMP:
|
||||||
|
kw.setStopienZabagnienia(val);
|
||||||
|
break;
|
||||||
|
case BUILDINGS:
|
||||||
|
kw.setStopienZabudowy(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (nodes.size() == 2) {
|
||||||
|
GridCoord[] kwadraty = GeomUtils.kwadratyOdcinka(nodes.get(0).idX, nodes.get(0).idY,
|
||||||
|
nodes.get(1).idX, nodes.get(1).idY);
|
||||||
|
for (int i = 0; i < kwadraty.length; i++) {
|
||||||
|
kw = Teren.getKwadrat(kwadraty[i].x, kwadraty[i].y);
|
||||||
|
switch (type) {
|
||||||
|
case FOREST:
|
||||||
|
kw.setStopienZalesienia(val);
|
||||||
|
break;
|
||||||
|
case WATER:
|
||||||
|
kw.setStopienZawodnienia(val);
|
||||||
|
break;
|
||||||
|
case SWAMP:
|
||||||
|
kw.setStopienZabagnienia(val);
|
||||||
|
break;
|
||||||
|
case BUILDINGS:
|
||||||
|
kw.setStopienZabudowy(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GridCoord[] wielokat = new GridCoord[nodes.size()];
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
wielokat[i] = new GridCoord(nodes.get(i).idX, nodes.get(i).idY);
|
||||||
|
}
|
||||||
|
writeAreaFeatureIntoSquares2(type, clearFeature, wielokat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeAreaFeatureIntoSquares(EAreaFeature type, boolean clearFeature) {
|
||||||
|
if (nodes.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Kwadrat kw;
|
||||||
|
float val = (clearFeature) ? 0.0f : 1.0f;
|
||||||
|
if (nodes.size() == 1) {
|
||||||
|
kw = Teren.getKwadrat(nodes.get(0).idX, nodes.get(0).idY);
|
||||||
|
switch (type) {
|
||||||
|
case FOREST:
|
||||||
|
kw.setStopienZalesienia(val);
|
||||||
|
break;
|
||||||
|
case WATER:
|
||||||
|
kw.setStopienZawodnienia(val);
|
||||||
|
break;
|
||||||
|
case SWAMP:
|
||||||
|
kw.setStopienZabagnienia(val);
|
||||||
|
break;
|
||||||
|
case BUILDINGS:
|
||||||
|
kw.setStopienZabudowy(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (nodes.size() == 2) {
|
||||||
|
GridCoord[] kwadraty = GeomUtils.kwadratyOdcinka(nodes.get(0).idX, nodes.get(0).idY,
|
||||||
|
nodes.get(1).idX, nodes.get(1).idY);
|
||||||
|
for (int i = 0; i < kwadraty.length; i++) {
|
||||||
|
kw = Teren.getKwadrat(kwadraty[i].x, kwadraty[i].y);
|
||||||
|
switch (type) {
|
||||||
|
case FOREST:
|
||||||
|
kw.setStopienZalesienia(val);
|
||||||
|
break;
|
||||||
|
case WATER:
|
||||||
|
kw.setStopienZawodnienia(val);
|
||||||
|
break;
|
||||||
|
case SWAMP:
|
||||||
|
kw.setStopienZabagnienia(val);
|
||||||
|
break;
|
||||||
|
case BUILDINGS:
|
||||||
|
kw.setStopienZabudowy(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GridCoord[] wielokat = new GridCoord[nodes.size()];
|
||||||
|
int minX = nodes.get(0).idX;
|
||||||
|
int minY = nodes.get(0).idY;
|
||||||
|
int maxX = nodes.get(0).idX;
|
||||||
|
int maxY = nodes.get(0).idY;
|
||||||
|
for (int i = 0; i < nodes.size(); i++) {
|
||||||
|
wielokat[i] = new GridCoord(nodes.get(i).idX, nodes.get(i).idY);
|
||||||
|
minX = (wielokat[i].x < minX) ? wielokat[i].x : minX;
|
||||||
|
minY = (wielokat[i].y < minY) ? wielokat[i].y : minY;
|
||||||
|
maxX = (wielokat[i].x > maxX) ? wielokat[i].x : maxX;
|
||||||
|
maxY = (wielokat[i].y > maxY) ? wielokat[i].y : maxY;
|
||||||
|
}
|
||||||
|
int ileKwTest = (maxX - minX) * (maxY - minY);
|
||||||
|
if (ileKwTest > 100000) {
|
||||||
|
int dx = maxX - minX;
|
||||||
|
int dy = maxY - minY;
|
||||||
|
Worker[] workers = new Worker[4];
|
||||||
|
workers[0] = new Worker(type, clearFeature, wielokat, minX, minX + dx / 2, minY, minY + dy / 2);
|
||||||
|
workers[1] = new Worker(type, clearFeature, wielokat, minX + dx / 2 + 1, maxX, minY, minY + dy / 2);
|
||||||
|
workers[2] = new Worker(type, clearFeature, wielokat, minX, minX + dx / 2, minY + dy / 2 + 1, maxY);
|
||||||
|
workers[3] = new Worker(type, clearFeature, wielokat, minX + dx / 2 + 1, maxX, minY + dy / 2 + 1, maxY);
|
||||||
|
for (int i = 0; i < workers.length; i++) {
|
||||||
|
workers[i].start();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GridCoord idTest = new GridCoord();
|
||||||
|
boolean nalezyDoWielokata;
|
||||||
|
// int liczKw = 0;
|
||||||
|
// int liczKwObszaru = 0;
|
||||||
|
// for (int j = maxY; j >= minY; j--) {
|
||||||
|
// for (int i = minX; i <= maxX; i++) {
|
||||||
|
for (int i = minX; i <= maxX; i++) {
|
||||||
|
for (int j = minY; j <= maxY; j++) {
|
||||||
|
idTest.x = i;
|
||||||
|
idTest.y = j;
|
||||||
|
// char c = ' ';
|
||||||
|
// liczKw++;
|
||||||
|
kw = Teren.getKwadrat(idTest.x, idTest.y);
|
||||||
|
if (kw == Kwadrat.EMPTY_SQUARE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
nalezyDoWielokata = GeomUtils.insidePolygon(wielokat, idTest);
|
||||||
|
if (nalezyDoWielokata) {
|
||||||
|
// c = 'O';
|
||||||
|
switch (type) {
|
||||||
|
case FOREST:
|
||||||
|
kw.setStopienZalesienia(val);
|
||||||
|
break;
|
||||||
|
case WATER:
|
||||||
|
kw.setStopienZawodnienia(val);
|
||||||
|
break;
|
||||||
|
case SWAMP:
|
||||||
|
kw.setStopienZabagnienia(val);
|
||||||
|
break;
|
||||||
|
case BUILDINGS:
|
||||||
|
kw.setStopienZabudowy(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
// liczKwObszaru++;
|
||||||
|
}
|
||||||
|
// rysowanie wielokata
|
||||||
|
// for (int k = 0; k < wielokat.length; k++) {
|
||||||
|
// if (wielokat[k].equals(idTest)) {
|
||||||
|
// c = 'X';
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// System.out.print(c);
|
||||||
|
// System.out.print(' ');
|
||||||
|
}
|
||||||
|
// System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Way{id=" + id +
|
||||||
|
", len=" + nodes.size() +
|
||||||
|
", nodes=" + nodes +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.konwersja;
|
||||||
|
|
||||||
|
import pl.wat.ms4ds.terenfunkcje.GridCoord;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Worker extends Thread {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(Worker.class);
|
||||||
|
|
||||||
|
static ArrayList<Worker> workers = new ArrayList<>();
|
||||||
|
|
||||||
|
static Integer nr = 0;
|
||||||
|
|
||||||
|
EAreaFeature type;
|
||||||
|
boolean clearFeature;
|
||||||
|
GridCoord[] polygon;
|
||||||
|
int minX;
|
||||||
|
int maxX;
|
||||||
|
int minY;
|
||||||
|
int maxY;
|
||||||
|
|
||||||
|
public Worker(EAreaFeature type, boolean clearFeature, GridCoord[] polygon, int minX, int maxX, int minY, int maxY) {
|
||||||
|
super("Worker_" + nr++);
|
||||||
|
this.type = type;
|
||||||
|
this.clearFeature = clearFeature;
|
||||||
|
this.polygon = polygon;
|
||||||
|
this.minX = minX;
|
||||||
|
this.maxX = maxX;
|
||||||
|
this.minY = minY;
|
||||||
|
this.maxY = maxY;
|
||||||
|
workers.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
int ileKwTest = (maxX - minX) * (maxY - minY);
|
||||||
|
synchronized (OpenStreetMapReader.synch) {
|
||||||
|
logger.debug(Thread.currentThread().getName() + " >>> polygon.lent= " + polygon.length + ", ileKwTest= " + Integer.toString(ileKwTest));
|
||||||
|
}
|
||||||
|
Way.writeAreaFeatureIntoSquares(type, clearFeature, polygon, minX, maxX, minY, maxY);
|
||||||
|
synchronized (OpenStreetMapReader.synch) {
|
||||||
|
logger.debug(Thread.currentThread().getName() + " <<< polygon.lent= " + polygon.length + ", ileKwTest= " + Integer.toString(ileKwTest));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
215
src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTDataProvider.java
Normal file
215
src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTDataProvider.java
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.nmt;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import javax.xml.stream.XMLInputFactory;
|
||||||
|
import javax.xml.stream.XMLStreamConstants;
|
||||||
|
import javax.xml.stream.XMLStreamReader;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
public class NMTDataProvider {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(NMTDataProvider.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
// File dir = new File(System.getProperty("user.home") + "/nmt/gugik_SkorowidzNMT2018.gml");
|
||||||
|
// HashMap<String, String> map = new HashMap<>();
|
||||||
|
// String fn0 = "D:/nmt/gugik_SkorowidzNMT20";
|
||||||
|
// for (int i = 18; i < 26; i++) {
|
||||||
|
// readFileLinksFromGUGiKxml(fn0 + i + ".gml", map);
|
||||||
|
// }
|
||||||
|
// saveLinks("D:/nmt/gugik_links.txt", map);
|
||||||
|
|
||||||
|
// start = 580-730, start=1091-1230
|
||||||
|
//
|
||||||
|
// String dir = "C:/Workspace/nmt/gugik_1m/";
|
||||||
|
// String links_fn = "C:/Workspace/nmt/gugik_links.txt";
|
||||||
|
String dir = args[0];
|
||||||
|
String links_fn = args[1];
|
||||||
|
// int start = Integer.parseInt(args[2]);
|
||||||
|
// int end = Integer.parseInt(args[3]);
|
||||||
|
|
||||||
|
Set<String> files = listFiles("C:/Workspace/nmt/gugik_1m/");
|
||||||
|
|
||||||
|
// downloadFileSet(links_fn, start, end, dir);
|
||||||
|
|
||||||
|
// ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
// executor.execute(() -> {
|
||||||
|
// try {
|
||||||
|
// downloadFileSet(links_fn, 290, 730, dir);
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// throw new RuntimeException(e);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// executor.execute(() -> {
|
||||||
|
// try {
|
||||||
|
// downloadFileSet(links_fn, 779, 1230, dir);
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// throw new RuntimeException(e);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// executor.shutdown();
|
||||||
|
// executor.awaitTermination(25, TimeUnit.MINUTES);
|
||||||
|
LOGGER.info("Koniec");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void saveLinks(String fn, HashMap<String, String> map) throws IOException {
|
||||||
|
BufferedWriter writer = new BufferedWriter(new FileWriter(fn));
|
||||||
|
for (String val : map.values()) {
|
||||||
|
writer.write(val);
|
||||||
|
writer.newLine();
|
||||||
|
}
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void downloadFile2(String urlStr, String dirName) throws IOException {
|
||||||
|
String fn = urlStr.substring(urlStr.lastIndexOf('_') + 1);
|
||||||
|
String path = dirName + fn;
|
||||||
|
// URI uri = URI.create("https://opendata.geoportal.gov.pl/NumDaneWys/NMT/81441/81441_1643337_N-34-125-D-d-3-1.asc");
|
||||||
|
URI uri = URI.create(urlStr);
|
||||||
|
InputStream inputStream = uri.toURL().openStream();
|
||||||
|
ReadableByteChannel readableByteChannel = Channels.newChannel(inputStream);
|
||||||
|
FileOutputStream fos = new FileOutputStream(path);
|
||||||
|
FileChannel fc = fos.getChannel();
|
||||||
|
fc.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
|
||||||
|
fc.close();
|
||||||
|
fos.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<String> listFiles(String dir) {
|
||||||
|
return Stream.of(new File(dir).listFiles())
|
||||||
|
.filter(file -> !file.isDirectory())
|
||||||
|
.map(File::getName)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void downloadFile(String urlStr, String dirName) throws IOException {
|
||||||
|
String fn = urlStr.substring(urlStr.lastIndexOf('_') + 1);
|
||||||
|
String path = dirName + fn;
|
||||||
|
URI uri = URI.create(urlStr);
|
||||||
|
try (InputStream inputStream = uri.toURL().openStream();) {
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(inputStream);
|
||||||
|
FileOutputStream fos;
|
||||||
|
String fext = fn.substring(fn.lastIndexOf('.') + 1);
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int count;
|
||||||
|
if (!fext.equals("zip")) {
|
||||||
|
fos = new FileOutputStream(path + ".zip");
|
||||||
|
ZipOutputStream zipOut = new ZipOutputStream(fos);
|
||||||
|
File fileToZip = new File(path);
|
||||||
|
ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
|
||||||
|
zipOut.putNextEntry(zipEntry);
|
||||||
|
while ((count = bis.read(buffer)) != -1) {
|
||||||
|
zipOut.write(buffer, 0, count);
|
||||||
|
}
|
||||||
|
zipOut.close();
|
||||||
|
bis.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fos = new FileOutputStream(path);
|
||||||
|
while ((count = bis.read(buffer, 0, 1024)) != -1) {
|
||||||
|
fos.write(buffer, 0, count);
|
||||||
|
}
|
||||||
|
fos.close();
|
||||||
|
bis.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void zipFile(String sourceFile) throws IOException {
|
||||||
|
FileOutputStream fos = new FileOutputStream(sourceFile + ".zip");
|
||||||
|
ZipOutputStream zipOut = new ZipOutputStream(fos);
|
||||||
|
|
||||||
|
File fileToZip = new File(sourceFile);
|
||||||
|
FileInputStream fis = new FileInputStream(fileToZip);
|
||||||
|
ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
|
||||||
|
zipOut.putNextEntry(zipEntry);
|
||||||
|
byte[] bytes = new byte[1024];
|
||||||
|
int length;
|
||||||
|
while ((length = fis.read(bytes)) >= 0) {
|
||||||
|
zipOut.write(bytes, 0, length);
|
||||||
|
}
|
||||||
|
zipOut.close();
|
||||||
|
fis.close();
|
||||||
|
fos.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void downloadFileSet(String fn, int start, int end, String dirName) throws IOException {
|
||||||
|
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fn)))) {
|
||||||
|
File dir = new File(dirName);
|
||||||
|
dir.mkdirs();
|
||||||
|
String line;
|
||||||
|
int i = 0;
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
if (i >= start) {
|
||||||
|
if (i >= end) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// LOGGER.debug("Start i={}, addr={}", i, line);
|
||||||
|
try {
|
||||||
|
downloadFile(line, dirName);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.debug("Downloading error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funkcja wykorzystana jednokrotnie w celu integracji w jednym pliku wszystkich linków
|
||||||
|
// do zasobów rozproszonych w wielu plikach.
|
||||||
|
private static void readFileLinksFromGUGiKxml(String fn, HashMap<String, String> map) throws Exception {
|
||||||
|
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||||
|
FileInputStream is = new FileInputStream(fn);
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(is);
|
||||||
|
// XMLStreamReader reader = factory.createXMLStreamReader(ClassLoader.getSystemResourceAsStream(fn));
|
||||||
|
XMLStreamReader reader = factory.createXMLStreamReader(bis);
|
||||||
|
String tagContent;
|
||||||
|
boolean foundLink = false;
|
||||||
|
LOGGER.debug("Poczatek odczytu z pliku: " + fn);
|
||||||
|
while (reader.hasNext()) {
|
||||||
|
int eventType = reader.next();
|
||||||
|
switch (eventType) {
|
||||||
|
case XMLStreamConstants.START_ELEMENT:
|
||||||
|
String str = reader.getLocalName();
|
||||||
|
if ("url_do_pobrania".equals(str)) {
|
||||||
|
foundLink = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XMLStreamConstants.CHARACTERS:
|
||||||
|
if (foundLink) {
|
||||||
|
tagContent = reader.getText().trim();
|
||||||
|
String godlo = tagContent.substring(tagContent.lastIndexOf('_') + 1);
|
||||||
|
godlo = godlo.substring(0, godlo.indexOf('.'));
|
||||||
|
String old = map.remove(godlo);
|
||||||
|
map.put(godlo, tagContent);
|
||||||
|
foundLink = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XMLStreamConstants.END_ELEMENT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
58
src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTReader.java
Normal file
58
src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTReader.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.nmt;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class NMTReader {
|
||||||
|
|
||||||
|
|
||||||
|
static void main(String[] args) {
|
||||||
|
// File dir = new File(System.getProperty("user.home") + "/nmt/gugik_SkorowidzNMT2018.gml");
|
||||||
|
|
||||||
|
InputStream is = null;
|
||||||
|
try {
|
||||||
|
File file = new File("C:/Workspace/nmt/N-34-139-A-b-2-4.asc");
|
||||||
|
is = new FileInputStream(file);
|
||||||
|
readFromInputStream(is);
|
||||||
|
//...
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
if (is != null) {
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readFromInputStream(InputStream inputStream) throws IOException {
|
||||||
|
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||||
|
String line= br.readLine();
|
||||||
|
String[] split = line.split(" ");
|
||||||
|
int ncols = Integer.parseInt(split[1]);
|
||||||
|
line= br.readLine();
|
||||||
|
split = line.split(" ");
|
||||||
|
int nrows = Integer.parseInt(split[1]);
|
||||||
|
line= br.readLine();
|
||||||
|
split = line.split(" ");
|
||||||
|
double xll = Double.parseDouble(split[1]);
|
||||||
|
line= br.readLine();
|
||||||
|
split = line.split(" ");
|
||||||
|
double yll = Double.parseDouble(split[1]);
|
||||||
|
line= br.readLine();
|
||||||
|
split = line.split(" ");
|
||||||
|
double cellsize = Double.parseDouble(split[1]);
|
||||||
|
line= br.readLine();
|
||||||
|
split = line.split(" ");
|
||||||
|
double nodata = Double.parseDouble(split[1]);
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
split = line.split(" ");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
public class DbfField {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field name with a maximum of 10 characters. If less than 10, it is padded with null characters (0x00).
|
||||||
|
*/
|
||||||
|
String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Field type:
|
||||||
|
* C – Character/String
|
||||||
|
* Y – Currency
|
||||||
|
* N – Numeric/integer
|
||||||
|
* F – Float
|
||||||
|
* D – Date
|
||||||
|
* T – DateTime
|
||||||
|
* B – Double
|
||||||
|
* I – Integer
|
||||||
|
* L – Logical
|
||||||
|
* M – Memo
|
||||||
|
* G – General
|
||||||
|
* M – Memo (binary) P – Picture Q – Varbinary V – Varchar (binary)
|
||||||
|
*/
|
||||||
|
char type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of decimal places.
|
||||||
|
*/
|
||||||
|
int size;
|
||||||
|
|
||||||
|
DbfField(String name, char type, int size) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shape File Header Reader.<br><br>
|
||||||
|
* used for *.dbf-files.<br>
|
||||||
|
*
|
||||||
|
* @author jrulka
|
||||||
|
*/
|
||||||
|
public class DbfHeader {
|
||||||
|
int fileType;
|
||||||
|
int dateY;
|
||||||
|
int dateM;
|
||||||
|
int dateD;
|
||||||
|
int numberOfRecords;
|
||||||
|
/**
|
||||||
|
* Position of first data record
|
||||||
|
*/
|
||||||
|
int dataPos;
|
||||||
|
/**
|
||||||
|
* Length of one data record, including delete flag
|
||||||
|
*/
|
||||||
|
int recordSize;
|
||||||
|
|
||||||
|
static final int SIZE_BYTES = 32;
|
||||||
|
|
||||||
|
DbfField[] fields;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new ShapeFileHeader.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public DbfHeader(BufferedInputStream bis) throws Exception {
|
||||||
|
byte[] data = new byte[32];
|
||||||
|
if (bis.read(data) != 32) {
|
||||||
|
throw new Exception("Invalid dbf file");
|
||||||
|
}
|
||||||
|
ByteBuffer bb = ByteBuffer.wrap(data);
|
||||||
|
// MAIN FILE HEADER
|
||||||
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
fileType = bb.get(0);
|
||||||
|
dateY = bb.get(1) + 1900;
|
||||||
|
dateM = bb.get(2);
|
||||||
|
dateD = bb.get(3);
|
||||||
|
numberOfRecords = bb.getInt(4);
|
||||||
|
dataPos = bb.getShort(8);
|
||||||
|
recordSize = bb.getShort(10);
|
||||||
|
// start of fields
|
||||||
|
int numFields = (dataPos - 32 - 1) / SIZE_BYTES;
|
||||||
|
fields = new DbfField[numFields];
|
||||||
|
for (int i = 0; i < numFields; i++) {
|
||||||
|
if (bis.read(data) != 32) {
|
||||||
|
throw new Exception("Invalid dbf file");
|
||||||
|
}
|
||||||
|
bb = ByteBuffer.wrap(data);
|
||||||
|
byte[] fieldData = new byte[11]; //0-11
|
||||||
|
bb.get(fieldData);
|
||||||
|
String name = null;
|
||||||
|
try {
|
||||||
|
name = new String(fieldData, "UTF-8");
|
||||||
|
name = name.substring(0, name.indexOf('\0')); // get proper name
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
char type = (char) bb.get();
|
||||||
|
bb.getInt();
|
||||||
|
int size = bb.get() & 0xFF; // so we get values from 0-255.
|
||||||
|
fields[i] = new DbfField(name, type, size);
|
||||||
|
}
|
||||||
|
data = new byte[1];
|
||||||
|
if (bis.read(data) != 1) {
|
||||||
|
throw new Exception("Invalid dbf file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class DbfRecord {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OSM Id taken from the Id of this feature (node_id, way_id, or relation_id) in the
|
||||||
|
* OSM database.
|
||||||
|
* VARCHAR (10 Bytes)
|
||||||
|
*/
|
||||||
|
String osmId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Digit code (between 1000 and 9999) defining the feature class. The first one or
|
||||||
|
* two digits define the layer, the last two or three digits the class inside a layer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class name of this feature. This does not add any information that is not already
|
||||||
|
* in the “code” field but it is better readable.
|
||||||
|
*/
|
||||||
|
String fclass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of this feature, like a street or place name. If the name in OSM contains
|
||||||
|
* obviously wrong data such as “fixme" or “none”, it will be empty.
|
||||||
|
*/
|
||||||
|
String name;
|
||||||
|
|
||||||
|
|
||||||
|
public DbfRecord() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void read(BufferedInputStream bis, DbfHeader header) throws Exception {
|
||||||
|
byte[] data = new byte[header.recordSize];
|
||||||
|
if (bis.read(data) != header.recordSize) {
|
||||||
|
throw new Exception("Invalid dbf file");
|
||||||
|
}
|
||||||
|
String str = new String(data, StandardCharsets.UTF_8);
|
||||||
|
// Na pozycji 0 jest flag byte, dane startują od pozycji 1.
|
||||||
|
int from = 1;
|
||||||
|
int to = 1 + header.fields[0].size;
|
||||||
|
osmId = str.substring(from, to);
|
||||||
|
int endPos = osmId.indexOf(' ');
|
||||||
|
osmId = osmId.substring(0, endPos);
|
||||||
|
from = to;
|
||||||
|
to += header.fields[1].size;
|
||||||
|
String codeStr = str.substring(from, to);
|
||||||
|
code = Integer.parseInt(codeStr);
|
||||||
|
from = to;
|
||||||
|
to += header.fields[2].size;
|
||||||
|
fclass = str.substring(from, to);
|
||||||
|
endPos = fclass.indexOf(' ');
|
||||||
|
fclass = fclass.substring(0, endPos);
|
||||||
|
from = to;
|
||||||
|
to += header.fields[3].size;
|
||||||
|
name = str.substring(from, to);
|
||||||
|
endPos = name.indexOf(' ');
|
||||||
|
name = name.substring(0, endPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
// GET DIRECTORY
|
||||||
|
String curDir = (args[0] != null) ? args[0] : System.getProperty("user.dir");
|
||||||
|
curDir = "";
|
||||||
|
String folder = "C:/Workspace/osm/dolnoslaskie-251217-free.shp/";
|
||||||
|
|
||||||
|
// LOAD SHAPE FILE (.shp, .shx, .dbf)
|
||||||
|
// gis_osm_buildings_a_free_1
|
||||||
|
// gis_osm_water_a_free_1
|
||||||
|
OsmShapeFileReader shapefile = new OsmShapeFileReader(curDir + folder, "gis_osm_buildings_a_free_1");
|
||||||
|
ShpShape shape = shapefile.nextShape();
|
||||||
|
System.out.println("Shape type = " + shape.getShapeType());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Shapefile (SHP) is a common geospatial vector data format for GIS software, developed by Esri.
|
||||||
|
* It allaws to store geographic features (points, lines, polygons) and their attributes in a collection of
|
||||||
|
* linked files, including .shp (geometry), .shx (index), and .dbf (attributes).
|
||||||
|
* <p>
|
||||||
|
* All these files must be in the same folder and start with the same name.<br>
|
||||||
|
* example: "my_shapefile.dbf", "my_shapefile.shp", "my_shapefile.shx"<br>
|
||||||
|
* <br>
|
||||||
|
* <a href="http://en.wikipedia.org/wiki/Shapefile" target=blank>http://en.wikipedia.org/wiki/Shapefile"</a><br>
|
||||||
|
*
|
||||||
|
* @author jrulka
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OsmShapeFileReader {
|
||||||
|
|
||||||
|
ShpHeader shpHeader;
|
||||||
|
DbfHeader dbfHeader;
|
||||||
|
BufferedInputStream bisShp;
|
||||||
|
BufferedInputStream bisDbf;
|
||||||
|
|
||||||
|
// pollyline:
|
||||||
|
// layer roads:
|
||||||
|
// layer waterways:
|
||||||
|
// layer railway:
|
||||||
|
//
|
||||||
|
// pollygon:
|
||||||
|
// layer buildings: fclass: 15xx: buildings
|
||||||
|
// layer landuse:
|
||||||
|
// fclass code
|
||||||
|
// forest 7201
|
||||||
|
// park 7202
|
||||||
|
// residential 7203
|
||||||
|
// industrial 7204
|
||||||
|
|
||||||
|
// layer water:
|
||||||
|
// fclass code
|
||||||
|
// water 8000
|
||||||
|
// reservoir 8201
|
||||||
|
// river 8202
|
||||||
|
// dock 8203
|
||||||
|
// glacier 8211
|
||||||
|
// wetland 8221
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* init the ShapeFile, and load the following files:
|
||||||
|
* "path + filename.shx",
|
||||||
|
* "path + filename.dbf",
|
||||||
|
* "path + filename.shp"
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* @param filename
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public OsmShapeFileReader(String path, String filename) throws Exception {
|
||||||
|
File dir = new File(path);
|
||||||
|
File shpFile = new File(dir, filename + ".shp");
|
||||||
|
FileInputStream is = new FileInputStream(shpFile);
|
||||||
|
bisShp = new BufferedInputStream(is);
|
||||||
|
shpHeader = new ShpHeader(bisShp);
|
||||||
|
File dbfFile = new File(dir, filename + ".dbf");
|
||||||
|
bisDbf = new BufferedInputStream(new FileInputStream(dbfFile));
|
||||||
|
dbfHeader = new DbfHeader(bisDbf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShpShape nextShape() throws Exception {
|
||||||
|
boolean hasNext = false;
|
||||||
|
try {
|
||||||
|
hasNext = hasNextShape();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
if (!hasNext) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ShpShape shape = null;
|
||||||
|
DbfRecord info = null;
|
||||||
|
switch (shpHeader.shapeType) {
|
||||||
|
// case Point, PointZ, PointM:
|
||||||
|
// shape = new ShpPoint(shpHeader.shapeType);
|
||||||
|
// shape.read(bisShp);
|
||||||
|
// info = new DbfRecord();
|
||||||
|
// info.read(bisDbf, dbfHeader);
|
||||||
|
// shape.setInfo(info);
|
||||||
|
// return shape;
|
||||||
|
// case PolyLine, PolyLineZ, PolyLineM:
|
||||||
|
// shape = new ShpPolyLine(shpHeader.shapeType);
|
||||||
|
// shape.read(bisShp);
|
||||||
|
// info = new DbfRecord();
|
||||||
|
// info.read(bisDbf, dbfHeader);
|
||||||
|
// shape.setInfo(info);
|
||||||
|
// return shape;
|
||||||
|
// case Polygon, PolygonZ, PolygonM:
|
||||||
|
// shape = new ShpPolygon(shpHeader.shapeType);
|
||||||
|
// shape.read(bisShp);
|
||||||
|
// info = new DbfRecord();
|
||||||
|
// info.read(bisDbf, dbfHeader);
|
||||||
|
// shape.setInfo(info);
|
||||||
|
// return shape;
|
||||||
|
// case MultiPoint, MultiPointZ, MultiPointM:
|
||||||
|
// shape = new ShpMultiPoint(shpHeader.shapeType);
|
||||||
|
// shape.read(bisShp);
|
||||||
|
// info = new DbfRecord();
|
||||||
|
// info.read(bisDbf, dbfHeader);
|
||||||
|
// shape.setInfo(info);
|
||||||
|
// return shape;
|
||||||
|
default:
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNextShape() throws IOException {
|
||||||
|
return bisShp.available() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shape File Header Reader.<br><br>
|
||||||
|
* used for *.shp-files and *.shx-files.<br>
|
||||||
|
* contains information about:<br>
|
||||||
|
* ...<br>
|
||||||
|
* Shape-Type<br>
|
||||||
|
* boundingbox<br>
|
||||||
|
* measure-range<br>
|
||||||
|
* ...<br>
|
||||||
|
*
|
||||||
|
* @author jrulka
|
||||||
|
*/
|
||||||
|
public class ShpHeader {
|
||||||
|
final static int SHAPE_FILE_CODE = 9994;
|
||||||
|
final static int SHAPE_FILE_VERSION = 1000;
|
||||||
|
|
||||||
|
int fileLength;
|
||||||
|
int shapeTypeCode;
|
||||||
|
double[][] bbox = new double[3][2]; // [x, y, z][min, max]
|
||||||
|
double[] rangeM = new double[2]; // [min, max]
|
||||||
|
|
||||||
|
ShpShape.Type shapeType = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new ShapeFileHeader.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public ShpHeader(BufferedInputStream bis) throws Exception {
|
||||||
|
byte[] data = new byte[100];
|
||||||
|
if (bis.read(data) != 100) {
|
||||||
|
throw new Exception("Invalid shp file");
|
||||||
|
}
|
||||||
|
ByteBuffer bb = ByteBuffer.wrap(data);
|
||||||
|
// MAIN FILE HEADER
|
||||||
|
bb.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
// magic number
|
||||||
|
if (bb.getInt(0) != SHAPE_FILE_CODE) {
|
||||||
|
throw new IOException("(ShapeFile) error: SHP_MAGIC = " + SHAPE_FILE_CODE);
|
||||||
|
}
|
||||||
|
// file length
|
||||||
|
fileLength = bb.getInt(24);
|
||||||
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
// shp version
|
||||||
|
if (bb.getInt(28) != SHAPE_FILE_VERSION) {
|
||||||
|
throw new IOException("(ShapeFile) error: SHP_VERSION = " + SHAPE_FILE_VERSION);
|
||||||
|
}
|
||||||
|
shapeTypeCode = bb.getInt(32);
|
||||||
|
try {
|
||||||
|
shapeType = ShpShape.Type.getByCode(shapeTypeCode);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
bbox[0][0] = bb.getDouble(36); // x-min
|
||||||
|
bbox[1][0] = bb.getDouble(44); // y-min
|
||||||
|
bbox[0][1] = bb.getDouble(52); // x-max
|
||||||
|
bbox[1][1] = bb.getDouble(60); // y-max
|
||||||
|
bbox[2][0] = bb.getDouble(68); // z-min
|
||||||
|
bbox[2][1] = bb.getDouble(76); // z-max
|
||||||
|
rangeM[0] = bb.getDouble(84); // m-min
|
||||||
|
rangeM[1] = bb.getDouble(92); // m-max
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the type ShapeType the shapeFile contains.<br>
|
||||||
|
* a shapeFile contains only one type of shape.<br>
|
||||||
|
*
|
||||||
|
* @return ShpShape.Type
|
||||||
|
*/
|
||||||
|
public ShpShape.Type getShapeType() {
|
||||||
|
return shapeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* data storage: [3][2] --> [x,y,z][min, max].
|
||||||
|
*
|
||||||
|
* @return boundingbox as double[][]
|
||||||
|
*/
|
||||||
|
public double[][] getBoundingBox() {
|
||||||
|
return bbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get measure range.<br>
|
||||||
|
* data storage: [2] --> [min, max]
|
||||||
|
*
|
||||||
|
* @return double[]
|
||||||
|
*/
|
||||||
|
public double[] getMeasureRange() {
|
||||||
|
return rangeM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get length in bytes of the shapeFile.
|
||||||
|
*
|
||||||
|
* @return length in bytes.
|
||||||
|
*/
|
||||||
|
public int getFileLengthBytes() {
|
||||||
|
return fileLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get Verions on the shapeFile.
|
||||||
|
*
|
||||||
|
* @return should return 1000.
|
||||||
|
*/
|
||||||
|
public int getVersion() {
|
||||||
|
return SHAPE_FILE_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get MAGIC NUMBER of shapeFile.
|
||||||
|
*
|
||||||
|
* @return should return 9994.
|
||||||
|
*/
|
||||||
|
public int getMagicNumber() {
|
||||||
|
return SHAPE_FILE_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void print() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shape: MultiPoint.<br>
|
||||||
|
* <pre>
|
||||||
|
* A MultiPoint represents a set of points.
|
||||||
|
* Possible ShapeTypes:
|
||||||
|
* MultiPoint ( 8 ),
|
||||||
|
* MultiPointZ ( 18 ),
|
||||||
|
* MultiPointM ( 28 ),
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jrulka
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ShpMultiPoint extends ShpShape {
|
||||||
|
double xMin;
|
||||||
|
double yMin;
|
||||||
|
double zMin;
|
||||||
|
double mMin;
|
||||||
|
double xMax;
|
||||||
|
double yMax;
|
||||||
|
double zMax;
|
||||||
|
double mMax;
|
||||||
|
int numberOfPoints;
|
||||||
|
double[] pointsX;
|
||||||
|
double[] pointsY;
|
||||||
|
double[] pointsZ;
|
||||||
|
double[] valuesM;
|
||||||
|
|
||||||
|
public ShpMultiPoint(ShpShape.Type shapeType) {
|
||||||
|
super(shapeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readRecordContent(ByteBuffer bb) {
|
||||||
|
xMin = bb.getDouble(); // x-min
|
||||||
|
yMin = bb.getDouble(); // y-min
|
||||||
|
xMax = bb.getDouble(); // x-max
|
||||||
|
yMax = bb.getDouble(); // y-max
|
||||||
|
numberOfPoints = bb.getInt(); // number of points (total of all parts)
|
||||||
|
pointsX = new double[numberOfPoints];
|
||||||
|
pointsY = new double[numberOfPoints];
|
||||||
|
pointsZ = new double[numberOfPoints];
|
||||||
|
for (int i = 0; i < numberOfPoints; i++) {
|
||||||
|
pointsX[i] = bb.getDouble(); // x - coordinate
|
||||||
|
pointsY[i] = bb.getDouble(); // y - coordinate
|
||||||
|
}
|
||||||
|
// if SHAPE-TYPE: 18
|
||||||
|
if (type.hasZvalues()) {
|
||||||
|
zMin = bb.getDouble(); // z-min
|
||||||
|
zMax = bb.getDouble(); // z-max
|
||||||
|
for (int i = 0; i < numberOfPoints; i++) {
|
||||||
|
pointsZ[i] = bb.getDouble(); // z - coordinate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if SHAPE-TYPE: 18 | 28
|
||||||
|
if (type.hasMvalues()) {
|
||||||
|
mMin = bb.getDouble(); // m-min
|
||||||
|
mMax = bb.getDouble(); // m-max
|
||||||
|
valuesM = new double[numberOfPoints];
|
||||||
|
for (int i = 0; i < numberOfPoints; i++) {
|
||||||
|
valuesM[i] = bb.getDouble(); // m - value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shape: Point.<br>
|
||||||
|
* <pre>
|
||||||
|
* possible ShapeTypes:
|
||||||
|
* Point ( 1 ),
|
||||||
|
* PointZ ( 11 ),
|
||||||
|
* PointM ( 21 ),
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jrulka
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ShpPoint extends ShpShape {
|
||||||
|
|
||||||
|
// SHAPE RECORD CONTENT
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double z;
|
||||||
|
double m; //[m-value]
|
||||||
|
|
||||||
|
public ShpPoint(ShpShape.Type shapeType) {
|
||||||
|
super(shapeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readRecordContent(ByteBuffer bb) {
|
||||||
|
x = bb.getDouble(); // x - coordinate
|
||||||
|
y = bb.getDouble(); // y - coordinate
|
||||||
|
// if SHAPE-TYPE: 11
|
||||||
|
if (type.hasZvalues()) {
|
||||||
|
z = bb.getDouble(); // z - coordinate
|
||||||
|
}
|
||||||
|
// if SHAPE-TYPE: 11 | 21
|
||||||
|
if (type.hasMvalues()) {
|
||||||
|
m = bb.getDouble(); // m - value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for PollyLine, Pollygon
|
||||||
|
*/
|
||||||
|
public abstract class ShpPollyShape extends ShpShape {
|
||||||
|
// SHAPE RECORD CONTENT
|
||||||
|
double xMin;
|
||||||
|
double yMin;
|
||||||
|
double zMin;
|
||||||
|
double mMin;
|
||||||
|
double xMax;
|
||||||
|
double yMax;
|
||||||
|
double zMax;
|
||||||
|
double mMax;
|
||||||
|
private int numberOfParts;
|
||||||
|
private int numberOfPoints;
|
||||||
|
private int[] partsPos;
|
||||||
|
double[] pointsX; // [number of points][x,y,z]
|
||||||
|
double[] pointsY;
|
||||||
|
double[] pointsZ;
|
||||||
|
double[] valuesM; // [number of points][m-value]
|
||||||
|
|
||||||
|
public ShpPollyShape(ShpShape.Type shape_type) {
|
||||||
|
super(shape_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readRecordContent(ByteBuffer bb) {
|
||||||
|
xMin = bb.getDouble(); // x-min
|
||||||
|
yMin = bb.getDouble(); // y-min
|
||||||
|
xMax = bb.getDouble(); // x-max
|
||||||
|
yMax = bb.getDouble(); // y-max
|
||||||
|
numberOfParts = bb.getInt(); // number of polygon-parts / rings
|
||||||
|
numberOfPoints = bb.getInt(); // number of points (total of all parts)
|
||||||
|
partsPos = new int[numberOfParts];
|
||||||
|
for (int i = 0; i < numberOfParts; i++) {
|
||||||
|
partsPos[i] = bb.getInt(); // index of the point-list (indicates start-point of a polygon)
|
||||||
|
}
|
||||||
|
pointsX = new double[numberOfPoints];
|
||||||
|
pointsY = new double[numberOfPoints];
|
||||||
|
for (int i = 0; i < numberOfPoints; i++) {
|
||||||
|
pointsX[i] = bb.getDouble(); // x - coordinate
|
||||||
|
pointsY[i] = bb.getDouble(); // y - coordinate
|
||||||
|
}
|
||||||
|
// if SHAPE-TYPE: 13
|
||||||
|
if (type.hasZvalues()) {
|
||||||
|
zMin = bb.getDouble(); // z-min
|
||||||
|
zMax = bb.getDouble(); // z-max
|
||||||
|
for (int i = 0; i < numberOfPoints; i++) {
|
||||||
|
pointsZ[i] = bb.getDouble(); // z - coordinate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if SHAPE-TYPE: 13 | 23
|
||||||
|
if (type.hasMvalues()) {
|
||||||
|
mMin = bb.getDouble(); // m-min
|
||||||
|
mMax = bb.getDouble(); // m-max
|
||||||
|
valuesM = new double[numberOfPoints];
|
||||||
|
for (int i = 0; i < numberOfPoints; i++) {
|
||||||
|
valuesM[i] = bb.getDouble(); // m - value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shape: PolyLine.<br>
|
||||||
|
* <pre>
|
||||||
|
* polyline: consists of one or more parts.
|
||||||
|
* part: connected sequence of two or more points.
|
||||||
|
* may or may not be connected to one another.
|
||||||
|
* may or may not intersect one another.
|
||||||
|
* same content as polygon.
|
||||||
|
* possible ShapeTypes:
|
||||||
|
* PolyLine ( 8 ),
|
||||||
|
* PolyLineZ ( 18 ),
|
||||||
|
* PolyLineM ( 28 ),
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jrulka
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ShpPolyLine extends ShpPollyShape {
|
||||||
|
|
||||||
|
public ShpPolyLine(Type shape_type) {
|
||||||
|
super(shape_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shape: Polygon.<br>
|
||||||
|
* <pre>
|
||||||
|
* polygon: consists of one or more rings (multiple outer rings).
|
||||||
|
* ring: four or more points ... closed, non-self-intersecting loop.
|
||||||
|
* interiour: clockwise order of vertices.
|
||||||
|
* same content as PolyLine.
|
||||||
|
* possible ShapeTypes:
|
||||||
|
* Polygon ( 8 ),
|
||||||
|
* PolygonZ ( 18 ),
|
||||||
|
* PolygonM ( 28 ),
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jrulka
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ShpPolygon extends ShpPollyShape {
|
||||||
|
|
||||||
|
public ShpPolygon(Type shape_type) {
|
||||||
|
super(shape_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,195 @@
|
|||||||
|
package pl.wat.ms4ds.terenfunkcje.osm.shapefile;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for Shapes.
|
||||||
|
*
|
||||||
|
* @author jrulka
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class ShpShape {
|
||||||
|
protected Type type;
|
||||||
|
|
||||||
|
//RECORD HEADER
|
||||||
|
protected int recordNumber;
|
||||||
|
protected int contentLength;
|
||||||
|
protected int shapeTypeCode;
|
||||||
|
|
||||||
|
DbfRecord info;
|
||||||
|
|
||||||
|
protected ShpShape(Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read the shape-data from the bytebuffer (buffer-position has to be defined before).<br>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void read(BufferedInputStream bis) throws Exception {
|
||||||
|
byte[] data = new byte[8];
|
||||||
|
if (bis.read(data) != 8) {
|
||||||
|
throw new Exception("Invalid shp file");
|
||||||
|
}
|
||||||
|
ByteBuffer bb = ByteBuffer.wrap(data);
|
||||||
|
// 1) READ RECORD HEADER
|
||||||
|
readRecordHeader(bb);
|
||||||
|
// Content length in words (16 bits)
|
||||||
|
byte[] dataContent = new byte[contentLength * 2];
|
||||||
|
if (bis.read(dataContent) != contentLength * 2) {
|
||||||
|
throw new Exception("Invalid shp file");
|
||||||
|
}
|
||||||
|
bb = ByteBuffer.wrap(dataContent);
|
||||||
|
// 2) READ RECORD CONTENT
|
||||||
|
// 2.1) check Shape Type
|
||||||
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
shapeTypeCode = bb.getInt();
|
||||||
|
try {
|
||||||
|
Type shape_type = Type.getByCode(shapeTypeCode);
|
||||||
|
if (shape_type == type) {
|
||||||
|
readRecordContent(bb);
|
||||||
|
} else if (shape_type != type) {
|
||||||
|
throw new Exception("(Shape) shape_type = " + shape_type + ", but expected " + type);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void readRecordHeader(ByteBuffer bb) {
|
||||||
|
bb.order(ByteOrder.BIG_ENDIAN);
|
||||||
|
recordNumber = bb.getInt();
|
||||||
|
contentLength = bb.getInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void readRecordContent(ByteBuffer bb);
|
||||||
|
|
||||||
|
void setInfo(DbfRecord info) {
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the record number of the shape.
|
||||||
|
*
|
||||||
|
* @return record number
|
||||||
|
*/
|
||||||
|
public int getRecordNumber() {
|
||||||
|
return recordNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the Type of the Shape.
|
||||||
|
*
|
||||||
|
* @return ShpShape.Type
|
||||||
|
*/
|
||||||
|
public Type getShapeType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Shape Types
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
public enum Type {
|
||||||
|
/**
|
||||||
|
* ID= 0
|
||||||
|
*/
|
||||||
|
NullShape(0, false, false),
|
||||||
|
/**
|
||||||
|
* ID= 1
|
||||||
|
*/
|
||||||
|
Point(1, false, false),
|
||||||
|
/**
|
||||||
|
* ID=11
|
||||||
|
*/
|
||||||
|
PointZ(11, true, true),
|
||||||
|
/**
|
||||||
|
* ID=21
|
||||||
|
*/
|
||||||
|
PointM(21, false, true),
|
||||||
|
/**
|
||||||
|
* ID= 3
|
||||||
|
*/
|
||||||
|
PolyLine(3, false, false),
|
||||||
|
/**
|
||||||
|
* ID=13
|
||||||
|
*/
|
||||||
|
PolyLineZ(13, true, true),
|
||||||
|
/**
|
||||||
|
* ID=23
|
||||||
|
*/
|
||||||
|
PolyLineM(23, false, true),
|
||||||
|
/**
|
||||||
|
* ID= 5
|
||||||
|
*/
|
||||||
|
Polygon(5, false, false),
|
||||||
|
/**
|
||||||
|
* ID=15
|
||||||
|
*/
|
||||||
|
PolygonZ(15, true, true),
|
||||||
|
/**
|
||||||
|
* ID=25
|
||||||
|
*/
|
||||||
|
PolygonM(25, false, true),
|
||||||
|
/**
|
||||||
|
* ID= 8
|
||||||
|
*/
|
||||||
|
MultiPoint(8, false, false),
|
||||||
|
/**
|
||||||
|
* ID=18
|
||||||
|
*/
|
||||||
|
MultiPointZ(18, true, true),
|
||||||
|
/**
|
||||||
|
* ID=28
|
||||||
|
*/
|
||||||
|
MultiPointM(28, false, true),
|
||||||
|
/**
|
||||||
|
* ID=31
|
||||||
|
*/
|
||||||
|
MultiPatch(31, true, true);
|
||||||
|
|
||||||
|
|
||||||
|
public final int code;
|
||||||
|
boolean has_z_values;
|
||||||
|
boolean has_m_values;
|
||||||
|
|
||||||
|
Type(int code, boolean has_z_values, boolean has_m_values) {
|
||||||
|
this.has_z_values = has_z_values;
|
||||||
|
this.has_m_values = has_m_values;
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getByCode(int ID) throws Exception {
|
||||||
|
for (Type st : Type.values())
|
||||||
|
if (st.code == ID)
|
||||||
|
return st;
|
||||||
|
throw new Exception("ShapeType: " + ID + " does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasZvalues() {
|
||||||
|
return has_z_values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMvalues() {
|
||||||
|
return has_m_values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTypeOfPolygon() {
|
||||||
|
return (this == Type.Polygon | this == Type.PolygonM | this == Type.PolygonZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTypeOfPolyLine() {
|
||||||
|
return (this == Type.PolyLine | this == Type.PolyLineM | this == Type.PolyLineZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTypeOfPoint() {
|
||||||
|
return (this == Type.Point | this == Type.PointM | this == Type.PointZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTypeOfMultiPoint() {
|
||||||
|
return (this == Type.MultiPoint | this == Type.MultiPointM | this == Type.MultiPointZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
76
teren.properties
Normal file
76
teren.properties
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#Polska
|
||||||
|
#Wspolrzedne referencyjne i wielkosc obszaru
|
||||||
|
x_ref=14
|
||||||
|
y_ref=49
|
||||||
|
dx_ref=11
|
||||||
|
dy_ref=7
|
||||||
|
#kwadraty_dir=c:/Workspace/git/teren-funkcje/au2data/new_teren/Polska/kwadraty/
|
||||||
|
kwadraty_dir=C:/Workspace/_data/swdt/ms4ds/teren/kwadraty/
|
||||||
|
drogi_dir=au2data/new_teren/Polska/drogi/
|
||||||
|
|
||||||
|
#Afganistan
|
||||||
|
#Wspolrzedne referencyjne i wielkosc obszaru
|
||||||
|
#x_ref=60
|
||||||
|
#y_ref=29
|
||||||
|
#dx_ref=15
|
||||||
|
#dy_ref=10
|
||||||
|
#kwadraty_dir=/au2data/new_teren/Afganistan/kwadraty/
|
||||||
|
#drogi_dir=/au2data/new_teren/Afganistan/drogi/
|
||||||
|
|
||||||
|
#Rozdzielczosc terenu dl_mk=200 | 100 | 50 | 25 | 20
|
||||||
|
dl_mk=100
|
||||||
|
|
||||||
|
#W celu wymuszenia (mimo jej braku) przejezdności terenu nalezy ustawić na: on
|
||||||
|
przejezdnosc_zawsze=off
|
||||||
|
minimalny_stopien_przejezdnosci=0.1
|
||||||
|
|
||||||
|
#Minimalny stopień przejezdności dla ruchu na przełaj dla kwadratów przejezdnych
|
||||||
|
#dla algorytmów wyznaczania dróg dla działań typu: atak, obrona, rozmieszczenie, ...
|
||||||
|
stopien_przejezdnosci.minimalny_na_przelaj=0.7
|
||||||
|
#Minimalny stopień przejezdności dla ruchu po drodze z uwzględnieniem nachylenia terenu
|
||||||
|
stopien_przejezdnosci.minimalny.na_drodze.nachylenie_terenu=0.9
|
||||||
|
#Minimalny stopień przejezdności dla ruchu na przełaj z uwzględnieniem nachylenia terenu
|
||||||
|
#Dla kątów <-alfa_max, alfa_min> stopień przejezdności == 1
|
||||||
|
#Dla kątów <alfa_min, alfa_max> stopień przejezdności == liniowo (względem tangensa kąta) maleje od 1 do tej wartości
|
||||||
|
#w p.p. stopień przejezdności == 0
|
||||||
|
stopien_przejezdnosci.minimalny.na_przelaj.nachylenie_terenu=0.1
|
||||||
|
#Minimalny kąt nachylenia terenu wpływający na stopień przejezdności (alfa_min) dla ruchu na drodze [stopnie]
|
||||||
|
stopien_przejezdnosci.na_drodze.nachylenie_terenu.kat_minimalny=15
|
||||||
|
#Maksymalny kąt nachylenia terenu wpływający na stopień przejezdności (alfa_max) dla ruchu na drodze [stopnie]
|
||||||
|
stopien_przejezdnosci.na_drodze.nachylenie_terenu.kat_maksymalny=50
|
||||||
|
#Minimalny kąt nachylenia terenu wpływający na stopień przejezdności (alfa_min) dla ruchu na przełaj [stopnie]
|
||||||
|
stopien_przejezdnosci.na_przelaj.nachylenie_terenu.kat_minimalny=15
|
||||||
|
#Maksymalny kąt nachylenia terenu wpływający na stopień przejezdności (alfa_min) dla ruchu na przełaj [stopnie]
|
||||||
|
stopien_przejezdnosci.na_przelaj.nachylenie_terenu.kat_maksymalny=45
|
||||||
|
|
||||||
|
#stopień przejezdności - parametr dla symulacji ruchu
|
||||||
|
stopien_przejezdnosci.podwozie_gasienicowe.teren_zabudowany=0.8
|
||||||
|
stopien_przejezdnosci.podwozie_gasienicowe.teren_zalesiony=0.25
|
||||||
|
stopien_przejezdnosci.podwozie_gasienicowe.teren_zabagniony=0.2
|
||||||
|
stopien_przejezdnosci.podwozie_gasienicowe.teren_zawodniony=0.0
|
||||||
|
stopien_przejezdnosci.podwozie_gasienicowe.teren_czysty=1.0
|
||||||
|
|
||||||
|
stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabudowany=0.7
|
||||||
|
stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zalesiony=0.15
|
||||||
|
stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabagniony=0.1
|
||||||
|
stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zawodniony=0.0
|
||||||
|
stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_czysty=0.9
|
||||||
|
|
||||||
|
stopien_przejezdnosci.podwozie_kolowe.teren_zabudowany=0.6
|
||||||
|
stopien_przejezdnosci.podwozie_kolowe.teren_zalesiony=0.1
|
||||||
|
stopien_przejezdnosci.podwozie_kolowe.teren_zabagniony=0.05
|
||||||
|
stopien_przejezdnosci.podwozie_kolowe.teren_zawodniony=0.0
|
||||||
|
stopien_przejezdnosci.podwozie_kolowe.teren_czysty=0.8
|
||||||
|
|
||||||
|
stopien_przejezdnosci.podwozie_poduszka.teren_zabudowany=0.7
|
||||||
|
stopien_przejezdnosci.podwozie_poduszka.teren_zalesiony=0.1
|
||||||
|
stopien_przejezdnosci.podwozie_poduszka.teren_zabagniony=0.9
|
||||||
|
stopien_przejezdnosci.podwozie_poduszka.teren_zawodniony=1.0
|
||||||
|
stopien_przejezdnosci.podwozie_poduszka.teren_czysty=1.0
|
||||||
|
|
||||||
|
stopien_przejezdnosci.podwozie_plozy.teren_zabudowany=0.1
|
||||||
|
stopien_przejezdnosci.podwozie_plozy.teren_zalesiony=0.1
|
||||||
|
stopien_przejezdnosci.podwozie_plozy.teren_zabagniony=0.1
|
||||||
|
stopien_przejezdnosci.podwozie_plozy.teren_zawodniony=0.0
|
||||||
|
stopien_przejezdnosci.podwozie_plozy.teren_czysty=1.0
|
||||||
|
|
||||||
Reference in New Issue
Block a user