Compare commits

...

8 Commits

57 changed files with 2341 additions and 2956 deletions

1
.gitignore vendored
View File

@@ -92,6 +92,7 @@ http-client.private.env.json
# Log file # Log file
*.log *.log
logfile*.txt
# BlueJ files # BlueJ files
*.ctxt *.ctxt

View File

@@ -1,4 +1,5 @@
<configuration> <configuration>
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<!-- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>--> <!-- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>-->
@@ -6,7 +7,8 @@
</encoder> </encoder>
</appender> </appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender"> <appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>terrain.log</file> <file>logfile-${bySecond}.txt</file>
<!-- <file>terrain.log</file>-->
<append>true</append> <append>true</append>
<encoder> <encoder>
<!-- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>--> <!-- <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>-->
@@ -15,11 +17,11 @@
</encoder> </encoder>
</appender> </appender>
<logger name="pl.wat.ms4ds.terrain" level="trace"> <logger name="pl.wat.ms4ds.terrain" level="debug">
<appender-ref ref="FILE"/> <appender-ref ref="FILE"/>
</logger> </logger>
<root level="trace"> <root level="debug">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>

View File

@@ -97,7 +97,7 @@
<archive> <archive>
<manifest> <manifest>
<addClasspath>true</addClasspath> <addClasspath>true</addClasspath>
<mainClass>pl.wat.ms4ds.terrain.nmt.NMTDataProvider</mainClass> <mainClass>pl.wat.ms4ds.terrain.nmt.NmtDataProvider</mainClass>
</manifest> </manifest>
<manifestEntries> <manifestEntries>
<Class-Path>teren-funkcje-1.0.2-SNAPSHOT.jar</Class-Path> <Class-Path>teren-funkcje-1.0.2-SNAPSHOT.jar</Class-Path>

View File

@@ -87,7 +87,7 @@ public final class AStar {
@Override @Override
public String toString() { public String toString() {
return "AStarNode{" + return "AStar.Node{" +
"x=" + x + "x=" + x +
", y=" + y + ", y=" + y +
", koncowy=" + koncowy + ", koncowy=" + koncowy +
@@ -153,7 +153,7 @@ public final class AStar {
} else { } else {
odcinek = wyznaczDroge(start, stop, staryKier, false, podwozie, rodzajDzialania); odcinek = wyznaczDroge(start, stop, staryKier, false, podwozie, rodzajDzialania);
} }
if (odcinek.size() == 0) { if (odcinek.isEmpty()) {
// gdy nie istnieje droga między danymi punktami profilującymi, to zwracam kolekcję pustą // gdy nie istnieje droga między danymi punktami profilującymi, to zwracam kolekcję pustą
return odcinek; return odcinek;
} }

View File

@@ -0,0 +1,198 @@
package pl.wat.ms4ds.terrain;
import java.awt.Color;
import java.util.Arrays;
public class AltitudeColorMapper {
// Define the color stops and corresponding normalized values (0.0 to 1.0)
private static final float[] STOPS = {0.0f, 0.1f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f};
private static final Color[] COLORS2 = {
new Color(0, 0, 64), // Dark Navy Blue
new Color(0, 64, 204), // Medium Blue
new Color(51, 204, 51), // Bright Green
new Color(255, 255, 128),// Yellow
new Color(228, 96, 0), // Orange
new Color(96, 0, 0), // Red
new Color(158, 110, 110),
new Color(220, 220, 220), // Red
Color.WHITE // White
};
private static final Color[] COLORS = {
new Color(40, 0, 40),
// new Color(20, 0, 60),
new Color(0, 0, 80), // DARK BLUE
// new Color(0, 0, 160),
// new Color(0, 0, 200),
new Color(0, 0, 255), // BLUE
// new Color(0, 80, 255),
// new Color(0, 160, 255),
// new Color(0, 200, 255),
new Color(0, 255, 255),
// new Color(0, 255, 200),
//
// new Color(0, 255, 160),
new Color(0, 255, 0), // GREEN
// new Color(80, 255, 0),
// new Color(80, 160, 20),
// new Color(120, 255, 0),
// new Color(200, 255, 0),
new Color(255, 255, 0), // YELLOW
// new Color(255, 200, 0),
// new Color(255, 120, 0),
// new Color(255, 60, 0),
new Color(255, 0, 0), // RED
// new Color(120, 0, 0),
new Color(40, 0, 0), // DARK RED
// new Color(80, 40, 40),
// new Color(120, 60, 60),
// new Color(160, 100, 100),
// new Color(200, 140, 140),
// new Color(220, 180, 180),
new Color(255, 215, 215),
Color.WHITE // White
};
/**
* RGB value representing the color in the default sRGB ColorModel.
* Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are blue.
* value = ((a & 0xFF) << 24) |
* ((r & 0xFF) << 16) |
* ((g & 0xFF) << 8) |
* ((b & 0xFF) << 0);
*/
private static final int[] COLORS_RGB = new int[7];
// static {
// Color c = new Color(0x37004E);
// int v = 0x37004E;
// int a = 0;
// int r = 0;
// int g = 0;
// int b = 50;
// int value = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) << 0);
// COLORS_RGB[0] = value;
// a = 0;
// r = 0;
// g = 0;
// b = 0;
// value = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | ((b & 0xFF) << 0);
// COLORS_RGB[0] = value;
// }
private static final Color[] gamaKolorow;
static {
Color[] gamaKolorowTemp = new Color[2000];
int i = 0;
int r = 40;
int g = 0;
int b = 40;
gamaKolorowTemp[i++] = new Color(r, g, b, 255);
for (int j = 0; j < 40; j++) {
// r: 40->0, g:0, b: 40->80
r--;
b++;
gamaKolorowTemp[i++] = new Color(r, g, b, 255);
}
for (int j = 0; j < 175; j++) {
// r: 0, g:0, b: 80->255
b++;
gamaKolorowTemp[i++] = new Color(r, g, b, 255);
}
for (int j = 0; j < 255; j++) {
// r: 0, g:1->255, b: 255
g++;
gamaKolorowTemp[i++] = new Color(r, g, b, 255);
}
for (int j = 0; j < 255; j++) {
// r: 0, g:255, b: 254->0
b--;
gamaKolorowTemp[i++] = new Color(r, g, b, 255);
}
for (int j = 0; j < 255; j++) {
// r: 1->255, g:255, b: 0
r++;
gamaKolorowTemp[i++] = new Color(r, g, b, 255);
}
for (int j = 0; j < 255; j++) {
// r: 255, g:254->0, b: 0
g--;
gamaKolorowTemp[i++] = new Color(r, g, b, 255);
}
for (int j = 0; j < 215; j++) {
// r: 254->40, g: 0, b: 0
r--;
gamaKolorowTemp[i++] = new Color(r, g, b, 255);
}
for (int j = 0; j < 215; j++) {
// r: 41->255, g: 0->215, b: 0->215
r++;
g++;
b++;
gamaKolorowTemp[i++] = new Color(r, g, b, 255);
}
gamaKolorow = Arrays.copyOf(gamaKolorowTemp, i);
}
/**
* Get the color corresponding to a given altitude value within a specified range.
*
* @param value The altitude value.
* @param minValue The minimum possible altitude.
* @param maxValue The maximum possible altitude.
* @return The interpolated color.
*/
public static Color getColorForAltitude(double value, double minValue, double maxValue) {
// Normalize the value to a 0.0 to 1.0 range
double normalizedValue = (value - minValue) / (maxValue - minValue);
if (normalizedValue <= 0.0) return COLORS[0];
if (normalizedValue >= 1.0) return COLORS[COLORS.length - 1];
// Find the correct interval in the color stops array
int stopIndex = 0;
while (stopIndex < STOPS.length - 1 && normalizedValue > STOPS[stopIndex + 1]) {
stopIndex++;
}
// Interpolate between the two nearest colors
float start = STOPS[stopIndex];
float end = STOPS[stopIndex + 1];
float range = end - start;
float fraction = (float) ((normalizedValue - start) / range);
Color c1 = COLORS[stopIndex];
Color c2 = COLORS[stopIndex + 1];
int r = (int) (c1.getRed() + (c2.getRed() - c1.getRed()) * fraction);
int g = (int) (c1.getGreen() + (c2.getGreen() - c1.getGreen()) * fraction);
int b = (int) (c1.getBlue() + (c2.getBlue() - c1.getBlue()) * fraction);
return new Color(r, g, b);
}
static void main() {
Color c = gamaKolorow[0];
}
}

View File

@@ -4,7 +4,7 @@ package pl.wat.ms4ds.terrain;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
abstract class BigSquare { abstract class BigSquare {
abstract Square getKwadrat(int x, int y); abstract Square getSquare(int x, int y);
protected transient String fileName; protected transient String fileName;
public int idX = 0; public int idX = 0;

View File

@@ -1,150 +0,0 @@
package pl.wat.ms4ds.terrain;
/**
* 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 Coord.Grid[] 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;
Coord.Grid[] res = new Coord.Grid[dx + 1];
for (int i = 0; i <= dx; i++) {
res[i] = new Coord.Grid(x, y);
if (p > 0) {
y += sy;
p -= ddx;
}
x += sx;
p += ddy;
}
return res;
} else {
// poruszamy sie po y
p = ddx - dy;
Coord.Grid[] res = new Coord.Grid[dy + 1];
for (int i = 0; i <= dy; i++) {
res[i] = new Coord.Grid(x, y);
if (p > 0) {
x += sx;
p -= ddy;
}
y += sy;
p += ddx;
}
return res;
}
}
static void print(Coord.Grid[] 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);
// }
}

View File

@@ -19,17 +19,14 @@ public class Coord {
this.lon = lon; this.lon = lon;
} }
public Geo(GeoCoord other) { public Geo(Geo other) {
lat = other.lat; lat = other.lat;
lon = other.lon; lon = other.lon;
} }
@Override @Override
public String toString() { public String toString() {
return "Geo{" + return "Geo{" + "lat=" + lat + ", lon=" + lon + '}';
"lat=" + lat +
", lon=" + lon +
'}';
} }
} }
@@ -61,13 +58,14 @@ public class Coord {
@Override @Override
public String toString() { public String toString() {
return "Puwg{" + return "Puwg{" + "easting=" + easting + ", northing=" + northing + '}';
"easting=" + easting +
", northing=" + northing +
'}';
} }
} }
/**
* Klasa reprezentująca współrzędne/położenie w siatce kwadratów terenu.
*
*/
public static class Grid { public static class Grid {
/** /**
@@ -97,14 +95,11 @@ public class Coord {
@Override @Override
public String toString() { public String toString() {
return "Grid{" + return "Grid{" + "x=" + x + ", y=" + y + '}';
"x=" + x +
", y=" + y +
'}';
} }
private static final double ODWROT_SS_DX_MS = 1.0 / MapConsts.SS_DX_MS; private static final double ODWROT_SS_DX_MS = 1.0 / MapConsts.SS_DELTA_LON_MS;
private static final double ODWROT_SS_DY_MS = 1.0 / MapConsts.SS_DY_MS; private static final double ODWROT_SS_DY_MS = 1.0 / MapConsts.SS_DELTA_LAT_MS;
public static double distance(Grid a, Grid b) { public static double distance(Grid a, Grid b) {
int dx = a.x - b.x; int dx = a.x - b.x;
@@ -213,7 +208,7 @@ public class Coord {
* @param idX współrzęna x GridCoord * @param idX współrzęna x GridCoord
* @return długość geograficzna * @return długość geograficzna
*/ */
public static float zamienIdKwadratuXNaDlugoscGeo(int idX) { public static float convertGridXToLon(int idX) {
long xms = zamienIdKwadratuXNaWspXms(idX); long xms = zamienIdKwadratuXNaWspXms(idX);
double lon = (double) xms / (double) MapConsts.DEG_MS - 180; double lon = (double) xms / (double) MapConsts.DEG_MS - 180;
return (float) lon; return (float) lon;
@@ -225,7 +220,7 @@ public class Coord {
* @param idY współrzęna y GridCoord * @param idY współrzęna y GridCoord
* @return szerokość geograficzna * @return szerokość geograficzna
*/ */
public static float zamienIdKwadratuYNaSzerokoscGeo(int idY) { public static float covertGridYToLat(int idY) {
long yms = zamienIdKwadratuYNaWspYms(idY); long yms = zamienIdKwadratuYNaWspYms(idY);
double lat = (double) yms / (double) MapConsts.DEG_MS - 90; double lat = (double) yms / (double) MapConsts.DEG_MS - 90;
return (float) lat; return (float) lat;
@@ -238,7 +233,7 @@ public class Coord {
public static long zamienIdKwadratuXNaWspXms(int idKwX) { public static long zamienIdKwadratuXNaWspXms(int idKwX) {
// indeksowanie kwadratow pola walki zaczyna sie od (0, 0) // indeksowanie kwadratow pola walki zaczyna sie od (0, 0)
// przesuniecie wspolrzednych do srodka kwadratu // przesuniecie wspolrzednych do srodka kwadratu
long xms = MapConsts.X_REF_MS + (long) ((idKwX + 0.5) * MapConsts.SS_DX_MS); long xms = MapConsts.X_REF_MS + (long) ((idKwX + 0.5) * MapConsts.SS_DELTA_LON_MS);
xms %= MapConsts.ANGLE_360_MS; xms %= MapConsts.ANGLE_360_MS;
return xms; return xms;
} }
@@ -250,32 +245,60 @@ public class Coord {
public static long zamienIdKwadratuYNaWspYms(int idKwY) { public static long zamienIdKwadratuYNaWspYms(int idKwY) {
// indeksowanie kwadratow pola walki zaczyna sie od (0, 0) // indeksowanie kwadratow pola walki zaczyna sie od (0, 0)
// przesuniecie wspolrzednych do srodka kwadratu // przesuniecie wspolrzednych do srodka kwadratu
long yms = MapConsts.Y_REF_MS + (long) ((idKwY + 0.5) * MapConsts.SS_DY_MS); long yms = MapConsts.Y_REF_MS + (long) ((idKwY + 0.5) * MapConsts.SS_DELTA_LAT_MS);
return yms; return yms;
} }
/** /**
* Zamienia długość geograficzną na współrzędna x GridCoord. * Zamienia długość geograficzną na współrzędna x Coord.Grid.
* *
* @param lon długość geograficzna * @param lon długość geograficzna
* @return współrzędna x klasy GridCoord * @return współrzędna x klasy GridCoord
*/ */
public static int zamienDlugoscGeoNaIdKwadratuX(double lon) { public static int convertLonToGridX(double lon) {
double xms_f = (lon + 180) * MapConsts.DEG_MS; double xms_f = (lon + 180) * MapConsts.DEG_MS;
return zamienWspXmsNaIdKwadratuX((long) xms_f); return zamienWspXmsNaIdKwadratuX((long) xms_f);
} }
/** /**
* Zamienia szerokość geograficzną na współrzędna y GridCoord. * Zamienia szerokość geograficzną na współrzędna y Coord.Grid.
* *
* @param lat szerokość geograficzna * @param lat szerokość geograficzna
* @return współrzędna y klasy GridCoord * @return współrzędna y klasy GridCoord
*/ */
public static int zamienSzerokoscGeoNaIdKwadratuY(double lat) { public static int convertLatToGridY(double lat) {
double yms_f = (lat + 90) * MapConsts.DEG_MS; double yms_f = (lat + 90) * MapConsts.DEG_MS;
return zamienWspYmsNaIdKwadratuY((long) yms_f); return zamienWspYmsNaIdKwadratuY((long) yms_f);
} }
public static final double INVERT_SS_DELTA_LON = 1 / MapConsts.SS_DELTA_LON;
public static final double INVERT_SS_DELTA_LAT = 1 / MapConsts.SS_DELTA_LAT;
private static final double REF_LON_OFFSET = 180 - MapConsts.REF_LON;
private static final double REF_LAT_OFFSET = 90 - MapConsts.REF_LAT;
/**
* Zamienia długość geograficzną w systemie WGS-84 na współrzędna x klasy {@link Grid}.
*
* @param lon długość geograficzna
* @return współrzędna x klasy GridCoord
*/
public static int convertLonToGridX2(double lon) {
double xx = (lon + REF_LON_OFFSET) * INVERT_SS_DELTA_LON;
return (int) xx;
}
/**
* Zamienia szerokość geograficzną w systemie WGS-84 na współrzędna y klasy {@link Grid}.
*
* @param lat szerokość geograficzna
* @return współrzędna y klasy GridCoord
*/
public static int convertLatToGridY2(double lat) {
double yy = (lat + REF_LAT_OFFSET) * INVERT_SS_DELTA_LAT;
return (int) yy;
}
/** /**
* Funkcja zamienia dlugosc geog. xms w milisekundach na IdKwadrat.x. * Funkcja zamienia dlugosc geog. xms w milisekundach na IdKwadrat.x.
* *
@@ -286,7 +309,7 @@ public class Coord {
// wspolrzedne geograficzne w milisekundach zawieraja sie w zakresie: // wspolrzedne geograficzne w milisekundach zawieraja sie w zakresie:
// 0 <= x < 360 dlugosc geograficzna // 0 <= x < 360 dlugosc geograficzna
// 0 <= y <= 180 szerokosc geograficzna // 0 <= y <= 180 szerokosc geograficzna
if ((xms < 0) || (xms >= 360 * MapConsts.DEG_MS)) { if (xms >= MapConsts.ANGLE_360_MS) {
// poza zakresem // poza zakresem
return -1; return -1;
} }
@@ -304,7 +327,7 @@ public class Coord {
// return -1; // return -1;
// } // }
// indeksowanie kwadratow pola walki zaczyna sie od (0, 0) // indeksowanie kwadratow pola walki zaczyna sie od (0, 0)
double xx = (x - MapConsts.X_REF_MS) * ODWROT_SS_DX_MS; double xx = (x - MapConsts.X_REF_MS) * INVERT_SS_DELTA_LON_MS;
// x = (x - MapConsts.X_REF_MS) / MapConsts.SS_DX_MS; // x = (x - MapConsts.X_REF_MS) / MapConsts.SS_DX_MS;
return (int) xx; return (int) xx;
} }
@@ -324,13 +347,13 @@ public class Coord {
return -1; return -1;
} }
// indeksowanie kwadratow pola walki zaczyna sie od (0, 0) // indeksowanie kwadratow pola walki zaczyna sie od (0, 0)
double yy = (yms - MapConsts.Y_REF_MS) * ODWROT_SS_DY_MS; double yy = (yms - MapConsts.Y_REF_MS) * INVERT_SS_DELTA_LAT_MS;
// long y = (yms - MapConsts.Y_REF_MS) / MapConsts.SS_DY_MS; // long y = (yms - MapConsts.Y_REF_MS) / MapConsts.SS_DY_MS;
return (int) yy; return (int) yy;
} }
private static final double ODWROT_SS_DX_MS = 1.0 / MapConsts.SS_DX_MS; private static final double INVERT_SS_DELTA_LON_MS = 1.0 / MapConsts.SS_DELTA_LON_MS;
private static final double ODWROT_SS_DY_MS = 1.0 / MapConsts.SS_DY_MS; private static final double INVERT_SS_DELTA_LAT_MS = 1.0 / MapConsts.SS_DELTA_LAT_MS;
/** /**
* Funkcja służy do konwersji współrzednych elipsoidalnych WGS84 (lat/lon) na płaskie X-northing, Y-easting * Funkcja służy do konwersji współrzednych elipsoidalnych WGS84 (lat/lon) na płaskie X-northing, Y-easting
@@ -347,8 +370,8 @@ public class Coord {
puwgCoord.northing = 999999999999999.0; puwgCoord.northing = 999999999999999.0;
return; return;
} }
double latRad = lat * DEG_2_RAD; double latRad = Math.toRadians(lat);
double dlam = (lon - 19.0) * DEG_2_RAD; double dlam = Math.toRadians(lon - 19.0);
double dlam_pow_2 = dlam * dlam; double dlam_pow_2 = dlam * dlam;
double dlam_pow_3 = dlam_pow_2 * dlam; double dlam_pow_3 = dlam_pow_2 * dlam;
double dlam_pow_4 = dlam_pow_3 * dlam; double dlam_pow_4 = dlam_pow_3 * dlam;
@@ -373,22 +396,14 @@ public class Coord {
double sns = sn * s; double sns = sn * s;
t2 = sns * c * OK / 2.0; t2 = sns * c * OK / 2.0;
t3 = sns * c_pow_3 * OK * (5.0 - t_pow_2 + 9.0 * eta + 4.0 * eta_pow_2) / 24.0; t3 = sns * c_pow_3 * OK * (5.0 - t_pow_2 + 9.0 * eta + 4.0 * eta_pow_2) / 24.0;
t4 = sns * c_pow_4 * c * OK * (61.0 - 58.0 * t_pow_2 + t_pow_4 t4 = sns * c_pow_4 * c * OK * (61.0 - 58.0 * t_pow_2 + t_pow_4 + 270.0 * eta - 330.0 * t_pow_2 * eta + 445.0 * eta_pow_2 + 324.0 * eta_pow_3 - 680.0 * t_pow_2 * eta_pow_2 + 88.0 * eta_pow_4 - 600.0 * t_pow_2 * eta_pow_3 - 192.0 * t_pow_2 * eta_pow_4) / 720.0;
+ 270.0 * eta - 330.0 * t_pow_2 * eta + 445.0 * eta_pow_2 t5 = sns * c_pow_4 * c_pow_3 * OK * (1385.0 - 3111.0 * t_pow_2 + 543.0 * t_pow_4 - t_pow_5 * t) / 40320.0;
+ 324.0 * eta_pow_3 - 680.0 * t_pow_2 * eta_pow_2 puwgCoord.northing = -5300000.0 + t1 + dlam_pow_2 * t2 + dlam_pow_4 * t3 + dlam_pow_4 * dlam_pow_2 * t4 + dlam_pow_4 * dlam_pow_4 * t5;
+ 88.0 * eta_pow_4 - 600.0 * t_pow_2 * eta_pow_3 - 192.0 * t_pow_2 * eta_pow_4) / 720.0;
t5 = sns * c_pow_4 * c_pow_3 * OK * (1385.0 - 3111.0 * t_pow_2
+ 543.0 * t_pow_4 - t_pow_5 * t) / 40320.0;
puwgCoord.northing = -5300000.0 + t1 + dlam_pow_2 * t2 + dlam_pow_4 * t3
+ dlam_pow_4 * dlam_pow_2 * t4 + dlam_pow_4 * dlam_pow_4 * t5;
t1 = sn * c * OK; t1 = sn * c * OK;
t2 = sn * c_pow_3 * OK * (1.0 - t_pow_2 + eta) / 6.0; t2 = sn * c_pow_3 * OK * (1.0 - t_pow_2 + eta) / 6.0;
t3 = sn * c_pow_4 * c * OK * (5.0 - 18.0 * t_pow_2 + t_pow_4 + 14.0 * eta t3 = sn * c_pow_4 * c * OK * (5.0 - 18.0 * t_pow_2 + t_pow_4 + 14.0 * eta - 58.0 * t_pow_2 * eta + 13.0 * eta_pow_2 + 4.0 * eta_pow_3 - 64.0 * t_pow_2 * eta_pow_2 - 24.0 * t_pow_2 * eta_pow_3) / 120.0;
- 58.0 * t_pow_2 * eta + 13.0 * eta_pow_2 + 4.0 * eta_pow_3
- 64.0 * t_pow_2 * eta_pow_2 - 24.0 * t_pow_2 * eta_pow_3) / 120.0;
t4 = sn * c_pow_4 * c_pow_3 * OK * (61.0 - 479.0 * t_pow_2 + 179.0 * t_pow_4 - t_pow_5 * t) / 5040.0; t4 = sn * c_pow_4 * c_pow_3 * OK * (61.0 - 479.0 * t_pow_2 + 179.0 * t_pow_4 - t_pow_5 * t) / 5040.0;
puwgCoord.easting = 500000.0 + dlam * t1 + dlam_pow_3 * t2 puwgCoord.easting = 500000.0 + dlam * t1 + dlam_pow_3 * t2 + dlam_pow_4 * dlam * t3 + dlam_pow_4 * dlam_pow_3 * t4;// + 0.5;
+ dlam_pow_4 * dlam * t3 + dlam_pow_4 * dlam_pow_3 * t4;// + 0.5;
} }
/** /**
@@ -431,31 +446,23 @@ public class Coord {
double t0, t1, t2, t3; double t0, t1, t2, t3;
t0 = t / (2.0 * sr * sn * OK_POW_2); t0 = t / (2.0 * sr * sn * OK_POW_2);
t1 = 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_POW_4); t1 = 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_POW_4);
t2 = 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 t2 = 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_POW_6);
+ 100.0 * eta_pow_3 - 66.0 * t_pow_2 * eta_pow_2 - 90.0 * t_pow_4 * eta + 88.0 * eta_pow_4 t3 = t * (1385.0 + 3633.0 * t_pow_2 + 4095.0 * t_pow_4 + 1575.0 * t_pow_6) / (40320.0 * sr * sn_pow_7 * (OK_POW_8));
+ 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_POW_6); double latrad = ftphi - de_pow_2 * t0 + de_pow_4 * t1 - de_pow_3 * de_pow_3 * t2 + de_pow_4 * de_pow_3 * t3;
t3 = t * (1385.0 + 3633 * t_pow_2 + 4095.0 * t_pow_4 + 1575.0 * t_pow_6) / (40320 * sr * sn_pow_7 * (OK_POW_8));
geoCoord.lat = ftphi - de_pow_2 * t0 + de_pow_4 * t1 - de_pow_3 * de_pow_3 * t2 + de_pow_4 * de_pow_3 * t3;
t0 = 1.0 / (sn * c * OK); t0 = 1.0 / (sn * c * OK);
t1 = (1.0 + 2.0 * t_pow_2 + eta) / (6.0 * sn_pow_3 * c * (OK_POW_3)); t1 = (1.0 + 2.0 * t_pow_2 + eta) / (6.0 * sn_pow_3 * c * (OK_POW_3));
t2 = (5.0 + 6.0 * eta + 28.0 * t_pow_2 - 3.0 * eta_pow_2 + 8.0 * t_pow_2 * eta t2 = (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_POW_5));
+ 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_POW_5));
t3 = (61.0 + 662.0 * t_pow_2 + 1320.0 * t_pow_4 + 720.0 * t_pow_6) / (5040.0 * sn_pow_7 * c * OK_POW_7); t3 = (61.0 + 662.0 * t_pow_2 + 1320.0 * t_pow_4 + 720.0 * t_pow_6) / (5040.0 * sn_pow_7 * c * OK_POW_7);
double dlam = de * t0 - de_pow_3 * t1 + de_pow_3 * de_pow_2 * t2 - de_pow_3 * de_pow_4 * t3; double dlam = de * t0 - de_pow_3 * t1 + de_pow_3 * de_pow_2 * t2 - de_pow_3 * de_pow_4 * t3;
// 19.0 * DEG_2_RAD == 0.33161255787892263; // 19.0 * DEG_2_RAD == 0.33161255787892263;
// geoCoord.lon = 0.33161255787892263 + dlam; // geoCoord.lon = 0.33161255787892263 + dlam;
// geoCoord.lon *= RAD_2_DEG; // geoCoord.lon *= RAD_2_DEG;
geoCoord.lon = dlam * RAD_2_DEG; geoCoord.lon = Math.toDegrees(dlam) + 19.0;
geoCoord.lon += 19.0; geoCoord.lat = Math.toDegrees(latrad);
geoCoord.lat *= RAD_2_DEG;
} }
//////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////
// Funkcje pomocnicze i stałe // Funkcje pomocnicze i stałe
/// /////////////////////////////////////////////////////////////////////////////
static double calculateESquared(double a, double b) { static double calculateESquared(double a, double b) {
a *= a; a *= a;
b *= b; b *= b;
@@ -484,13 +491,9 @@ public class Coord {
} }
static double sphtmd(double sphi) { static double sphtmd(double sphi) {
return (AP * sphi) - (BP * Math.sin(2.0 * sphi)) + (CP * Math.sin(4.0 * 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));
- (DP * Math.sin(6.0 * sphi)) + (EP * Math.sin(8.0 * sphi));
} }
private static final double DEG_2_RAD = Math.PI / 180.0;
private static final double RAD_2_DEG = 180.0 / Math.PI;
/** /**
* Dlługość dużej półsi, w metrach dla elipsoidy WGS-84. * Dlługość dużej półsi, w metrach dla elipsoidy WGS-84.
*/ */

View File

@@ -1,158 +0,0 @@
package pl.wat.ms4ds.terrain;
public class CoordConversion {
/*
Opis:
konwersja wspolrzednych z ukladu WGS 84 do ukladu PUWG 1992
Parametry:
B_stopnie - szerokosc geograficzna wyrazona w stopniach
L_stopnie - dlugosc geograficzna wyrazona w stopniach
Xpuwg - wskazanie na wspolrzedna X ukladu PUWG 1992 (UWAGA - wspolrzedna pionowa)
Ypuwg - wskazanie na wspolrzedna Y ukladu PUWG 1992 (UWAGA - wspolrzedna pozioma)
Zwracana wartosc:
0 - konwersja powiodla sie
1 - szerokosc geograficzna B poza zakresem
2 - dlugosc geograficzna L poza zakresem
*/
public static int wgs84ToPuwg1992(double B_stopnie, double L_stopnie) {
double Xpuwg;
double Ypuwg;
// Parametry elipsoidy GRS-80
double e = 0.0818191910428; //pierwszymimo¶ród elipsoidy
double R0 = 6367449.14577; //promieñ sfery Lagrange.a
double Snorm = 2.0E-6; //parametr normuj±cy
double xo = 5760000.0; //parametr centruj±cy
//Wspolczynniki wielomianu
double a0 = 5765181.11148097;
double a1 = 499800.81713800;
double a2 = -63.81145283;
double a3 = 0.83537915;
double a4 = 0.13046891;
double a5 = -0.00111138;
double a6 = -0.00010504;
// Parametry odwzorowania Gaussa-Kruegera dla uk³adu PUWG92
double L0_stopnie = 19.0; //Pocz±tek uk³adu wsp. PUWG92 (d³ugo¶æ)
double m0 = 0.9993;
double x0 = -5300000.0;
double y0 = 500000.0;
// Zakres stosowalnosci metody
double Bmin = 48.0 * Math.PI / 180.0;
double Bmax = 56.0 * Math.PI / 180.0;
double dLmin = -6.0 * Math.PI / 180.0;
double dLmax = 6.0 * Math.PI / 180.0;
// Weryfikacja danych wejsciowych
double B = B_stopnie * Math.PI / 180.0;
double dL_stopnie = L_stopnie - L0_stopnie;
double dL = dL_stopnie * Math.PI / 180.0;
if ((B < Bmin) || (B > Bmax))
return 1;
if ((dL < dLmin) || (dL > dLmax))
return 2;
//etap I - elipsoida na kulê
double U = 1.0 - e * Math.sin(B);
double V = 1.0 + e * Math.sin(B);
double K = Math.pow((U / V), (e / 2.0));
double C = K * Math.tan(B / 2.0 + Math.PI / 4.0);
double fi = 2.0 * Math.atan(C) - Math.PI / 2.0;
double d_lambda = dL;
// etap II - kula na walec
double p = Math.sin(fi);
double q = Math.cos(fi) * Math.cos(d_lambda);
double r = 1.0 + Math.cos(fi) * Math.sin(d_lambda);
double s = 1.0 - Math.cos(fi) * Math.sin(d_lambda);
double XMERC = R0 * Math.atan(p / q);
double YMERC = 0.5 * R0 * Math.log(r / s);
// //etap III - walec na p³aszczyznê
// complex<double> Z ((XMERC - xo) * Snorm, YMERC * Snorm);
// complex<double> Zgk;
// Zgk = a0 + Z * (a1 + Z * (a2 + Z * (a3 + Z * (a4 + Z * (a5 + Z * a6)))));
// double Xgk = Zgk.real();
// double Ygk = Zgk.imag();
//
// //Przej¶cie do uk³adu aplikacyjnego
// Xpuwg = m0 * Xgk + x0;
// Ypuwg = m0 * Ygk + y0;
return 0;
}
/*
Opis:
konwersja wspolrzednych z ukladu PUWG 1992 do ukladu WGS 84
Parametry:
Xpuwg - wskazanie na wspolrzedna X ukladu PUWG 1992 (UWAGA - wspolrzedna pionowa)
Ypuwg - wskazanie na wspolrzedna Y ukladu PUWG 1992 (UWAGA - wspolrzedna pozioma)
B_stopnie - szerokosc geograficzna wyrazona w stopniach
L_stopnie - dlugosc geograficzna wyrazona w stopniach
Zwracana wartosc:
0 - konwersja powiodla sie
*/
public static int puwg1992ToWgs84(double Xpuwg, double Ypuwg, double B_stopnie, double L_stopnie) {
double L0_stopnie = 19.0; //Pocz±tek uk³adu wsp. PUWG92 (d³ugo¶æ)
double m0 = 0.9993;
double x0 = -5300000.0;
double y0 = 500000.0;
double R0 = 6367449.14577; //promieñ sfery Lagrange.a
double Snorm = 2.0E-6; //parametr normuj±cy
double xo_prim = 5765181.11148097; //parametr centruj±cy
// Wspolczynniki wielomianu
double b0 = 5760000;
double b1 = 500199.26224125;
double b2 = 63.88777449;
double b3 = -0.82039170;
double b4 = -0.13125817;
double b5 = 0.00101782;
double b6 = 0.00010778;
// Wspolczynniki szeregu tryg.
double c2 = 0.0033565514856;
double c4 = 0.0000065718731;
double c6 = 0.0000000176466;
double c8 = 0.0000000000540;
//Przejscie z ukladu aplikacyjnego
double Xgk, Ygk;
Xgk = (Xpuwg - x0) / m0;
Ygk = (Ypuwg - y0) / m0;
// //etap I - (Xgk, Ygk) -> (Xmerc, Ymerc)
// complex<double> Z ((Xgk - xo_prim) * Snorm, Ygk * Snorm);
// complex<double> Zmerc;
//
// Zmerc = b0 + Z * (b1 + Z * (b2 + Z * (b3 + Z * (b4 + Z * (b5 + Z * b6)))));
//
// double Xmerc = Zmerc.real();
// double Ymerc = Zmerc.imag();
//
// //etap II - Xmerc,Ymerc -> fi, delta_lambda
// double alfa = Xmerc / R0;
// double beta = Ymerc / R0;
//
// double w = 2.0 * atan(exp(beta)) - M_PI / 2.0;
// double fi = asin(cos(w) * sin(alfa));
// double d_lambda = atan(tan(w) / cos(alfa));
//
// //etap III
// double B = fi + c2 * sin(2.0 * fi) + c4 * sin(4.0 * fi) + c6 * sin(6.0 * fi) + c8 * sin(8.0 * fi);
// double dL = d_lambda;
//
// //Obliczenia koncowe
// *B_stopnie = B / M_PI * 180.0;
// double dL_stopnie = dL / M_PI * 180.0;
// *L_stopnie = dL_stopnie + L0_stopnie;
return 0;
}
}

View File

@@ -7,7 +7,7 @@ class EmptyBigSquare extends BigSquare {
private EmptyBigSquare() { private EmptyBigSquare() {
} }
Square getKwadrat(int ssX, int ssY) { Square getSquare(int ssX, int ssY) {
return Square.EMPTY; return Square.EMPTY;
} }
} }

View File

@@ -1,19 +0,0 @@
package pl.wat.ms4ds.terrain;
/**
*
*/
public class GeoCoord {
public double lat;
public double lon;
public GeoCoord() {}
public GeoCoord(double lat, double lon) {
this.lat = lat;
this.lon = lon;
}
public GeoCoord(GeoCoord other) {
lat = other.lat;
lon = other.lon;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -12,28 +12,27 @@ public final class MapConsts {
private static final Logger LOGGER = LoggerFactory.getLogger(MapConsts.class); private static final Logger LOGGER = LoggerFactory.getLogger(MapConsts.class);
/** /**
* Umowny uklad odniesienia dla lokalizacji geograficznej: <p> * Długość geograficzna referencyjna początku umownego układu współrzędnych w postaci siatki kwadratów. <p>
* Długość geograficzna (wsp. X) przyjmuje wartości: [0, 360) odpowiadające [-180, 180]<p> * Wartości długości geograficznej mapowane są: [-180, 180) -> [0, 360).
* Szerokość geograficzna (wsp. Y) przyjmuje wartości: [0, 180] odpowadające [-90, 90]
*/ */
public static final int X_REF; public static final int REF_LON;
/** /**
* Umowny uklad odniesienia dla lokalizacji geograficznej: <p> * Szerokość geograficzna referencyjna początku umownego układu współrzędnych w postaci siatki kwadratów. <p>
* Długość geograficzna (wsp. X) przyjmuje wartości: [0, 360) odpowiadające [-180, 180]<p> * Wartości szerokości geograficznej mapowane są: [-90, 90] -> [0, 180].
* Szerokość geograficzna (wsp. Y) przyjmuje wartości: [0, 180] odpowadające [-90, 90]
*/ */
public static final int Y_REF; public static final int REF_LAT;
public static final int DX_REF;
public static final int DY_REF;
public static final String KWADRATY_DIR; public static final int DELTA_LON_REF;
public static final int DELTA_LAT_REF;
public static final String DATA_DIR;
/** /**
* Nazwa pliku z konfiguracja mechanizmu odpowiedzialnego za transfer. Plik * Nazwa pliku z konfiguracja mechanizmu odpowiedzialnego za transfer. Plik
* musi znajdowac sie w katalogu glownym aplikacji, ewentualnie musi tu byc * musi znajdowac sie w katalogu glownym aplikacji, ewentualnie musi tu byc
* podana sciezka bezwzgledna do niego. * podana sciezka bezwzgledna do niego.
*/ */
private static final String PLIK_Z_USTAWIENIAMI = "teren.properties"; private static final String PROPERTIES_FILE = "teren.properties";
/** /**
* Dlugosc boku duzego kwadratu na osi OX w liczbie malych kwadratow. * Dlugosc boku duzego kwadratu na osi OX w liczbie malych kwadratow.
@@ -50,15 +49,15 @@ public final class MapConsts {
/** /**
* Powierzchnia malego kwadratu w metrach. * Powierzchnia malego kwadratu w metrach.
*/ */
public static final int POW_MK; public static final int SS_AREA;
/** /**
* Szerokość małego kwadratu w stopniach. * Szerokość małego kwadratu w stopniach.
*/ */
public static final double DELTA_X; public static final double SS_DELTA_LON;
/** /**
* Wysokość małego kwadratu w stopniach. * Wysokość małego kwadratu w stopniach.
*/ */
public static final double DELTA_Y; public static final double SS_DELTA_LAT;
/** /**
* Liczba duzych kwadratow na stopien geograficzny po osi OX (dlugosc geograficzna). * Liczba duzych kwadratow na stopien geograficzny po osi OX (dlugosc geograficzna).
*/ */
@@ -70,30 +69,29 @@ public final class MapConsts {
/** /**
* Szerokość duzych kwadratow w stopniach geograficznych po osi OX (dlugosc geograficzna). * Szerokość duzych kwadratow w stopniach geograficznych po osi OX (dlugosc geograficzna).
*/ */
public static final double BS_DX; public static final double BS_DELTA_LON;
/** /**
* Wysokość duzych kwadratow w stopniach geograficznych po osi OY (szerokosc geograficzna). * Wysokość duzych kwadratow w stopniach geograficznych po osi OY (szerokosc geograficzna).
*/ */
public static final double BS_DY; public static final double BS_DELTA_LAT;
/** /**
* Szerokości geograficzne środków kwadratów. * Szerokości geograficzne środków kwadratów.
*/ */
static final double[] LATS; static final double[] SS_LATS;
/** /**
* Długości geograficzne środków kwadratów. * Długości geograficzne środków kwadratów.
*/ */
static final double[] LONS; static final double[] SS_LONS;
static Properties ustawienia; static Properties properties;
static { static {
String propertiesFileName = System.getProperty("user.dir") + "\\" + PLIK_Z_USTAWIENIAMI; String propertiesFileName = System.getProperty("user.dir") + "\\" + PROPERTIES_FILE;
ustawienia = new Properties(); properties = new Properties();
try { try {
LOGGER.debug("Odczyt ustawien z pliku: {}.", propertiesFileName); LOGGER.debug("Odczyt ustawien z pliku: {}.", propertiesFileName);
ustawienia.load(new FileInputStream(propertiesFileName)); properties.load(new FileInputStream(propertiesFileName));
} catch (IOException e) { } catch (IOException e) {
LOGGER.error("Brak pliku z ustawieniami."); LOGGER.error("Brak pliku z ustawieniami.");
throw new RuntimeException(e); throw new RuntimeException(e);
@@ -101,14 +99,16 @@ public final class MapConsts {
// przesuniecie o 180 stop. // przesuniecie o 180 stop.
// poludnik zerowy ma wartosc 180, zatem wspolrzedne zachodnie (ujemne) zawierają sie w <0, 180) // poludnik zerowy ma wartosc 180, zatem wspolrzedne zachodnie (ujemne) zawierają sie w <0, 180)
// wspolrzedne wschodnie (nieujemne) zawieraja sie w przedziale <180, 360) // wspolrzedne wschodnie (nieujemne) zawieraja sie w przedziale <180, 360)
X_REF = Integer.parseInt(ustawienia.getProperty("x_ref")) + 180; REF_LON = Integer.parseInt(properties.getProperty("x_ref")) + 180;
// przesuniecie o 90 stop. // przesuniecie o 90 stop.
// rownik ma wartosc 90, zatem wspolrzedne poludniowe (ujemne) zawierają sie w <0, 90) // rownik ma wartosc 90, zatem wspolrzedne poludniowe (ujemne) zawierają sie w <0, 90)
// wspolrzedne polnocne (nieujemne) zawieraja sie w przedziale <90, 180> // wspolrzedne polnocne (nieujemne) zawieraja sie w przedziale <90, 180>
Y_REF = Integer.parseInt(ustawienia.getProperty("y_ref")) + 90; REF_LAT = Integer.parseInt(properties.getProperty("y_ref")) + 90;
DX_REF = Integer.parseInt(ustawienia.getProperty("dx_ref")); DELTA_LON_REF = Integer.parseInt(properties.getProperty("dx_ref"));
DY_REF = Integer.parseInt(ustawienia.getProperty("dy_ref")); DELTA_LAT_REF = Integer.parseInt(properties.getProperty("dy_ref"));
String val = ustawienia.getProperty("dl_mk"); double BS_X_NUM = DELTA_LON_REF / BS_PER_DEG_X;
double BS_Y_NUM = DELTA_LAT_REF / BS_PER_DEG_Y;
String val = properties.getProperty("dl_mk");
switch (val) { switch (val) {
case "20": case "20":
SS_SIZE = 20; SS_SIZE = 20;
@@ -126,50 +126,50 @@ public final class MapConsts {
SS_SIZE = 200; SS_SIZE = 200;
break; break;
} }
POW_MK = SS_SIZE * SS_SIZE; SS_AREA = SS_SIZE * SS_SIZE;
if (SS_SIZE == 20) { if (SS_SIZE == 20) {
SS_PER_BS_X = 83 * 10; SS_PER_BS_X = 83 * 10;
SS_PER_BS_Y = 93 * 10; SS_PER_BS_Y = 93 * 10;
DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); SS_DELTA_LON = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X);
DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); SS_DELTA_LAT = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y);
KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "20m/"; DATA_DIR = properties.getProperty("kwadraty_dir") + "20m/";
} else if (SS_SIZE == 25) { } else if (SS_SIZE == 25) {
SS_PER_BS_X = 83 * 8; SS_PER_BS_X = 83 * 8;
SS_PER_BS_Y = 93 * 8; SS_PER_BS_Y = 93 * 8;
DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); SS_DELTA_LON = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X);
DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); SS_DELTA_LAT = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y);
KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "25m/"; DATA_DIR = properties.getProperty("kwadraty_dir") + "25m/";
} else if (SS_SIZE == 50) { } else if (SS_SIZE == 50) {
SS_PER_BS_X = 83 * 4; SS_PER_BS_X = 83 * 4;
SS_PER_BS_Y = 93 * 4; SS_PER_BS_Y = 93 * 4;
DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); SS_DELTA_LON = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X);
DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); SS_DELTA_LAT = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y);
KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "50m/"; DATA_DIR = properties.getProperty("kwadraty_dir") + "50m/";
} else if (SS_SIZE == 100) { } else if (SS_SIZE == 100) {
SS_PER_BS_X = 83 * 2; SS_PER_BS_X = 83 * 2;
SS_PER_BS_Y = 93 * 2; SS_PER_BS_Y = 93 * 2;
DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); SS_DELTA_LON = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X);
DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); SS_DELTA_LAT = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y);
KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "100m/"; DATA_DIR = properties.getProperty("kwadraty_dir") + "100m/";
} else { } else {
// domyslnie dlugosc kwadratu 200m // domyslnie dlugosc kwadratu 200m
SS_PER_BS_X = 83; SS_PER_BS_X = 83;
SS_PER_BS_Y = 93; SS_PER_BS_Y = 93;
DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); SS_DELTA_LON = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X);
DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); SS_DELTA_LAT = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y);
KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "200m/"; DATA_DIR = properties.getProperty("kwadraty_dir") + "200m/";
} }
BS_DX = 1.0 / (double) BS_PER_DEG_X; BS_DELTA_LON = 1.0 / (double) BS_PER_DEG_X;
BS_DY = 1.0 / (double) BS_PER_DEG_Y; BS_DELTA_LAT = 1.0 / (double) BS_PER_DEG_Y;
LONS = new double[DX_REF * BS_PER_DEG_X * SS_PER_BS_X]; SS_LONS = new double[DELTA_LON_REF * BS_PER_DEG_X * SS_PER_BS_X];
for (int i = 0; i < LONS.length; i++) { for (int i = 0; i < SS_LONS.length; i++) {
LONS[i] = X_REF + DELTA_X * (i + 0.5); SS_LONS[i] = REF_LON + SS_DELTA_LON * (i + 0.5);
} }
LATS = new double[DY_REF * BS_PER_DEG_Y * SS_PER_BS_Y]; SS_LATS = new double[DELTA_LAT_REF * BS_PER_DEG_Y * SS_PER_BS_Y];
for (int i = 0; i < LATS.length; i++) { for (int i = 0; i < SS_LATS.length; i++) {
LATS[i] = Y_REF + DELTA_Y * (i + 0.5); SS_LATS[i] = REF_LAT + SS_DELTA_LAT * (i + 0.5);
} }
LOGGER.debug("Wczytane ustawienia:\n \tLON_REF={}, LAT_REF={}, DX_REF={}, DY_REF{}, SQUARE_SIZE={}, GRID_SIZE={}x{}, DATA_DIR={}", X_REF, Y_REF, DX_REF, DY_REF, SS_SIZE, LONS.length, LATS.length, KWADRATY_DIR); LOGGER.debug("Wczytane ustawienia:\n \tLON_REF={}, LAT_REF={}, DX_REF={}, DY_REF{}, SQUARE_SIZE={}, GRID_SIZE={}x{}, DATA_DIR={}", REF_LON, REF_LAT, DELTA_LON_REF, DELTA_LAT_REF, SS_SIZE, SS_LONS.length, SS_LATS.length, DATA_DIR);
} }
/** /**
@@ -179,7 +179,7 @@ public final class MapConsts {
/** /**
* Liczba milisekund na 360 stopni. * Liczba milisekund na 360 stopni.
*/ */
public static final long ANGLE_360_MS = 3600000 * 360; public static final long ANGLE_360_MS = DEG_MS * 360;
/** /**
* Wielkosc cache'u pola walki (liczba duzych kwadratow trzymanych w RAM). * Wielkosc cache'u pola walki (liczba duzych kwadratow trzymanych w RAM).
*/ */
@@ -191,7 +191,7 @@ public final class MapConsts {
* @return * @return
*/ */
public static int getX_REF() { public static int getX_REF() {
return X_REF; return REF_LON;
} }
/** /**
@@ -200,7 +200,7 @@ public final class MapConsts {
* @return * @return
*/ */
public static int getY_REF() { public static int getY_REF() {
return Y_REF; return REF_LAT;
} }
/** /**
@@ -209,7 +209,7 @@ public final class MapConsts {
* @return * @return
*/ */
public static int getDX_REF() { public static int getDX_REF() {
return DX_REF; return DELTA_LON_REF;
} }
/** /**
@@ -218,28 +218,28 @@ public final class MapConsts {
* @return * @return
*/ */
public static int getDY_REF() { public static int getDY_REF() {
return DY_REF; return DELTA_LAT_REF;
} }
/** /**
* Dlugosci bokow malego kwadratu w milisekundach geograficznych po osi OX (dlugosc geograficzna). * Dlugosci bokow malego kwadratu w milisekundach geograficznych po osi OX (dlugosc geograficzna).
*/ */
public static final double SS_DX_MS = DELTA_X * DEG_MS; public static final double SS_DELTA_LON_MS = SS_DELTA_LON * DEG_MS;
/** /**
* Dlugosci bokow malego kwadratu w milisekundach geograficznych po osi OY (szerokosc geograficzna). * Dlugosci bokow malego kwadratu w milisekundach geograficznych po osi OY (szerokosc geograficzna).
*/ */
public static final double SS_DY_MS = DELTA_Y * DEG_MS; public static final double SS_DELTA_LAT_MS = SS_DELTA_LAT * DEG_MS;
// wspolrzedne dolnego lewego rogu mapy w ms // wspolrzedne dolnego lewego rogu mapy w ms
// wspolrzedne geograficzne w milisekundach zawieraja sie w zakresie: // wspolrzedne geograficzne w milisekundach zawieraja sie w zakresie:
// 0 <= x < 360 dlugosc geograficzna // 0 <= x < 360 dlugosc geograficzna
// 0 <= y <= 180 szerokosc geograficzna // 0 <= y <= 180 szerokosc geograficzna
public static final int X_REF_MS = X_REF * DEG_MS; public static final int X_REF_MS = REF_LON * DEG_MS;
public static final int Y_REF_MS = Y_REF * DEG_MS; public static final int Y_REF_MS = REF_LAT * DEG_MS;
public static final int DX_REF_MS = DEG_MS * DX_REF; // szerokosc pola walki w stopniach public static final int DX_REF_MS = DEG_MS * DELTA_LON_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 DY_REF_MS = DEG_MS * DELTA_LAT_REF; // wysokosc polwa walki w stopniach
public static final int BS_DX_MS = (int) (BS_DX * DEG_MS); public static final int BS_DX_MS = (int) (BS_DELTA_LON * DEG_MS);
public static final int BS_DY_MS = (int) (BS_DY * DEG_MS); public static final int BS_DY_MS = (int) (BS_DELTA_LAT * DEG_MS);
/** /**
* Liczba malych kwadratow przypadajaca na bok arkusza mapy drogowej. * Liczba malych kwadratow przypadajaca na bok arkusza mapy drogowej.

View File

@@ -2,7 +2,7 @@ package pl.wat.ms4ds.terrain;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pl.wat.ms4ds.terrain.konwersja.CoordUtils; import pl.wat.ms4ds.terrain.nmt.NmtDataGenerator;
import java.io.*; import java.io.*;
@@ -12,42 +12,11 @@ public class RightBigSquare extends BigSquare {
private Square[][] squares; private Square[][] squares;
Square getKwadrat(int ssX, int ssY) { Square getSquare(int ssX, int ssY) {
return squares[ssX][ssY]; return squares[ssX][ssY];
} }
static final int NORTH = 0; public RightBigSquare() {
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;
public void saveToFile(String dir) throws IOException {
// Utworzenie katalogów, gdyby nie istniały.
File directory = new File(dir);
directory.mkdirs();
String path = dir + fileName + ".bin";
Square.RawData ss = new Square.RawData();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path));
for (int x = 0; x < squares.length; x++) {
for (int y = 0; y < squares[0].length; y++) {
ss.read(squares[x][y]);
ss.write(out);
}
}
out.close();
logger.debug("Zapisano nowy plik mapy: {}.", path);
} }
/** /**
@@ -61,10 +30,10 @@ public class RightBigSquare extends BigSquare {
if (newDir != null) { if (newDir != null) {
fn = newDir + fileName + ".bin"; fn = newDir + fileName + ".bin";
} else { } else {
fn = MapConsts.KWADRATY_DIR + fileName + ".bin"; fn = MapConsts.DATA_DIR + fileName + ".bin";
} }
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fn)); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fn));
byte[] buf = new byte[9 * 256]; byte[] buf = new byte[10 * 256];
int offset = 0; int offset = 0;
for (int x = 0; x < squares.length; x++) { for (int x = 0; x < squares.length; x++) {
for (int y = 0; y < squares[0].length; y++) { for (int y = 0; y < squares[0].length; y++) {
@@ -83,199 +52,37 @@ public class RightBigSquare extends BigSquare {
logger.debug("Zapisano plik mapy: {}", fn); logger.debug("Zapisano plik mapy: {}", fn);
} }
/** void readFromFile(String dir) throws IOException {
* Funkcja generuje nowy plik z danymi na podstawie danych z pliku referencyjnego (kwadraty o rozm. 100m). if (fileName == null) {
* <p>Nowy plik moze byc z danymi w innej skali (kwadraty o rozmiarach: 100m lub 50m).
*
* @param dir katalog docelowy dla nowego pliku
* @param dlmk rozmiar kwadratow generownych danych
* @throws IOException generowany wyjątek
*/
public void saveNewFileWithNewScale20m(String dir, int dlmk) throws IOException {
if (MapConsts.SS_SIZE != 100) {
// operacja tylko dla danych terenowych o kwadratach 200m
return; return;
} }
final int m = 5; try {
String s = "20m/"; String fullPath = dir + fileName + ".bin";
StringBuilder sb = new StringBuilder(100); BufferedInputStream in = new BufferedInputStream(new FileInputStream(fullPath), 2 * 8192);
sb.append(dir); byte[] buffer = new byte[10 * 512];
sb.append(s); int offset = 0;
// Utworzenie katalogów, gdyby nie istniały. int count = in.read(buffer);
File directory = new File(sb.toString()); squares = new Square[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y];
directory.mkdirs(); for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) {
sb.append(fileName);
sb.append(".bin");
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString()));
Square.RawData[][][][] ss_all = new Square.RawData[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++) {
Square.RawData[][] ss = new Square.RawData[m][m];
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
ss[i][j] = new Square.RawData();
}
}
ss_all[x][y] = ss;
// jest odcinek drogi na tym kierunku
if (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[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 (squares[x][y].stopienZalesienia > 0) {
hex = TerrainType.FOREST.ID;
} else if (squares[x][y].stopienZawodnienia > 0) {
hex = TerrainType.WATER.ID;
} else if (squares[x][y].stopienZabudowy > 0) {
hex = TerrainType.BUILDINGS.ID;
} else if (squares[x][y].stopienZabagnienia > 0) {
hex = TerrainType.SWAMP.ID;
}
ss[i][j].terrainType = (byte) hex;
// Konwersja [m] -> [0.25m]
ss[i][j].elevation = (short) (squares[x][y].wysokoscSrednia * 4);
}
}
}
}
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 y = 0; y < MapConsts.SS_PER_BS_Y; y++) {
for (int j = 0; j < m; j++) { Square kw = new Square(x, y);
ss_all[x][y][i][j].write(out); if (offset >= count) {
count = in.read(buffer);
offset = 0;
} }
offset = kw.readFromBuffer(buffer, offset);
squares[x][y] = kw;
} }
} }
in.close();
logger.debug("Doczytano plik mapy: {}", fullPath);
} catch (IOException e) {
squares = null;
throw e;
} }
out.close();
logger.debug("Zapisano nowy plik mapy: " + sb + " dla rozmiaru MK= " + dlmk);
} }
/** /**
* Generuje nowe, wyzerowane kwadraty w danej skali w nowym formacie. * Generuje nowe, wyzerowane kwadraty w danej skali w nowym formacie.
* *
@@ -283,60 +90,7 @@ public class RightBigSquare extends BigSquare {
* @param dlmk * @param dlmk
* @throws IOException * @throws IOException
*/ */
public void saveNewFileWithNewFormatWithElevetion(String dir, int dlmk) throws IOException { public void writeToFile_ElevationOnly(String dir, int dlmk) throws IOException {
if (MapConsts.SS_SIZE != 100) {
// operacja tylko dla danych terenowych o kwadratach 200m
return;
}
int m;
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);
Square.RawData ss = new Square.RawData();
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++) {
// Konwersja [m] -> [0.25m]
ss.elevation = (short) (squares[x][y].wysokoscSrednia * 4);
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
ss.write(out);
}
}
}
}
out.close();
logger.debug("Zapisano nowy plik mapy: {} dla rozmiaru MK= {}", sb, dlmk);
}
/**
* Generuje nowe, wyzerowane kwadraty w danej skali w nowym formacie.
*
* @param dir
* @param dlmk
* @throws IOException
*/
public void writeToFileOldToNewFormatWithElevetion(String dir, int dlmk) throws IOException {
if (MapConsts.SS_SIZE != 100) { if (MapConsts.SS_SIZE != 100) {
// operacja tylko dla danych terenowych o kwadratach 200m // operacja tylko dla danych terenowych o kwadratach 200m
return; return;
@@ -365,22 +119,22 @@ public class RightBigSquare extends BigSquare {
File directory = new File(sb.toString()); File directory = new File(sb.toString());
directory.mkdirs(); directory.mkdirs();
sb.append(fileName + ".bin"); sb.append(fileName + ".bin");
Square.RawData ss = new Square.RawData();
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(sb.toString())); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(sb.toString()));
byte[] buf = new byte[9 * 256]; byte[] buf = new byte[10 * 256];
int offset = 0; int offset = 0;
for (int x = 0; x < squares.length; x++) { for (int x = 0; x < squares.length; x++) {
for (int y = 0; y < squares[0].length; y++) { for (int i = 0; i < m; i++) {
Square square = squares[x][y]; for (int y = 0; y < squares[0].length; y++) {
square.elevation = square.wysokoscSrednia; Square square = squares[x][y];
if (square.elevation > 2660) { if (square.elevation > NmtDataGenerator.H_MAX) {
logger.warn("Elevation: {}, fn= {} ", square.elevation, fileName); logger.warn("Elevation: {}, fn= {}", square.elevation, fileName);
} }
for (int i = 0; i < m * m; i++) { for (int j = 0; j < m; j++) {
offset = square.writeToBuffer(buf, offset); offset = square.writeToBuffer_ElevationOnly(buf, offset);
if (offset >= buf.length) { if (offset >= buf.length) {
out.write(buf); out.write(buf);
offset = 0; offset = 0;
}
} }
} }
} }
@@ -392,7 +146,7 @@ public class RightBigSquare extends BigSquare {
logger.debug("Zapisano plik mapy: {}", fileName); logger.debug("Zapisano plik mapy: {}", fileName);
} }
public void saveFileFromNewToOldFormat(String dir) throws IOException { public void writeToFile_OldFormat(String dir) throws IOException {
StringBuilder sb = new StringBuilder(100); StringBuilder sb = new StringBuilder(100);
sb.append(dir); sb.append(dir);
// Utworzenie katalogów, gdyby nie istniały. // Utworzenie katalogów, gdyby nie istniały.
@@ -402,30 +156,28 @@ public class RightBigSquare extends BigSquare {
if (fileName.indexOf('.') < 0) { if (fileName.indexOf('.') < 0) {
sb.append(".bin"); sb.append(".bin");
} }
Square.RawData ss = new Square.RawData();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString())); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString()));
for (int x = 0; x < squares.length; x++) { for (int x = 0; x < squares.length; x++) {
for (int y = 0; y < squares[0].length; y++) { for (int y = 0; y < squares[0].length; y++) {
float f; Square square = squares[x][y];
int hex = 0;
int hex_s = 0; int hex_s = 0;
int hex_w = 0; int hex_w = 0;
int hex_b = 0; int hex_b = 0;
int hex_f = 0; int hex_f = 0;
switch (squares[x][y].terrainType) { switch (square.terrainType) {
// case 0, 1, 4: // case 0, 1, 4:
// hex = 0; // hex = 0;
// break; // break;
case 2: case SWAMP:
hex_s = 100; hex_s = 100;
break; break;
case 3: case WATER:
hex_w = 100; hex_w = 100;
break; break;
case 5: case BUILDINGS:
hex_b = 100; hex_b = 100;
break; break;
case 6: case FOREST:
hex_f = 100; hex_f = 100;
break; break;
default: default:
@@ -434,14 +186,15 @@ public class RightBigSquare extends BigSquare {
out.writeByte(hex_w); out.writeByte(hex_w);
out.writeByte(hex_b); out.writeByte(hex_b);
out.writeByte(hex_s); out.writeByte(hex_s);
int elevation = (int) squares[x][y].elevation; int elevation = (int) square.elevation;
out.writeInt(elevation); out.writeInt(elevation);
out.writeInt(squares[x][y].roznicaWzniesien); // Różnica wzniesień.
out.writeInt(0);
int bit_1; int bit_1;
hex = 0; int hex = 0;
bit_1 = 1; bit_1 = 1;
byte[] roads = squares[x][y].roads; byte[] roads = square.roads;
for (int i = 0; i < roads.length; i++) { for (int i = 0; i < 8; i++) {
// jest odcinek drogi na tym kierunku // jest odcinek drogi na tym kierunku
if (roads[i] > 0) { if (roads[i] > 0) {
hex |= bit_1; hex |= bit_1;
@@ -451,8 +204,8 @@ public class RightBigSquare extends BigSquare {
out.writeByte(hex); out.writeByte(hex);
hex = 0; hex = 0;
bit_1 = 1; bit_1 = 1;
byte[] watercourses = squares[x][y].watercourses; byte[] watercourses = square.watercourses;
for (int i = 0; i < watercourses.length; i++) { for (int i = 0; i < 8; i++) {
// jest odcinek przeszkody wodnej na tym kierunku // jest odcinek przeszkody wodnej na tym kierunku
if (watercourses[i] > 1) { if (watercourses[i] > 1) {
hex |= bit_1; hex |= bit_1;
@@ -462,7 +215,7 @@ public class RightBigSquare extends BigSquare {
out.writeByte(hex); out.writeByte(hex);
hex = 0; hex = 0;
bit_1 = 1; bit_1 = 1;
for (int i = 0; i < watercourses.length; i++) { for (int i = 0; i < 8; i++) {
// jest odcinek rowu na tym kierunku // jest odcinek rowu na tym kierunku
if (watercourses[i] == 1) { if (watercourses[i] == 1) {
hex |= bit_1; hex |= bit_1;
@@ -476,322 +229,95 @@ public class RightBigSquare extends BigSquare {
logger.debug("Zapisano nowy plik mapy: {}", sb); logger.debug("Zapisano nowy plik mapy: {}", sb);
} }
void readFromFileNew(String dir) throws IOException { /**
* Konstruktor ladujacy duzy kwadrat z pliku binarnego w starym formacie.
*
* @param dir opcjonalny katalog z danymi
*
*/
void readFromFile_OldFormat(String dir) throws IOException {
if (fileName == null) { if (fileName == null) {
return; return;
} }
try {
String fullPath = dir + fileName + ".bin";
BufferedInputStream in = new BufferedInputStream(new FileInputStream(fullPath), 2 * 8192);
byte[] buffer = new byte[9 * 512];
int offset = 0;
int count = in.read(buffer);
squares = new Square[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++) {
Square kw = new Square(x, y);
if (offset >= count) {
count = in.read(buffer);
offset = 0;
}
offset = kw.readFromBuffer(buffer, offset);
if (kw.elevation < -3) {
logger.warn("Elevation: {}, fn= {} ", kw.elevation, fileName);
}
if (kw.elevation > 2660) {
logger.warn("Elevation: {}, fn= {} ", kw.elevation, fileName);
}
squares[x][y] = kw;
}
}
in.close();
logger.debug("Doczytano plik mapy: " + fullPath);
} catch (IOException e) {
squares = null;
throw e;
}
}
void readFromFile(String dir) throws IOException {
try {
String fullPath = dir + fileName + ".bin";
Square.RawData ss = new Square.RawData();
// DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(fullPath)));
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(fullPath)));
squares = new Square[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++) {
ss.read(in);
Square kw = new Square(x, y, ss);
squares[x][y] = kw;
if (kw.elevation > 2660) {
logger.warn("Elevation: {}, fn={} ", kw.elevation, fileName);
}
if (kw.elevation < -3) {
logger.warn("Elevation: {}, fn= {} ", kw.elevation, fileName);
}
}
}
in.close();
logger.debug("Doczytano plik mapy: " + fullPath);
} catch (IOException e) {
squares = 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.SS_SIZE != 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); StringBuilder sb = new StringBuilder(100);
sb.append(dir); if (dir == null) {
sb.append(s); sb.append(MapConsts.DATA_DIR);
// Utworzenie katalogów, gdyby nie istniały. } else {
File directory = new File(sb.toString()); sb.append(dir);
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 = squares[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 = squares[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 = squares[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 = squares[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(squares[x][y].wysokoscSrednia);
} else {
out.writeInt(0);
}
if (roznicaWzniesien) {
out.writeInt(squares[x][y].roznicaWzniesien);
} else {
out.writeInt(0);
}
int bit_1;
hex = 0;
if (drogi) {
bit_1 = 1;
for (int i = 0; i < squares[x][y].jestDroga.length; i++) {
// jest odcinek drogi na tym kierunku
if (squares[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 < squares[x][y].jestPrzeszkodaWodna.length; i++) {
// jest odcinek przeszkody wodnej na tym kierunku
if (squares[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 < squares[x][y].jestRow.length; i++) {
// jest odcinek rowu na tym kierunku
if (squares[x][y].jestRow[i]) {
hex |= bit_1;
}
bit_1 <<= 1;
}
}
out.writeByte(hex);
}
}
} }
out.close(); sb.append(fileName).append(".bin");
logger.debug("Zapisano nowy plik mapy: " + sb.toString() + " dla rozmiaru MK= " + dlmk);
}
public RightBigSquare() {
}
/**
* konstruktor ladujacy duzy kwadrat z pliku binarnego w starym formacie
*
* @param fname nazwa pliku z danymi
*/
RightBigSquare(String fname, String dir) throws IOException {
try { try {
File f = new File(fname);
fileName = f.getName();
fileName = fileName.substring(0, fileName.lastIndexOf('.'));
StringBuilder sb = new StringBuilder(100);
if (dir == null) {
sb.append(MapConsts.KWADRATY_DIR);
} else {
sb.append(dir);
}
sb.append(fileName + ".bin");
ObjectInputStream in = new ObjectInputStream(new FileInputStream(sb.toString())); ObjectInputStream in = new ObjectInputStream(new FileInputStream(sb.toString()));
squares = new Square[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y]; squares = new Square[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y];
for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) { for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) {
for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) { for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) {
Square kw = new Square(x, y); Square kw = new Square(x, y);
squares[x][y] = kw; squares[x][y] = kw;
kw.terrainType = TerrainType.NONE;
int hex = in.readByte(); int hex = in.readByte();
kw.stopienZalesienia = (float) hex * (1.0f / 100.f); if (hex > 30) {
hex = in.readByte(); kw.terrainType = TerrainType.FOREST;
kw.stopienZawodnienia = (float) hex * (1.0f / 100.f);
hex = in.readByte();
kw.stopienZabudowy = (float) hex * (1.0f / 100.f);
hex = in.readByte();
kw.stopienZabagnienia = (float) hex * (1.0f / 100.f);
kw.wysokoscSrednia = in.readInt();
if (kw.wysokoscSrednia < -3) {
logger.warn("Elevation: {}, fn= {} ", kw.wysokoscSrednia, fileName);
} }
if (kw.wysokoscSrednia > 2660) { hex = in.readByte();
logger.warn("Elevation: {}, fn= {} ", kw.wysokoscSrednia, fileName); if (hex > 30) {
kw.terrainType = TerrainType.WATER;
} }
kw.roznicaWzniesien = in.readInt(); hex = in.readByte();
if (hex > 30) {
kw.terrainType = TerrainType.BUILDINGS;
}
hex = in.readByte();
if (hex > 30) {
kw.terrainType = TerrainType.SWAMP;
}
kw.elevation = in.readInt();
if (kw.elevation < NmtDataGenerator.H_MIN) {
logger.warn("Elevation: {}, fn= {}", kw.elevation, fileName);
}
if (kw.elevation > NmtDataGenerator.H_MAX) {
logger.warn("Elevation: {}, fn= {}", kw.elevation, fileName);
}
// Pomijam dane o różnicy wzniesień.
in.readInt();
int bit_1 = 1; int bit_1 = 1;
hex = in.readByte(); hex = in.readByte();
if (kw.jestDroga == null) { for (int i = 0; i < 8; i++) {
kw.jestDroga = new boolean[8];
}
for (int i = 0; i < kw.jestDroga.length; i++) {
// jest odcinek rowu na tym kierunku // jest odcinek rowu na tym kierunku
if ((hex & bit_1) != 0) { if ((hex & bit_1) != 0) {
kw.jestDroga[i] = true; kw.roads[i] = 2;
} }
bit_1 <<= 1; bit_1 <<= 1;
} }
bit_1 = 1; bit_1 = 1;
hex = in.readByte(); hex = in.readByte();
if (kw.jestPrzeszkodaWodna == null) { for (int i = 0; i < 8; i++) {
kw.jestPrzeszkodaWodna = new boolean[8]; // jest odcinek rzeki na tym kierunku
}
for (int i = 0; i < kw.jestPrzeszkodaWodna.length; i++) {
// jest odcinek rowu na tym kierunku
if ((hex & bit_1) != 0) { if ((hex & bit_1) != 0) {
kw.jestPrzeszkodaWodna[i] = true; kw.watercourses[i] = 3;
} }
bit_1 <<= 1; bit_1 <<= 1;
} }
bit_1 = 1; bit_1 = 1;
hex = in.readByte(); hex = in.readByte();
if (kw.jestRow == null) { for (int i = 0; i < 8; i++) {
kw.jestRow = new boolean[8];
}
for (int i = 0; i < kw.jestRow.length; i++) {
// jest odcinek rowu na tym kierunku // jest odcinek rowu na tym kierunku
if ((hex & bit_1) != 0) { if ((hex & bit_1) != 0) {
kw.jestRow[i] = true; kw.watercourses[i] = 1;
} }
bit_1 <<= 1; bit_1 <<= 1;
} }
} }
} }
in.close(); in.close();
logger.debug("Doczytano plik mapy: " + sb.toString()); logger.debug("Doczytano plik mapy: {}", sb);
} catch (IOException e) { } catch (IOException e) {
squares = null; squares = null;
throw e; 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++) {
squares[x][y].stopienZalesienia = (zalesienie) ? 0 : squares[x][y].stopienZalesienia;
squares[x][y].stopienZawodnienia = (zawodnienie) ? 0 : squares[x][y].stopienZawodnienia;
squares[x][y].stopienZabudowy = (zabudowa) ? 0 : squares[x][y].stopienZabudowy;
squares[x][y].stopienZabagnienia = (zabagnienie) ? 0 : squares[x][y].stopienZabagnienia;
squares[x][y].wysokoscSrednia = (wysokosc) ? 0 : squares[x][y].wysokoscSrednia;
squares[x][y].roznicaWzniesien = (roznicaWzniesien) ? 0 : squares[x][y].roznicaWzniesien;
if (drogi) {
for (int i = 0; i < squares[x][y].jestDroga.length; i++) {
squares[x][y].jestDroga[i] = false;
}
}
if (rzeki) {
for (int i = 0; i < squares[x][y].jestPrzeszkodaWodna.length; i++) {
squares[x][y].jestPrzeszkodaWodna[i] = false;
}
}
if (rowy) {
for (int i = 0; i < squares[x][y].jestRow.length; i++) {
squares[x][y].jestRow[i] = false;
}
}
}
}
}
@Override @Override
public String toString() { public String toString() {
return "RightBigSquare{" + this.fileName + '}'; return "RightBigSquare{" + fileName + '}';
} }
} }

View File

@@ -1,13 +1,21 @@
package pl.wat.ms4ds.terrain; package pl.wat.ms4ds.terrain;
/**
import java.io.DataInputStream; *
import java.io.IOException; * A class representing the characteristics of a square of terrain within a regular grid.
import java.io.ObjectInputStream; *
import java.io.ObjectOutputStream; */
public class Square { public class Square {
/**
* Horizontal grid coordinate.
*/
public final int x;
/**
* Vertical grid coordinate.
*/
public final int y;
/** /**
* The height above the level of the sea. Unit of measure meter [m]. * The height above the level of the sea. Unit of measure meter [m].
*/ */
@@ -23,7 +31,7 @@ public class Square {
* 5 - BUILDINGS * 5 - BUILDINGS
* 6 - FOREST * 6 - FOREST
*/ */
public short terrainType; public TerrainType terrainType;
/** /**
* Type of watercourse (water obstacle) in a given direction. Each index corresponds to a given direction. * Type of watercourse (water obstacle) in a given direction. Each index corresponds to a given direction.
@@ -37,182 +45,38 @@ public class Square {
*/ */
public final byte[] roads; public final byte[] roads;
/// ///////////////////////////////////// /**
/// tymczasowo * A type of crossing that allows overcoming terrain obstacles, e.g. rivers.
public float stopienZabudowy; * <p></p>Possible values: 0 - none, 1 - bridge, 2 - tunnel
public float stopienZalesienia; */
public float stopienZawodnienia; public CrossingType crossingType;
public float stopienZabagnienia;
public boolean[] jestDroga;
public boolean[] jestRow;
public boolean[] jestPrzeszkodaWodna;
public int roznicaWzniesien;
public int wysokoscSrednia;
/// ///////////////////////////////////// /**
* Size of the square.
*/
public static final int SIZE = 50;
public static class RawData { public enum CrossingType {
/** NONE(0),
* The height above the level of the sea. Unit of measure [0.25m]. BRIDGE(1),
*/ TUNNEL(2);
short elevation;
/**
* Terrain type. <p></p>Possible values:
* 0 - BARE_GROUND
* 1 - GRASS
* 2 - SWAMP
* 3 - WATER
* 4 - SCRUB, BUSHES
* 5 - BUILDINGS
* 6 - FOREST
*/
byte terrainType;
/** static final CrossingType[] values = values();
* Small road in a given direction. Each bit corresponds to a given direction.
*/
byte smallRoads;
/** public static CrossingType valueById(int id) {
* Minor road in a given direction. Each bit corresponds to a given direction. return (0 <= id && id <= 2) ? values[id] : NONE;
*/
byte minorRoads;
/**
* Major road in a given direction. Each bit corresponds to a given direction.
*/
byte majorRoads;
/**
* The existence of a drain in a given direction. Each bit corresponds to a given direction.
*/
byte drains;
/**
* The existence of a stream in a given direction. Each bit corresponds to a given direction.
*/
byte streams;
/**
* The existence of a river in a given direction. Each bit corresponds to a given direction.
*/
byte rivers;
public void reset() {
elevation = 0;
terrainType = 0;
smallRoads = 0;
minorRoads = 0;
majorRoads = 0;
drains = 0;
streams = 0;
rivers = 0;
} }
public void write(ObjectOutputStream out) throws IOException { public final int id;
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 read(ObjectInputStream in) throws IOException { CrossingType(int id) {
elevation = in.readShort(); this.id = id;
terrainType = in.readByte();
smallRoads = in.readByte();
minorRoads = in.readByte();
majorRoads = in.readByte();
drains = in.readByte();
streams = in.readByte();
rivers = in.readByte();
} }
public RawData(short elevation, byte terrainType) {
this.elevation = elevation;
this.terrainType = terrainType;
}
public RawData() {
}
public RawData(Square kw) {
terrainType = (byte) kw.terrainType;
// Konwersja na decymetry.
elevation = (short) (kw.elevation * 4);
byte bit = 1;
for (int i = 0; i < kw.watercourses.length; i++) {
switch (kw.watercourses[i]) {
case 1:
drains |= bit;
break;
case 2:
streams |= bit;
break;
case 3:
rivers |= bit;
break;
default:
break;
}
switch (kw.roads[i]) {
case 1:
smallRoads |= bit;
break;
case 2:
minorRoads |= bit;
break;
case 3:
majorRoads |= bit;
break;
default:
break;
}
bit <<= 1;
}
}
public void read(Square kw) {
terrainType = (byte) kw.terrainType;
// Konwersja na decymetry.
elevation = (short) (kw.elevation * 4);
byte bit = 1;
for (int i = 0; i < kw.watercourses.length; i++) {
switch (kw.watercourses[i]) {
case 1:
drains |= bit;
break;
case 2:
streams |= bit;
break;
case 3:
rivers |= bit;
break;
default:
break;
}
switch (kw.roads[i]) {
case 1:
smallRoads |= bit;
break;
case 2:
minorRoads |= bit;
break;
case 3:
majorRoads |= bit;
break;
default:
break;
}
bit <<= 1;
}
}
} }
/**
* Obiekt reprezentujący tzw. pusty kwadrat (spoza obszaru).
*/
public static final Square EMPTY = new Square(-1, -1); public static final Square EMPTY = new Square(-1, -1);
public Square() { public Square() {
@@ -226,26 +90,23 @@ public class Square {
watercourses = new byte[8]; watercourses = new byte[8];
} }
public Square(int x, int y, RawData rawData) { public int writeToBuffer_ElevationOnly(byte[] buffer, int offset) {
this.x = x; // Konwersja [m] -> [0.25m].
this.y = y; int elev = (short) (elevation * 4);
roads = new byte[8]; byte b1 = (byte) (elev & 0xFF);
watercourses = new byte[8]; elev >>= 8;
// Konwersja na metry a[0.25m] -> b[m] byte b0 = (byte) (elev & 0xFF);
elevation = (float) (rawData.elevation) / 4; buffer[offset] = b0;
terrainType = rawData.terrainType; buffer[offset + 1] = b1;
int bit = 1; buffer[offset + 2] = 0;
for (int i = 0; i < 8; i++) { buffer[offset + 3] = 0;
int b1 = ((rawData.majorRoads & bit) > 0) ? 3 : 0; buffer[offset + 4] = 0;
int b2 = ((rawData.minorRoads & bit) > 0) ? 2 : 0; buffer[offset + 5] = 0;
int b3 = ((rawData.smallRoads & bit) > 0) ? 1 : 0; buffer[offset + 6] = 0;
roads[i] = (byte) (b1 + b2 + b3); buffer[offset + 7] = 0;
b1 = ((rawData.rivers & bit) > 0) ? 3 : 0; buffer[offset + 8] = 0;
b2 = ((rawData.streams & bit) > 0) ? 2 : 0; buffer[offset + 9] = 0;
b3 = ((rawData.drains & bit) > 0) ? 1 : 0; return offset + 10;
watercourses[i] = (byte) (b1 + b2 + b3);
bit <<= 1;
}
} }
public int writeToBuffer(byte[] buffer, int offset) { public int writeToBuffer(byte[] buffer, int offset) {
@@ -258,7 +119,7 @@ public class Square {
byte smallRoads = 0; byte smallRoads = 0;
byte minorRoads = 0; byte minorRoads = 0;
byte majorRoads = 0; byte majorRoads = 0;
for (int i = 0; i < watercourses.length; i++) { for (int i = 0; i < 8; i++) {
switch (watercourses[i]) { switch (watercourses[i]) {
case 1: case 1:
drains |= bit; drains |= bit;
@@ -287,83 +148,64 @@ public class Square {
} }
bit <<= 1; bit <<= 1;
} }
// Konwersja short -> 2 bytes
byte b1 = (byte) (elev & 0xFF); byte b1 = (byte) (elev & 0xFF);
elev >>= 8; elev >>= 8;
byte b0 = (byte) (elev & 0xFF); byte b0 = (byte) (elev & 0xFF);
if (b0 == -1 && b1 == -4) {
System.out.println("a");
}
buffer[offset + 1] = b1; buffer[offset + 1] = b1;
buffer[offset] = b0; buffer[offset] = b0;
buffer[offset + 2] = (byte) terrainType; buffer[offset + 2] = (byte) terrainType.id;
buffer[offset + 3] = smallRoads; buffer[offset + 3] = smallRoads;
buffer[offset + 4] = minorRoads; buffer[offset + 4] = minorRoads;
buffer[offset + 5] = majorRoads; buffer[offset + 5] = majorRoads;
buffer[offset + 6] = drains; buffer[offset + 6] = drains;
buffer[offset + 7] = streams; buffer[offset + 7] = streams;
buffer[offset + 8] = rivers; buffer[offset + 8] = rivers;
return offset + 9; // 0 - brak, 1 - most, 2 - tunel
buffer[offset + 9] = (byte) crossingType.id;
return offset + 10;
} }
public int readFromBuffer(byte[] buffer, int offset) { public int readFromBuffer(byte[] buffer, int offset) {
// Odczyt wartości typu short
//
int elev = buffer[offset] & 0xFF; int elev = buffer[offset] & 0xFF;
elev = (elev << 8) + (buffer[offset + 1] & 0xFF); // elev = (elev << 8) + (buffer[offset + 1] & 0xFF);
elev = (elev << 8) | (buffer[offset + 1] & 0xFF);
// Rzutowanie "elev" na short zachowuje znak liczby.
short v = (short) elev; short v = (short) elev;
// Konwersja na metry a[0.25m] -> b[m] // Konwersja jednostek [0.25m]->[m]
elevation = (float) (v) / 4; elevation = (float) (v) / 4;
if (elevation > 2660) { terrainType = TerrainType.valueFromId(buffer[offset + 2]);
System.out.println("h=" + elevation);
}
terrainType = buffer[offset + 2];
byte smallRoads = buffer[offset + 3]; byte smallRoads = buffer[offset + 3];
byte minorRoads = buffer[offset + 4]; byte minorRoads = buffer[offset + 4];
byte majorRoads = buffer[offset + 5]; byte majorRoads = buffer[offset + 5];
byte drains = buffer[offset + 6]; byte drains = buffer[offset + 6];
byte streams = buffer[offset + 7]; byte streams = buffer[offset + 7];
byte rivers = buffer[offset + 8]; byte rivers = buffer[offset + 8];
byte b = buffer[offset + 9];
crossingType = CrossingType.valueById(b);
int bit = 1; int bit = 1;
// 8 kierunków geograficznych (0 - NORTH, 1 - NORTH_EAST, ...) // 8 kierunków geograficznych (0 - NORTH, 1 - NORTH_EAST, ...)
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
int b1 = ((majorRoads & bit) > 0) ? 3 : 0; int b1 = ((majorRoads & bit) != 0) ? 3 : 0;
int b2 = ((minorRoads & bit) > 0) ? 2 : 0; int b2 = ((minorRoads & bit) != 0) ? 2 : 0;
int b3 = ((smallRoads & bit) > 0) ? 1 : 0; int b3 = ((smallRoads & bit) != 0) ? 1 : 0;
roads[i] = (byte) (b1 + b2 + b3); roads[i] = (byte) (b1 + b2 + b3);
b1 = ((rivers & bit) > 0) ? 3 : 0; b1 = ((rivers & bit) != 0) ? 3 : 0;
b2 = ((streams & bit) > 0) ? 2 : 0; b2 = ((streams & bit) != 0) ? 2 : 0;
b3 = ((drains & bit) > 0) ? 1 : 0; b3 = ((drains & bit) != 0) ? 1 : 0;
watercourses[i] = (byte) (b1 + b2 + b3); watercourses[i] = (byte) (b1 + b2 + b3);
bit <<= 1; bit <<= 1;
} }
return offset + 9; return offset + 10;
} }
void read(RawData rawData) {
// Konwersja na metry a[0.25m] -> b[m]
elevation = (float) (rawData.elevation) / 4;
terrainType = rawData.terrainType;
int bit = 1;
for (int i = 0; i < 8; i++) {
int b1 = ((rawData.majorRoads & bit) > 0) ? 3 : 0;
int b2 = ((rawData.minorRoads & bit) > 0) ? 2 : 0;
int b3 = ((rawData.smallRoads & bit) > 0) ? 1 : 0;
roads[i] = (byte) (b1 + b2 + b3);
b1 = ((rawData.rivers & bit) > 0) ? 3 : 0;
b2 = ((rawData.streams & bit) > 0) ? 2 : 0;
b3 = ((rawData.drains & bit) > 0) ? 1 : 0;
watercourses[i] = (byte) (b1 + b2 + b3);
bit <<= 1;
}
}
public final int x;
public final int y;
@Override @Override
public final boolean equals(Object o) { public final boolean equals(Object o) {
if (!(o instanceof Square SQUARE)) return false; if (!(o instanceof Square square)) return false;
return x == SQUARE.x && y == SQUARE.y; return x == square.x && y == square.y;
} }
@Override @Override
@@ -374,17 +216,18 @@ public class Square {
return result; return result;
} }
@Override
public String toString() { public String toString() {
StringBuilder linia = new StringBuilder(100); StringBuilder linia = new StringBuilder(100);
linia.append("["); linia.append("[");
char c = switch (terrainType) { char c = switch (terrainType) {
case 1 -> 'G'; case NONE -> 'G';
case 2 -> 'S'; case GRASS -> 'g';
case 3 -> 'W'; case SWAMP -> 'S';
case 4 -> 'R'; case WATER -> 'W';
case 5 -> 'B'; case SCRUB_BUSHES -> 'R';
case 6 -> 'F'; case BUILDINGS -> 'B';
default -> ' '; case FOREST -> 'F';
}; };
linia.append(c); linia.append(c);
linia.append(' '); linia.append(' ');

View File

@@ -1,6 +1,7 @@
package pl.wat.ms4ds.terrain; package pl.wat.ms4ds.terrain;
import java.io.*; import java.io.*;
import java.util.ArrayList;
import java.util.Set; import java.util.Set;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@@ -8,7 +9,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pl.wat.ms4ds.common.ERodzajPodwozia; import pl.wat.ms4ds.common.ERodzajPodwozia;
import pl.wat.ms4ds.common.ERodzajTerenuPokrycie; import pl.wat.ms4ds.common.ERodzajTerenuPokrycie;
import pl.wat.ms4ds.terrain.nmt.NMTDataProvider; import pl.wat.ms4ds.terrain.nmt.NmtDataProvider;
import static pl.wat.ms4ds.terrain.Square.EMPTY; import static pl.wat.ms4ds.terrain.Square.EMPTY;
@@ -16,10 +17,10 @@ public class Teren {
private static final Logger LOGGER = LoggerFactory.getLogger(Teren.class); private static final Logger LOGGER = LoggerFactory.getLogger(Teren.class);
private static final int BIG_X_MAX = 100; private static final int BIG_X_MAX = MapConsts.DELTA_LON_REF * MapConsts.BS_PER_DEG_X;
private static final int BIG_Y_MAX = 100; private static final int BIG_Y_MAX = MapConsts.DELTA_LAT_REF * MapConsts.BS_PER_DEG_Y;
private static BigSquare bigSquares[][] = new BigSquare[BIG_X_MAX][BIG_Y_MAX]; private static final BigSquare[][] bigSquares = new BigSquare[BIG_X_MAX][BIG_Y_MAX];
// tablica obiektów synchronizujących dostęp do dużych kwadratów przy odczycie z pliku // tablica obiektów synchronizujących dostęp do dużych kwadratów przy odczycie z pliku
private static Object bsSynch = new Object(); private static Object bsSynch = new Object();
@@ -44,31 +45,28 @@ public class Teren {
* Jawne wywolanie zapisu do pliku bufora zmian terenu. Zapisane zostaną aktywne/załadowane duże kwadraty. * Jawne wywolanie zapisu do pliku bufora zmian terenu. Zapisane zostaną aktywne/załadowane duże kwadraty.
*/ */
public static void saveToFiles(String dir) { public static void saveToFiles(String dir) {
for (int i = 0; i < bigSquares.length; i++) { for (int i = 0; i < BIG_X_MAX; i++) {
for (int j = 0; j < bigSquares[i].length; j++) { for (int j = 0; j < BIG_Y_MAX; j++) {
BigSquare bs = bigSquares[i][j]; BigSquare bs = bigSquares[i][j];
if (bs instanceof RightBigSquare rbs) { if (bs instanceof RightBigSquare rbs) {
try { try {
rbs.writeToFile(dir); rbs.writeToFile(dir);
bigSquares[i][j] = null;
} catch (IOException e) { } catch (IOException e) {
LOGGER.warn("Błąd zapisu pliku mapy: " + rbs.fileName); LOGGER.warn("Błąd zapisu pliku mapy: " + rbs.fileName);
} }
} }
} }
} }
reset();
} }
public static void reset() { public static void reset() {
for (int i = 0; i < bigSquares.length; i++) { for (int i = 0; i < BIG_X_MAX; i++) {
for (int j = 0; j < bigSquares[i].length; j++) { for (int j = 0; j < BIG_Y_MAX; j++) {
bigSquares[i][j] = null; bigSquares[i][j] = null;
} }
} }
bigSquaresInMemory = 0; cache.clear();
for (int i = 0; i < history.length; i++) {
history[i].set(-1, -1);
}
System.gc(); System.gc();
} }
@@ -80,22 +78,22 @@ public class Teren {
* @return Nazwa zwracanego pliku z danymi (null - gdy niepoprawne współrzędne). * @return Nazwa zwracanego pliku z danymi (null - gdy niepoprawne współrzędne).
*/ */
public static String getFileName(double lat, double lon) { public static String getFileName(double lat, double lon) {
int idX = Coord.zamienDlugoscGeoNaIdKwadratuX(lon); int idX = Coord.convertLonToGridX(lon);
int idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(lat); int idY = Coord.convertLatToGridY(lat);
int bigX = idX / MapConsts.SS_PER_BS_X; int bigX = idX / MapConsts.SS_PER_BS_X;
int bigY = idY / MapConsts.SS_PER_BS_Y; int bigY = idY / MapConsts.SS_PER_BS_Y;
return getFileName(bigX, bigY); return getFileName(bigX, bigY);
} }
private static String getFileName(int bsX, int bsY) { private static String getFileName(int bsX, int bsY) {
int x_stop = MapConsts.X_REF + bsX / MapConsts.BS_PER_DEG_X - 180; int x_stop = MapConsts.REF_LON + bsX / MapConsts.BS_PER_DEG_X - 180;
char cLon = (x_stop < 0) ? 'W' : 'E'; char cLon = (x_stop < 0) ? 'W' : 'E';
if (x_stop < 0) { if (x_stop < 0) {
x_stop = -x_stop; x_stop = -x_stop;
} }
int dx = bsX % MapConsts.BS_PER_DEG_X; int dx = bsX % MapConsts.BS_PER_DEG_X;
char cx = LITERALS.charAt(dx); char cx = LITERALS.charAt(dx);
int y_stop = MapConsts.Y_REF + bsY / MapConsts.BS_PER_DEG_Y - 90; int y_stop = MapConsts.REF_LAT + bsY / MapConsts.BS_PER_DEG_Y - 90;
char cLat = (y_stop < 0) ? 'S' : 'N'; char cLat = (y_stop < 0) ? 'S' : 'N';
if (y_stop < 0) { if (y_stop < 0) {
y_stop = -y_stop; y_stop = -y_stop;
@@ -123,12 +121,15 @@ public class Teren {
return sb.toString(); return sb.toString();
} }
private static BigSquare loadAreaOld(int bsX, int bsY) { private static BigSquare loadArea_OldFormat(int bsX, int bsY) {
String fName = getFileName(bsX, bsY) + ".bin"; String fName = getFileName(bsX, bsY);
try { try {
return new RightBigSquare(fName, null); RightBigSquare bs = new RightBigSquare();
bs.fileName = fName;
bs.readFromFile_OldFormat(MapConsts.DATA_DIR);
return bs;
} catch (IOException e) { } catch (IOException e) {
LOGGER.warn("Brak pliku mapy: {}{}{}", MapConsts.KWADRATY_DIR, fName, ".bin"); LOGGER.warn("Brak pliku mapy: {}{}{}", MapConsts.DATA_DIR, fName, ".bin");
return EmptyBigSquare.EMPTY_BIG_SQUARE; return EmptyBigSquare.EMPTY_BIG_SQUARE;
} }
} }
@@ -138,10 +139,10 @@ public class Teren {
try { try {
RightBigSquare bs = new RightBigSquare(); RightBigSquare bs = new RightBigSquare();
bs.fileName = fName; bs.fileName = fName;
bs.readFromFile(MapConsts.KWADRATY_DIR); bs.readFromFile(MapConsts.DATA_DIR);
return bs; return bs;
} catch (IOException e) { } catch (IOException e) {
LOGGER.warn("Brak pliku mapy: {}{}{}", MapConsts.KWADRATY_DIR, fName, ".bin"); LOGGER.warn("Brak pliku mapy: {}{}{}", MapConsts.DATA_DIR, fName, ".bin");
return EmptyBigSquare.EMPTY_BIG_SQUARE; return EmptyBigSquare.EMPTY_BIG_SQUARE;
} }
} }
@@ -151,13 +152,13 @@ public class Teren {
public static Square getKwadratPUWG(double northing, double easting) { public static Square getKwadratPUWG(double northing, double easting) {
Coord.Geo geoCoord = new Coord.Geo(); Coord.Geo geoCoord = new Coord.Geo();
Coord.convertPUWG1992ToWGS84(northing, easting, geoCoord); Coord.convertPUWG1992ToWGS84(northing, easting, geoCoord);
return getKwadrat(geoCoord.lat, geoCoord.lon); return getSquare(geoCoord.lat, geoCoord.lon);
} }
public static Square getKwadrat(double lat, double lon) { public static Square getSquare(double lat, double lon) {
int idX = Coord.zamienDlugoscGeoNaIdKwadratuX(lon); int idX = Coord.convertLonToGridX(lon);
int idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(lat); int idY = Coord.convertLatToGridY(lat);
return getKwadrat(idX, idY); return getSquare(idX, idY);
} }
/** /**
@@ -167,7 +168,7 @@ public class Teren {
* @param y współrzędna pionowa (indeks wiersza) * @param y współrzędna pionowa (indeks wiersza)
* @return obiekt reprezentujący charakterystyki fragmentu terenu * @return obiekt reprezentujący charakterystyki fragmentu terenu
*/ */
public static Square getKwadrat(int x, int y) { public static Square getSquare(int x, int y) {
if (x < 0 || y < 0) { if (x < 0 || y < 0) {
return EMPTY; return EMPTY;
} }
@@ -175,7 +176,7 @@ public class Teren {
int bsX = x / MapConsts.SS_PER_BS_X; int bsX = x / MapConsts.SS_PER_BS_X;
// wspolrzędna y dużego kwadratu // wspolrzędna y dużego kwadratu
int bsY = y / MapConsts.SS_PER_BS_Y; int bsY = y / MapConsts.SS_PER_BS_Y;
if (bsX < 0 || bsX >= BIG_X_MAX || bsY < 0 || bsY >= BIG_Y_MAX) { if (bsX >= BIG_X_MAX || bsY >= BIG_Y_MAX) {
return EMPTY; return EMPTY;
} }
// wspolrzędna x małego kwadratu w ramach dużego kwadratu // wspolrzędna x małego kwadratu w ramach dużego kwadratu
@@ -188,38 +189,25 @@ public class Teren {
bigSquares[bsX][bsY] = loadArea(bsX, bsY); bigSquares[bsX][bsY] = loadArea(bsX, bsY);
} }
} }
return bigSquares[bsX][bsY].getKwadrat(ssX, ssY); return bigSquares[bsX][bsY].getSquare(ssX, ssY);
} }
private static Coord.Grid[] history = new Coord.Grid[MapConsts.MAX_BIG_SQUARES_IN_MEMORY]; private static Coord.Grid[] history = new Coord.Grid[MapConsts.MAX_BIG_SQUARES_IN_MEMORY];
private static int bigSquaresInMemory = 0; private static final ArrayList<Coord.Grid> cache = new ArrayList<>(MapConsts.MAX_BIG_SQUARES_IN_MEMORY);
private static void makeRoom(int bigX, int bigY) { private static void makeRoom(int bigX, int bigY) {
if (bigSquaresInMemory >= MapConsts.MAX_BIG_SQUARES_IN_MEMORY) { if (cache.size() >= MapConsts.MAX_BIG_SQUARES_IN_MEMORY) {
// najpierw zapisuję w pliku dokonane zmiany // Brak miejsca, zatem zwalniam/usuwam najstarszy element;
if (bigSquares[history[0].x][history[0].y] instanceof RightBigSquare rbs) { Coord.Grid removing = cache.removeFirst();
try { RightBigSquare rbs = (RightBigSquare) bigSquares[removing.x][removing.y];
//!! dla potrzeb generowania danych try {
rbs.liczbaZmian = 1; rbs.writeToFile(null);
rbs.writeToFile(null); } catch (IOException _) {
} catch (IOException e) {
e.printStackTrace();
}
} }
// następnie usuwam duzy kwadrat z pamięci bigSquares[removing.x][removing.y] = null;
bigSquares[history[0].x][history[0].y] = null; LOGGER.debug("Big square X= {}, Y= {}, fn= {} removed from cache", bigX, bigY, rbs.fileName);
for (int i = 1; i < history.length; i++) {
// przesuwam elementy w lewo
history[i - 1].set(history[i]);
}
// uaktualniam indeksy duzego kwadratu w historii (ostatni == najnowszy element)
history[MapConsts.MAX_BIG_SQUARES_IN_MEMORY - 1].x = bigX;
history[MapConsts.MAX_BIG_SQUARES_IN_MEMORY - 1].y = bigY;
} else {
history[bigSquaresInMemory].x = bigX;
history[bigSquaresInMemory].y = bigY;
bigSquaresInMemory++;
} }
cache.add(new Coord.Grid(bigX, bigY));
} }
/** /**
@@ -278,19 +266,19 @@ public class Teren {
for (int i = 0; i < history.length; i++) { for (int i = 0; i < history.length; i++) {
history[i] = new Coord.Grid(); history[i] = new Coord.Grid();
} }
przejezdnoscZawsze = MapConsts.ustawienia.getProperty("przejezdnosc_zawsze").equals("on"); przejezdnoscZawsze = MapConsts.properties.getProperty("przejezdnosc_zawsze").equals("on");
minStopienPrzejezd = Double.parseDouble(MapConsts.ustawienia.getProperty("minimalny_stopien_przejezdnosci")); minStopienPrzejezd = Double.parseDouble(MapConsts.properties.getProperty("minimalny_stopien_przejezdnosci"));
minStopienPrzejezdNaPrzelaj = Double.parseDouble(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.minimalny_na_przelaj")); minStopienPrzejezdNaPrzelaj = Double.parseDouble(MapConsts.properties.getProperty("stopien_przejezdnosci.minimalny_na_przelaj"));
minStopienPrzejezdNaDrodzeNachylenie = Double.parseDouble(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.minimalny.na_drodze.nachylenie_terenu")); minStopienPrzejezdNaDrodzeNachylenie = Double.parseDouble(MapConsts.properties.getProperty("stopien_przejezdnosci.minimalny.na_drodze.nachylenie_terenu"));
minStopienPrzejezdNaPrzelajNachylenie = Double.parseDouble(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.minimalny.na_przelaj.nachylenie_terenu")); minStopienPrzejezdNaPrzelajNachylenie = Double.parseDouble(MapConsts.properties.getProperty("stopien_przejezdnosci.minimalny.na_przelaj.nachylenie_terenu"));
minKatNachylTerenuNaDrodze = Double.parseDouble(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.na_drodze.nachylenie_terenu.kat_minimalny")); minKatNachylTerenuNaDrodze = Double.parseDouble(MapConsts.properties.getProperty("stopien_przejezdnosci.na_drodze.nachylenie_terenu.kat_minimalny"));
minKatNachylTerenuNaDrodze = Math.max(0, minKatNachylTerenuNaDrodze); minKatNachylTerenuNaDrodze = Math.max(0, minKatNachylTerenuNaDrodze);
minKatNachylTerenuNaDrodze = Math.min(60, minKatNachylTerenuNaDrodze); minKatNachylTerenuNaDrodze = Math.min(60, minKatNachylTerenuNaDrodze);
minKatNachylTerenuNaDrodze *= Math.PI / 180; minKatNachylTerenuNaDrodze *= Math.PI / 180;
maxKatNachylTerenuNaDrodze = Double.parseDouble(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.na_drodze.nachylenie_terenu.kat_maksymalny")); maxKatNachylTerenuNaDrodze = Double.parseDouble(MapConsts.properties.getProperty("stopien_przejezdnosci.na_drodze.nachylenie_terenu.kat_maksymalny"));
maxKatNachylTerenuNaDrodze = Math.max(0, maxKatNachylTerenuNaDrodze); maxKatNachylTerenuNaDrodze = Math.max(0, maxKatNachylTerenuNaDrodze);
maxKatNachylTerenuNaDrodze = Math.min(60, maxKatNachylTerenuNaDrodze); maxKatNachylTerenuNaDrodze = Math.min(60, maxKatNachylTerenuNaDrodze);
maxKatNachylTerenuNaDrodze *= Math.PI / 180; maxKatNachylTerenuNaDrodze *= Math.PI / 180;
@@ -300,12 +288,12 @@ public class Teren {
minKatNachylTerenuNaDrodze = temp; minKatNachylTerenuNaDrodze = temp;
} }
minKatNachylTerenuNaPrzelaj = Double.parseDouble(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.na_przelaj.nachylenie_terenu.kat_minimalny")); minKatNachylTerenuNaPrzelaj = Double.parseDouble(MapConsts.properties.getProperty("stopien_przejezdnosci.na_przelaj.nachylenie_terenu.kat_minimalny"));
minKatNachylTerenuNaPrzelaj = Math.max(0, minKatNachylTerenuNaPrzelaj); minKatNachylTerenuNaPrzelaj = Math.max(0, minKatNachylTerenuNaPrzelaj);
minKatNachylTerenuNaPrzelaj = Math.min(60, minKatNachylTerenuNaPrzelaj); minKatNachylTerenuNaPrzelaj = Math.min(60, minKatNachylTerenuNaPrzelaj);
minKatNachylTerenuNaPrzelaj *= Math.PI / 180; minKatNachylTerenuNaPrzelaj *= Math.PI / 180;
maxKatNachylTerenuNaPrzelaj = Double.parseDouble(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.na_przelaj.nachylenie_terenu.kat_maksymalny")); maxKatNachylTerenuNaPrzelaj = Double.parseDouble(MapConsts.properties.getProperty("stopien_przejezdnosci.na_przelaj.nachylenie_terenu.kat_maksymalny"));
maxKatNachylTerenuNaPrzelaj = Math.max(0, maxKatNachylTerenuNaPrzelaj); maxKatNachylTerenuNaPrzelaj = Math.max(0, maxKatNachylTerenuNaPrzelaj);
maxKatNachylTerenuNaPrzelaj = Math.min(60, maxKatNachylTerenuNaPrzelaj); maxKatNachylTerenuNaPrzelaj = Math.min(60, maxKatNachylTerenuNaPrzelaj);
maxKatNachylTerenuNaPrzelaj *= Math.PI / 180; maxKatNachylTerenuNaPrzelaj *= Math.PI / 180;
@@ -328,59 +316,59 @@ public class Teren {
STOPIEN_PRZEJEZDNOSCI = new float[ERodzajPodwozia.numberOfValues()][ERodzajTerenuPokrycie.numberOfValues()]; STOPIEN_PRZEJEZDNOSCI = new float[ERodzajPodwozia.numberOfValues()][ERodzajTerenuPokrycie.numberOfValues()];
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_gasienicowe.teren_zabudowany")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_gasienicowe.teren_zabudowany"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_gasienicowe.teren_zalesiony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_gasienicowe.teren_zalesiony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_gasienicowe.teren_zabagniony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_gasienicowe.teren_zabagniony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_gasienicowe.teren_zawodniony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_gasienicowe.teren_zawodniony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.GASIENICE.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.GASIENICE.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_gasienicowe.teren_czysty")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_gasienicowe.teren_czysty"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA_GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA_GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabudowany")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabudowany"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA_GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA_GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zalesiony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zalesiony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA_GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA_GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabagniony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabagniony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA_GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA_GASIENICE.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zawodniony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zawodniony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA_GASIENICE.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA_GASIENICE.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_czysty")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_czysty"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_kolowe.teren_zabudowany")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_kolowe.teren_zabudowany"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_kolowe.teren_zalesiony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_kolowe.teren_zalesiony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_kolowe.teren_zabagniony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_kolowe.teren_zabagniony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_kolowe.teren_zawodniony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_kolowe.teren_zawodniony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.KOLA.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_kolowe.teren_czysty")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_kolowe.teren_czysty"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PODUSZKA_POW.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PODUSZKA_POW.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_poduszka.teren_zabudowany")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_poduszka.teren_zabudowany"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PODUSZKA_POW.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PODUSZKA_POW.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_poduszka.teren_zalesiony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_poduszka.teren_zalesiony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PODUSZKA_POW.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PODUSZKA_POW.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_poduszka.teren_zabagniony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_poduszka.teren_zabagniony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PODUSZKA_POW.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PODUSZKA_POW.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_poduszka.teren_zawodniony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_poduszka.teren_zawodniony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PODUSZKA_POW.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PODUSZKA_POW.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_poduszka.teren_czysty")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_poduszka.teren_czysty"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PLOZY.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PLOZY.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_zabudowany")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_zabudowany"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PLOZY.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PLOZY.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_zalesiony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_zalesiony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PLOZY.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PLOZY.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_zabagniony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_zabagniony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PLOZY.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PLOZY.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_zawodniony")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_zawodniony"));
STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PLOZY.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id] = STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PLOZY.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id] =
Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_czysty")); Float.parseFloat(MapConsts.properties.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_czysty"));
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@@ -394,23 +382,28 @@ public class Teren {
LOGGER.debug("start"); LOGGER.debug("start");
// Teren.normalizujDanePokrycia(); // Teren.normalizujDanePokrycia();
String newDir = "D:/work/kwadraty_nmt/temp/25/"; String newDir = "D:/work/kwadraty_nmt/temp/100m/";
String dir1 = "D:/work/nowe/25m/"; String dir1 = "D:/work/terrain/";
String inDir = "D:/work/kwadraty_nmt/withElevation/25m/"; String inDir = "D:/work/kwadraty_nmt/withElevation/25m/";
String dir2 = "C:/Workspace/_data/swdt/ms4ds/teren/kwadraty/100m/"; String dir2 = "C:/Workspace/_data/swdt/ms4ds/teren/kwadraty/100m/";
Set<String> fileNames = NmtDataProvider.listFiles(inDir);
generateDataFromOldFormat(fileNames, newDir, 100);
// Set<String> fileNames2 = new HashSet<>();
// fileNames2.add(dir2 + "E014C_N53D.bin");
// generateData(fileNames, inDir, newDir);
// Square kw = getKwadrat(1500, 2100); // Square kw = getKwadrat(1500, 2100);
// System.out.println(kw); // System.out.println(kw);
// kw = getKwadrat(2100, 1500); // kw = getKwadrat(2100, 1500);
// System.out.println(kw); // System.out.println(kw);
Set<String> fileNames = NMTDataProvider.listFiles(dir1);
// String fn = "E017B_N54E"; // String fn = "E017B_N54E";
// RightBigSquare rbs = new RightBigSquare(dir2 + fn + ".bin", null); // RightBigSquare rbs = new RightBigSquare(dir2 + fn + ".bin", null);
// rbs.writeToFileOldToNewFormatWithElevetion(dir1, 25); // rbs.writeToFileOldToNewFormatWithElevetion(dir1, 25);
RightBigSquare rbs = new RightBigSquare(); // RightBigSquare rbs = new RightBigSquare();
rbs.fileName = "E017B_N54E"; // rbs.fileName = "E017B_N54E";
rbs.readFromFileNew(dir1); // rbs.readFromFile(dir1);
// Teren.generateData(fileNames, dir1, newDir); // Teren.generateData(fileNames, dir1, newDir);
// Teren.generateDataOldToNewFormat(fileNames, dir2, dir1, 25); // Teren.generateDataOldToNewFormat(fileNames, dir2, dir1, 25);
@@ -431,131 +424,21 @@ public class Teren {
} }
public static void wyzerujDane() {
// WYGENEROWANIE CZYSTYCH PLIKÓW DANYCH
for (int x = 0; x < bigSquares.length; x++) {
for (int y = 0; y < bigSquares[x].length; y++) {
try {
BigSquare bs = loadArea(x, y);
if (bs != null && bs instanceof RightBigSquare) {
RightBigSquare rbs = (RightBigSquare) bs;
// wyzerowanie wszystkiego poza wysokością i różnicą wzniesień
rbs.resetSquares(true, true, true, true, true, true, true, true, true);
rbs.liczbaZmian = 1;
rbs.writeToFile(null);
}
} catch (IOException e) {
// e.printStackTrace();
}
}
}
}
/**
* Funkcja uzupełnia brakujące dane wysokosciowe jako średnia kwadratów sąsiednich o niezerowych wysokosciach.
* Funkcja powinna być wywoływana dla danych zawierających informacje o wodach morskich.
*/
public static void poprawDaneWysokosciowe() {
int maxX = MapConsts.SS_PER_BS_X * MapConsts.BS_PER_DEG_X * MapConsts.DX_REF;
int maxY = MapConsts.SS_PER_BS_Y * MapConsts.BS_PER_DEG_Y * MapConsts.DY_REF;
for (int x = 0; x < maxX; x++) {
for (int y = 0; y < maxY; y++) {
Square kw = getKwadrat(x, y);
if (kw == EMPTY) {
continue;
}
if (kw.stopienZawodnienia == 0 && kw.wysokoscSrednia == 0) {
// operacja dla kwadratów lądowych
int licz = 0;
int suma = 0;
for (int i = -1; i < 1; i++) {
for (int j = -1; j < 1; j++) {
if (i == 0 && j == 0) {
// pomijam dane bieżącego kwadratu
continue;
}
int xx = x + i;
int yy = y + j;
Square kwSasiad = getKwadrat(xx, yy);
if (kwSasiad == EMPTY) {
// pomijam kwadraty poza mapą
continue;
}
if (kwSasiad.wysokoscSrednia > 0) {
// uśredniam tylko po kwadratach o niezerowej wysokości
suma += kwSasiad.wysokoscSrednia;
licz++;
}
}
}
float wys = (float) suma / (float) licz;
kw.wysokoscSrednia = (int) wys;
}
}
}
for (int x = 0; x < bigSquares.length; x++) {
for (int y = 0; y < bigSquares[x].length; y++) {
try {
BigSquare bs = bigSquares[x][y];
if (bs instanceof RightBigSquare rbs) {
rbs.liczbaZmian = 1;
rbs.writeToFile(null);
}
} catch (IOException e) {
// e.printStackTrace();
}
}
}
}
/**
* Funkcja poprawia dane o pokryciu, aby dane sumowały się do jedynki.
*/
static void normalizujDanePokrycia() {
int maxX = MapConsts.SS_PER_BS_X * MapConsts.BS_PER_DEG_X * MapConsts.DX_REF;
int maxY = MapConsts.SS_PER_BS_Y * MapConsts.BS_PER_DEG_Y * MapConsts.DY_REF;
for (int x = 0; x < maxX; x++) {
for (int y = 0; y < maxY; y++) {
Square kw = getKwadrat(x, y);
if (kw == EMPTY) {
continue;
}
float suma = kw.stopienZalesienia + kw.stopienZawodnienia + kw.stopienZabudowy + kw.stopienZabagnienia;
if (suma > 1.0f) {
kw.stopienZalesienia /= suma;
kw.stopienZawodnienia /= suma;
kw.stopienZabudowy /= suma;
kw.stopienZabagnienia = 1.0f - kw.stopienZalesienia - kw.stopienZawodnienia - kw.stopienZabudowy;
}
}
}
for (int x = 0; x < bigSquares.length; x++) {
for (int y = 0; y < bigSquares[x].length; y++) {
try {
BigSquare bs = bigSquares[x][y];
if (bs instanceof RightBigSquare rbs) {
rbs.liczbaZmian = 1;
rbs.writeToFile(null);
}
} catch (IOException e) {
// e.printStackTrace();
}
}
}
}
/** /**
* Generuje pliki z danymi w nowym formacie na podstawie danych w satrym formacie. * Generuje pliki z danymi w nowym formacie na podstawie danych w satrym formacie.
* *
* @param outDir katalog z danymi terenowymi np. "d:/Workspace2/kwadraty/czyste-wysokosc/" * @param outDir katalog z danymi terenowymi np. "d:/Workspace2/kwadraty/czyste-wysokosc/"
* @param dlmk docelowy rozmiar generowanych kwadratów terenu * @param dlmk docelowy rozmiar generowanych kwadratów terenu
*/ */
public static void generateDataOldToNewFormat(Set<String> fileNames, String inDir, String outDir, int dlmk) throws IOException { public static void generateDataFromOldFormat(Set<String> fileNames, String outDir, int dlmk) throws IOException {
for (String fileName : fileNames) { for (String fileName : fileNames) {
RightBigSquare rbs = new RightBigSquare(fileName, null); File file = new File(fileName);
rbs.writeToFileOldToNewFormatWithElevetion(outDir, dlmk); String fn = file.getName();
RightBigSquare rbs = new RightBigSquare();
rbs.fileName = fn.substring(0, fn.length() - 4);
rbs.readFromFile_OldFormat(null);
rbs.writeToFile_ElevationOnly(outDir, dlmk);
} }
} }
/** /**
@@ -563,16 +446,26 @@ public class Teren {
* *
* @param outDir katalog z danymi terenowymi np. "d:/Workspace2/kwadraty/czyste-wysokosc/" * @param outDir katalog z danymi terenowymi np. "d:/Workspace2/kwadraty/czyste-wysokosc/"
*/ */
public static void generateDataToOldFormat(Set<String> fileNames, String inDir, String outDir) throws IOException {
for (String fileName : fileNames) {
File file = new File(fileName);
String fn = file.getName().substring(0, file.getName().lastIndexOf('.'));
RightBigSquare rbs = new RightBigSquare();
rbs.fileName = fn;
rbs.readFromFile(inDir);
rbs.writeToFile_OldFormat(outDir);
}
}
public static void generateData(Set<String> fileNames, String inDir, String outDir) throws IOException { public static void generateData(Set<String> fileNames, String inDir, String outDir) throws IOException {
for (String fileName : fileNames) { for (String fileName : fileNames) {
File file = new File(fileName); File file = new File(fileName);
String fn = file.getName().substring(0, file.getName().lastIndexOf('.')); String fn = file.getName().substring(0, file.getName().lastIndexOf('.'));
RightBigSquare rbs = new RightBigSquare(); RightBigSquare rbs = new RightBigSquare();
rbs.fileName = fn; rbs.fileName = fn;
rbs.readFromFileNew(inDir); rbs.readFromFile(inDir);
// rbs.writeToFile(outDir); rbs.writeToFile(outDir);
} }
} }
} }

View File

@@ -1,7 +1,7 @@
package pl.wat.ms4ds.terrain; package pl.wat.ms4ds.terrain;
public enum TerrainType { public enum TerrainType {
BARE_GROUND(0), NONE(0),
GRASS(1), GRASS(1),
SWAMP(2), SWAMP(2),
WATER(3), WATER(3),
@@ -9,30 +9,16 @@ public enum TerrainType {
BUILDINGS(5), BUILDINGS(5),
FOREST(6); FOREST(6);
static { static final TerrainType[] values = values();
BARE_GROUND.height = 0;
BARE_GROUND.passability = true;
public static TerrainType valueFromId(int id) {
return values[id];
} }
public int getHeight(byte terrainType) { public final int id;
return height;
}
public final int ID;
private int height;
/**
* Zdolność przekraczania
*/
private boolean passability;
TerrainType(int id) { TerrainType(int id) {
this.ID = id; this.id = id;
} }
TerrainType(int id, int height, boolean passability) {
this.ID = id;
this.height = height;
this.passability = passability;
}
} }

View File

@@ -18,88 +18,70 @@ public class TerrainUtils {
* @param y2 * @param y2
* @return * @return
*/ */
public static float widocznoscOptyczna(float ho, float ht, int x1, int y1, int x2, int y2) { public static int lineOfSight(float ho, float ht, int x1, int y1, int x2, int y2) {
if ((x1 == x2) && (y1 == y2)) { if ((x1 == x2) && (y1 == y2)) {
return 1.0f; return 1;
} }
Square kwDo = Teren.getKwadrat(x1, y1); Square start = Teren.getSquare(x1, y1);
Square kwOd = Teren.getKwadrat(x2, y2); Square stop = Teren.getSquare(x2, y2);
if (kwDo == Square.EMPTY || kwOd == Square.EMPTY) { if (start == Square.EMPTY || stop == Square.EMPTY) {
return 0.0f; return 0;
} }
// roznica wysokosci miedzy skrajnymi kwadratami // roznica wysokosci miedzy skrajnymi kwadratami
float roznicaWysokosci = kwDo.wysokoscSrednia + ht - kwOd.wysokoscSrednia - ho; float heightDiff;
float wysBezwzgObserwatora; float observerTotalHeight = start.elevation + ho;
if (roznicaWysokosci < 0) { float targetTotalHeight = stop.elevation + ht;
// sprawdzanie kwOd -> kwDo if (observerTotalHeight > targetTotalHeight) {
// zamiana ról
int swap = x1; int swap = x1;
x1 = x2; x1 = x2;
x2 = swap; x2 = swap;
swap = y1; swap = y1;
y1 = y2; y1 = y2;
y2 = swap; y2 = swap;
roznicaWysokosci = -roznicaWysokosci; heightDiff = observerTotalHeight - targetTotalHeight;
wysBezwzgObserwatora = kwDo.wysokoscSrednia + ht; observerTotalHeight = targetTotalHeight;
} else { } else {
wysBezwzgObserwatora = kwOd.wysokoscSrednia + ho; heightDiff = targetTotalHeight - observerTotalHeight;
} }
Coord.Grid[] kwadratyNaOdcinku = Bresenham.generateSegment(x1, y1, x2, y2); int[] seq = GeomUtils.generateSquaresOfSegment2(x1, y1, x2, y2);
double dlugoscOdcinka = Coord.Grid.distance(x1, y1, x2, y2); double dist = Coord.Grid.distance(x1, y1, x2, y2);
double tangAlfa0 = roznicaWysokosci / dlugoscOdcinka; double tangAlfa0 = heightDiff / dist;
float dh_max = 0; float dh_max = 0;
for (int i = 1; i < kwadratyNaOdcinku.length - 1; i++) { // Tablica współrzędnych: x0, y0, x1, y1, x2, y2, x3, y3...
// Testowane kwadraty pośrednie między startowym a końcowym.
for (int i = 2; i < seq.length - 2; ) {
// badanie wewnetrznych kwadratow nalezacych do odcinka, // badanie wewnetrznych kwadratow nalezacych do odcinka,
// czy nie sa powyzej linii widocznosci dla kwadratow skrajnych // czy nie sa powyzej linii widocznosci dla kwadratow skrajnych
float wysokoscPrzeszkody = 0.0f; int x = seq[i++];
Square kwAkt = Teren.getKwadrat(kwadratyNaOdcinku[i].x, kwadratyNaOdcinku[i].y); int y = seq[i++];
if (kwAkt.stopienZalesienia > 0.5f) { Square curr = Teren.getSquare(x, y);
wysokoscPrzeszkody = 10.0f; float obstacleHeight = switch (curr.terrainType) {
} case TerrainType.SCRUB_BUSHES -> 1;
if (kwAkt.stopienZabudowy > 0.5f) { case TerrainType.BUILDINGS -> 10;
wysokoscPrzeszkody = 10.0f; case TerrainType.FOREST -> 10;
} default -> 0;
};
// wyznaczenie roznicy wysokosci kwadratu badanego i docelowego // wyznaczenie roznicy wysokosci kwadratu badanego i docelowego
// uwzgledniajac wysokosc obserwatora oraz wysokosc przeszkody // uwzgledniajac wysokosc obserwatora oraz wysokosc przeszkody
float dh = kwAkt.wysokoscSrednia + wysokoscPrzeszkody - wysBezwzgObserwatora; float dh = curr.elevation + obstacleHeight - observerTotalHeight;
if (dh_max >= dh) { if (dh_max >= dh) {
continue; continue;
} }
dist = Coord.Grid.distance(x, y, x1, y1);
double odleg = Coord.Grid.distance(kwadratyNaOdcinku[i].x, kwadratyNaOdcinku[i].y, x1, y1); // float tangAlfa = roznWysAkt / odleg;
// float tangAlfa = roznWysAkt / odleg; // if (tangAlfa0 < tangAlfa) {
// if (tangAlfa0 < tangAlfa) { if (tangAlfa0 * dist < dh) {
if (tangAlfa0 * odleg < dh) { // wysokosc aktualnie badanego kwadratu jest powyzej
// wysokosc aktualnie badanego kwadratu jest powyzej/ponizej
// linii poprowadzonej z kwadratu startowego do docelowego (z uwzglednieniem wysokosci obserwatora i celu) // linii poprowadzonej z kwadratu startowego do docelowego (z uwzglednieniem wysokosci obserwatora i celu)
// odpowiednio dla katow dodatnich/ujemnych // odpowiednio dla katow dodatnich
return 0.0f; return 0;
} }
dh_max = dh; dh_max = dh;
} }
return 1.0f; return 1;
}
public static float widocznoscOptyczna(int x, int y) {
Square kw = Teren.getKwadrat(x, y);
if (kw.stopienZabudowy > 0.25f || kw.stopienZalesienia > 0.25f) {
return 0.3f;
}
return 1.0f;
}
public static float sredStopienWidoczOptycznej(float wysokoscObserwatora, float wysokoscCelu,
Coord.Grid kwadratOd, int dl1, Coord.Grid 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;
} }
} }

View File

@@ -1,41 +0,0 @@
package pl.wat.ms4ds.terrain.nmt;
/**
*
*/
public class NMTData {
public int x;
public int y;
public double sum;
public int count;
public double ell;
public double nll;
public double eur;
public double nur;
public NMTData(int x, int y, double sum, int count) {
this.x = x;
this.y = y;
this.sum = sum;
this.count = count;
}
@Override
public String toString() {
return "NMTData{" +
"x=" + x +
", y=" + y +
", sum=" + sum +
", count=" + count +
", ell=" + ell +
", nll=" + nll +
", eur=" + eur +
", nur=" + nur +
'}';
}
}

View File

@@ -0,0 +1,71 @@
package pl.wat.ms4ds.terrain.nmt;
/**
* Klasa pomocnicza do generowania danych terenowych NMT.
* <p>
* Cachuje i agreguje dane dotyczące wysokości odczytane z siatki punktów
* w ramach wyznaczonych granic kwadratu terenu (współrzędne PUWG1992).
*/
public class NmtData {
/**
* Współrzędna X kwadratu w ramach siatki terenu.
*/
public int x;
/**
* Współrzędna X kwadratu w ramach siatki terenu.
*/
public int y;
/**
* Suma wysokości z punktów "wpadających" do tego kwadratu.
*/
public double sum;
/**
* Licznik punktów "wpadających" do tego kwadratu.
*/
public int count;
//
// Granice kwadratu wyrażone za pomocą współrzędnych PUWG1992 używanych w danych NMT.
//
/**
* Wpółrzędne PUWG1992 easting lewego dolnego wierzchołka.
*/
public double ell;
/**
* Wpółrzędne PUWG1992 northing lewego dolnego wierzchołka.
*/
public double nll;
/**
* Wpółrzędne PUWG1992 easting prawego górnego wierzchołka.
*/
public double eur;
/**
* Wpółrzędne PUWG1992 northing prawego górnego wierzchołka.
*/
public double nur;
public NmtData(int x, int y, double sum, int count) {
this.x = x;
this.y = y;
this.sum = sum;
this.count = count;
}
@Override
public String toString() {
return "NMTData{" +
"x=" + x +
", y=" + y +
", sum=" + sum +
", count=" + count +
", ell=" + ell +
", nll=" + nll +
", eur=" + eur +
", nur=" + nur +
'}';
}
}

View File

@@ -6,81 +6,170 @@ import pl.wat.ms4ds.terrain.*;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.util.concurrent.*;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
public class NMTDataReader { /**
* Klasa odpowiedzialna za generowanie danych wysokościowych w przyjętym formacie (sieci kwadratów) na podstawie
* pobranych danych NMT (spakowane w plikach o nazwach skorowidzów).
*/
public class NmtDataGenerator {
private static final Logger logger = LoggerFactory.getLogger(NMTDataReader.class); private static final Logger logger = LoggerFactory.getLogger(NmtDataGenerator.class);
static void main(String[] args) { static void main(String[] args) {
String[] splitted = "b a, e, l.d u, n g".split("\\s+|,\\s*|\\.\\s*"); /*
// File dir = new File(System.getProperty("user.home") + "/nmt/gugik_SkorowidzNMT2018.gml"); * Generowanie danych terenowych odbywa się na podstawie plików z danymi NMT w dwóch formatach:
// Dzieli na podstringi biorąc jako znak podziału spację i jej wielokrotność * ASC (siatka/tabela wysokość) TXT (współrzędne geo, wysokość). Pliki spakowane.
String[] splitted2 = "b a e l.d u n g".split("[ ]+"); * Pliki znajdują się w lokalizacji określonej przez "inDir" w katalogach (odpowiadających skorowidzom).
* W katalogu "idDir" znajdują się pliki textowe z listą nazw plików w podkatalogach skorowidzowych.
* Dane wysokościowe z plików NMT przetwarzane współbieżnie przez executora.
* W ramach tego etapu/wątku:
* 1. pliki rozpakowywane do katalogu roboczego "workDir",
* 2. po czym następuje ich odczyt i zapamiętanie danych szczegółowych w obiektach
* NMTData (suma wysokości, licznik, granice kwadratu terenu we współrzędnych PUWG1992),
* 3. obiekty NMTData (odpowiadające kwadratom terenu) cachowane w hashmapie
* indywidualnie w ramach wątku executora.
* 4. po zakończeniu odczytu plik jest usuwany,
* 5. następnie dane zagregowane (średnie wysokości) zapisywane do kwadratów terenu
* (zapis w kwadratach jest synchronizowany).
*
* Wątki synchronizowane po tym etapie w celu zrzucenia zaktualizowanych danych na dysk.
*
*/
String fn_list = "D:/work/nmt/m-33_files.txt"; String inDir = "D:/work/nmt/";
String inDir = "D:/work/nmt/m-33/";
String workDir = "D:/work/temp/"; String workDir = "D:/work/temp/";
String outDir = "D:/work/kwadraty_nmt/withElevation/25m/"; String outDir = "D:/work/kwadraty_nmt/temp/100m/";
Thread t = new Thread(() -> { ArrayList<String> list = new ArrayList<>();
generateNMTData(fn_list, 0, 24000, inDir, workDir, outDir); list.add("m-33");
}); list.add("m-34");
// HashMap<Coord.Grid, NMTData> nmtDataHashMap = new HashMap<>(); list.add("m-35");
// try { list.add("n-33");
// readFromFile(workDir + "73232_990195_NMT-M3492Ad33.xyz", nmtDataHashMap); list.add("n-34");
// } catch (IOException e) { ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
// return;
// }
// generateNMTData(workDir, workDir, outDir);
t.start();
// t2.start();
Scanner s = new Scanner(System.in);
// exit for (int i = 0; i < list.size(); i++) {
// String fn_list = inDir + list.get(i) + "_files.txt";
String s1; generateNMTData(executor, fn_list, 0, 24000, inDir + list.get(i) + "/", workDir, outDir);
while (true) {
s1 = s.nextLine();
if (s1.equals("exit")) {
stop();
break;
}
}
try {
System.out.println("Czekam");
t.join();
} catch (InterruptedException e) {
} }
System.out.println("End."); System.out.println("End.");
// renameFiles2(inDir, inDir);
// Set<String> files = NMTDataProvider.listFiles(inDir);
// Object[] array = files.stream().sorted().toArray();
// String[] fnames = new String[files.size()];
// for (int i = 0; i < fnames.length; i++) {
// fnames[i] = (String) array[i];
// }
// try {
// saveFileList("D:/work/nmt/asc_n-34_files.txt", fnames);
// } catch (IOException e) {
//
// }
} }
static volatile boolean stop = false; /**
* Generuje dane na podstawie listy spakowanych (zip) plików z podanego katalogu.
static synchronized boolean isStopped() { *
return stop; * @param fn_list
} * @param startPos
* @param endPos
static synchronized void stop() { * @param inDir
stop = true; * @param workDir
* @param outDir
*/
static void generateNMTData(ExecutorService executor, String fn_list, int startPos, int endPos, String inDir, String workDir, String outDir) {
final int TN = 8;
File file = new File(fn_list);
ArrayList<String> fileNames = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
String line;
while ((line = br.readLine()) != null) {
fileNames.add(line);
}
} catch (IOException e) {
return;
}
int count = 0;
int i = startPos;
ArrayList<Future> futures = new ArrayList<>();
while (i < endPos) {
if (i >= fileNames.size()) {
break;
}
int j;
for (j = 0; j < TN; j++) {
if (i >= fileNames.size()) {
break;
}
// asynchroniczne wywołanie zadania
int ii = i;
i++;
Future future = executor.submit(() -> {
long start = System.currentTimeMillis();
String fn = fileNames.get(ii);
File f = null;
String[] unzippedFileNames = null;
try {
unzippedFileNames = unzipFile(inDir + fn, workDir);
} catch (IOException e) {
logger.warn("IO error while processing zip file: {}", inDir + fn);
} catch (Exception e) {
logger.warn(e.getMessage());
}
HashMap<Coord.Grid, NmtData> nmtDataHashMap = new HashMap<>();
for (String ufn : unzippedFileNames) {
String fpath = workDir + ufn;
try {
f = new File(fpath);
if (f.length() < 10) {
logger.warn("File: {} is empty.", ufn);
continue;
}
readFromFile(fpath, nmtDataHashMap);
} catch (Exception e) {
logger.warn("Error while reading from file: {}.", ufn);
} finally {
if (f != null) {
f.delete();
}
}
}
for (Coord.Grid gridCoord : nmtDataHashMap.keySet()) {
NmtData nmtData = nmtDataHashMap.get(gridCoord);
if (nmtData.count > 0) {
Square square = Teren.getSquare(gridCoord.x, gridCoord.y);
if (square == Square.EMPTY) {
continue;
}
synchronized (square) {
square.elevation = (float) (nmtData.sum / nmtData.count);
// Zaokrąglenie do ćwiartki metra (0.0, 0.25, 0.5, 0.75)
//
square.elevation *= 4;
square.elevation = (int) square.elevation;
square.elevation /= 4;
if (H_MIN >= square.elevation || H_MAX <= square.elevation) {
logger.trace("!!!Dane poza zakresem: h= {}", square.elevation);
}
}
}
}
nmtDataHashMap.clear();
logger.debug("File processed: {}, duration= {}[ms], status: {}/{}", fn, System.currentTimeMillis() - start, ii, endPos - 1);
});
futures.add(future);
}
count += j;
// Punkt synchronizacyjny.
for (Future future : futures) {
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
logger.warn("Error in thread: {}", e.getMessage());
}
}
futures.clear();
if (count % 2000 == 0) {
Teren.saveToFiles(outDir);
}
}
Teren.saveToFiles(outDir);
logger.info("Finished processing file list: {}", fn_list);
} }
/** /**
@@ -91,8 +180,8 @@ public class NMTDataReader {
* @param outDir * @param outDir
*/ */
static void generateNMTData(String inDir, String workDir, String outDir) { static void generateNMTData(String inDir, String workDir, String outDir) {
Set<String> files = NMTDataProvider.listFiles(inDir); Set<String> files = NmtDataProvider.listFiles(inDir);
HashMap<Coord.Grid, NMTData> nmtDataHashMap = new HashMap<>(); HashMap<Coord.Grid, NmtData> nmtDataHashMap = new HashMap<>();
for (String fn : files) { for (String fn : files) {
String fpath = workDir + fn; String fpath = workDir + fn;
try { try {
@@ -109,8 +198,8 @@ public class NMTDataReader {
} }
} }
for (Coord.Grid gridCoord : nmtDataHashMap.keySet()) { for (Coord.Grid gridCoord : nmtDataHashMap.keySet()) {
NMTData nmtData = nmtDataHashMap.get(gridCoord); NmtData nmtData = nmtDataHashMap.get(gridCoord);
Square square = Teren.getKwadrat(gridCoord.x, gridCoord.y); Square square = Teren.getSquare(gridCoord.x, gridCoord.y);
if (square == Square.EMPTY) { if (square == Square.EMPTY) {
continue; continue;
} }
@@ -129,115 +218,6 @@ public class NMTDataReader {
Teren.saveToFiles(outDir); Teren.saveToFiles(outDir);
} }
/**
* Generuje dane na podstawie listy spakowanych (zip) plików z podanego katalogu.
*
* @param fn_list
* @param startPos
* @param endPos
* @param inDir
* @param workDir
* @param outDir
*/
static void generateNMTData(String fn_list, int startPos, int endPos, String inDir, String workDir, String outDir) {
File file = new File(fn_list);
ArrayList<String> fileNames = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
String line;
while ((line = br.readLine()) != null) {
fileNames.add(line);
}
} catch (IOException e) {
return;
}
HashMap<Coord.Grid, NMTData> nmtDataHashMap = new HashMap<>();
int count = 0;
for (int i = startPos; i < endPos; i++) {
count++;
long start = System.currentTimeMillis();
if (i >= fileNames.size()) {
break;
}
String fn = fileNames.get(i);
File f = null;
String[] unzippedFileNames = null;
try {
unzippedFileNames = unzipFile(inDir + fn, workDir);
} catch (IOException e) {
logger.warn("IO error while processing zip file: {}", inDir + fn);
try (BufferedWriter writer = new BufferedWriter(new FileWriter("D:/Work/nmt/status.txt", true))) {
writer.write("Error while processing zip file: " + fileNames.get(i) + " at position: " + i + "\n");
} catch (IOException e1) {
logger.debug(e1.getMessage());
}
} catch (Exception e) {
logger.warn(e.getMessage());
}
for (String ufn : unzippedFileNames) {
String fpath = workDir + ufn;
try {
readFromFile(fpath, nmtDataHashMap);
f = new File(fpath);
f.delete();
} catch (Exception e) {
if (f.length() < 10) {
logger.warn("File: {} is empty.", ufn);
f.delete();
} else {
logger.warn("Error while reading from file: {}.", ufn);
try (BufferedWriter writer = new BufferedWriter(new FileWriter("D:/Work/nmt/status.txt", true))) {
writer.write("Error while reading file: " + ufn + " at position: " + i + "\n");
} catch (IOException e1) {
logger.debug(e1.getMessage());
}
}
}
}
logger.debug("File processed: {}, duration= {}[ms], status: {}/{}", fn, System.currentTimeMillis() - start, i, endPos - 1);
for (Coord.Grid gridCoord : nmtDataHashMap.keySet()) {
NMTData nmtData = nmtDataHashMap.get(gridCoord);
Square square = Teren.getKwadrat(gridCoord.x, gridCoord.y);
if (square == Square.EMPTY) {
continue;
}
if (nmtData.count > 0) {
square.elevation = (float) (nmtData.sum / nmtData.count);
// Zaokrąglenie do ćwiartki metra (0.0, 0.25, 0.5, 0.75)
//
square.elevation *= 4;
square.elevation = (int) square.elevation;
square.elevation /= 4;
if (H_MIN >= square.elevation || H_MAX <= square.elevation) {
logger.trace("!!!Dane poza zakresem: h= {}", square.elevation);
}
}
}
nmtDataHashMap.clear();
if (count % 2000 == 0) {
Teren.saveToFiles(outDir);
}
// Reakcja na wymuszenie zakończenia przetwarzania.
if (isStopped()) {
Teren.saveToFiles(outDir);
try (BufferedWriter writer = new BufferedWriter(new FileWriter("D:/Work/nmt/status.txt", true))) {
writer.write("Work interrupted with the file list: " + fn_list + ", last processed file: " + fileNames.get(i) + " at position: " + i + "\n");
} catch (IOException e) {
logger.error(e.getMessage());
}
logger.info("Interrupted processing file list: {}", fn_list);
return;
}
}
Teren.saveToFiles(outDir);
try (BufferedWriter writer = new BufferedWriter(new FileWriter("D:/Work/nmt/status.txt", true))) {
int last = Math.min(fileNames.size() - 1, endPos);
writer.write("Work finished with the file list: " + fn_list + ", last processed file: " + fileNames.get(last) + " at position: " + last + "\n");
} catch (IOException e) {
logger.error(e.getMessage());
}
logger.info("Finished processing file list: {}", fn_list);
}
private static void saveFileList(String fn, String[] fileList) throws IOException { private static void saveFileList(String fn, String[] fileList) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(fn)); BufferedWriter writer = new BufferedWriter(new FileWriter(fn));
for (String val : fileList) { for (String val : fileList) {
@@ -249,7 +229,7 @@ public class NMTDataReader {
// usuwanie z nazwy nadmiarowych rozszerz przed rozszerzeniem // usuwanie z nazwy nadmiarowych rozszerz przed rozszerzeniem
static void renameFiles(String inDir, String outDir) { static void renameFiles(String inDir, String outDir) {
Set<String> fileNames = NMTDataProvider.listFiles(inDir); Set<String> fileNames = NmtDataProvider.listFiles(inDir);
for (String fn : fileNames) { for (String fn : fileNames) {
String nfn = fn.substring(0, fn.indexOf('.')); String nfn = fn.substring(0, fn.indexOf('.'));
File fileToMove = new File(inDir + fn); File fileToMove = new File(inDir + fn);
@@ -263,7 +243,7 @@ public class NMTDataReader {
// dodanie 0 do liczb dla wyrównania długości // dodanie 0 do liczb dla wyrównania długości
static void renameFiles2(String inDir, String outDir) { static void renameFiles2(String inDir, String outDir) {
Set<String> fileNames = NMTDataProvider.listFiles(inDir); Set<String> fileNames = NmtDataProvider.listFiles(inDir);
for (String fn : fileNames) { for (String fn : fileNames) {
if (fn.length() >= 20) { if (fn.length() >= 20) {
continue; continue;
@@ -294,7 +274,7 @@ public class NMTDataReader {
} }
} }
private static void readFromFile(String fn, HashMap<Coord.Grid, NMTData> nmtDataHashMap) throws IOException { private static void readFromFile(String fn, HashMap<Coord.Grid, NmtData> nmtDataHashMap) throws IOException {
File file = new File(fn); File file = new File(fn);
InputStream inputStream = new FileInputStream(file); InputStream inputStream = new FileInputStream(file);
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
@@ -314,10 +294,10 @@ public class NMTDataReader {
} }
} }
static final int H_MIN = -70; public static final int H_MIN = -70;
static final int H_MAX = 2660; public static final int H_MAX = 2660;
private static void readASC(BufferedReader br, String firstLine, HashMap<Coord.Grid, NMTData> nmtDataHashMap) throws IOException { private static void readASC(BufferedReader br, String firstLine, HashMap<Coord.Grid, NmtData> nmtDataHashMap) throws IOException {
String line = firstLine; String line = firstLine;
// Dzieli na podstringi biorąc jako znak podziału spację i jej wielokrotność // Dzieli na podstringi biorąc jako znak podziału spację i jej wielokrotność
// nawias kwadratowy zawiera znaki podziału // nawias kwadratowy zawiera znaki podziału
@@ -363,7 +343,7 @@ public class NMTDataReader {
s = line.substring(start); s = line.substring(start);
data[i][ncols - 1] = Double.parseDouble(s); data[i][ncols - 1] = Double.parseDouble(s);
} }
NMTData nmtData = new NMTData(-1, -1, 0, 0); NmtData nmtData = new NmtData(-1, -1, 0, 0);
Coord.Geo geoCoord = new Coord.Geo(); Coord.Geo geoCoord = new Coord.Geo();
Coord.Puwg puwgCoord = new Coord.Puwg(); Coord.Puwg puwgCoord = new Coord.Puwg();
double h; double h;
@@ -382,33 +362,28 @@ public class NMTDataReader {
if (nmtData.ell > x_puwg || nmtData.eur < x_puwg || nmtData.nll > y_puwg || nmtData.nur < y_puwg) { if (nmtData.ell > x_puwg || nmtData.eur < x_puwg || nmtData.nll > y_puwg || nmtData.nur < y_puwg) {
// Punkt poza granicą bieżącego kwadratu. // Punkt poza granicą bieżącego kwadratu.
Coord.convertPUWG1992ToWGS84(y_puwg, x_puwg, geoCoord); Coord.convertPUWG1992ToWGS84(y_puwg, x_puwg, geoCoord);
x = Coord.zamienDlugoscGeoNaIdKwadratuX(geoCoord.lon); x = Coord.convertLonToGridX(geoCoord.lon);
y = Coord.zamienSzerokoscGeoNaIdKwadratuY(geoCoord.lat); y = Coord.convertLatToGridY(geoCoord.lat);
final int x1 = x; final int x1 = x;
final int y1 = y; final int y1 = y;
nmtData = nmtDataHashMap.computeIfAbsent(new Coord.Grid(x, y), k -> new NMTData(x1, y1, 0, 0)); nmtData = nmtDataHashMap.computeIfAbsent(new Coord.Grid(x, y), k -> new NmtData(x1, y1, 0, 0));
if (nmtData.nur == 0) { if (nmtData.nur == 0) {
// Kwadrat jeszcze nie był odczytany (czysty). // Kwadrat jeszcze nie był odczytany (czysty).
// Współrzędne geo środka kwadratu. // Współrzędne geo środka kwadratu.
geoCoord.lon = Coord.zamienIdKwadratuXNaDlugoscGeo(x); geoCoord.lon = Coord.convertGridXToLon(x);
geoCoord.lat = Coord.zamienIdKwadratuYNaSzerokoscGeo(y); geoCoord.lat = Coord.covertGridYToLat(y);
// Wyznacz współrzędne PUWG lewego dolnego rogu kwadratu. // Wyznacz współrzędne PUWG lewego dolnego rogu kwadratu.
Coord.convertWGS84ToPUWG1992(geoCoord.lat - MapConsts.DELTA_Y / 2, geoCoord.lon - MapConsts.DELTA_X / 2, puwgCoord); Coord.convertWGS84ToPUWG1992(geoCoord.lat - MapConsts.SS_DELTA_LAT / 2, geoCoord.lon - MapConsts.SS_DELTA_LON / 2, puwgCoord);
nmtData.ell = (int) puwgCoord.easting; nmtData.ell = (int) puwgCoord.easting;
nmtData.nll = (int) puwgCoord.northing; nmtData.nll = (int) puwgCoord.northing;
// Wyznacz współrzędne PUWG prawego górnego rogu kwadratu. // Wyznacz współrzędne PUWG prawego górnego rogu kwadratu.
Coord.convertWGS84ToPUWG1992(geoCoord.lat + MapConsts.DELTA_Y / 2, geoCoord.lon + MapConsts.DELTA_X / 2, puwgCoord); Coord.convertWGS84ToPUWG1992(geoCoord.lat + MapConsts.SS_DELTA_LAT / 2, geoCoord.lon + MapConsts.SS_DELTA_LON / 2, puwgCoord);
nmtData.eur = (int) puwgCoord.easting; nmtData.eur = (int) puwgCoord.easting;
nmtData.nur = (int) puwgCoord.northing; nmtData.nur = (int) puwgCoord.northing;
} }
} }
if (H_MIN < h && h < H_MAX) { nmtData.sum += h;
// Filtracja danych z rozsądnego zakresu dla Polski. nmtData.count++;
nmtData.sum += h;
nmtData.count++;
} else {
logger.trace("!!!Dane poza zakresem: h= {}, [i,j]=[{},{}]", h, i, j);
}
// Przejdź do następnej kolumny. // Przejdź do następnej kolumny.
x_puwg += cellsize; x_puwg += cellsize;
} }
@@ -417,7 +392,7 @@ public class NMTDataReader {
} }
} }
private static void readXYZ(BufferedReader br, String firstLine, HashMap<Coord.Grid, NMTData> nmtDataHashMap) throws IOException { private static void readXYZ(BufferedReader br, String firstLine, HashMap<Coord.Grid, NmtData> nmtDataHashMap) throws IOException {
Coord.Puwg puwgCoord = new Coord.Puwg(); Coord.Puwg puwgCoord = new Coord.Puwg();
Coord.Geo geo = new Coord.Geo(); Coord.Geo geo = new Coord.Geo();
String line = firstLine; String line = firstLine;
@@ -433,7 +408,7 @@ public class NMTDataReader {
double h; double h;
int x; int x;
int y; int y;
NMTData nmtData = new NMTData(-1, -1, 0, 0); NmtData nmtData = new NmtData(-1, -1, 0, 0);
int start; int start;
int end; int end;
int row = 0; int row = 0;
@@ -466,33 +441,28 @@ public class NMTDataReader {
if (nmtData.ell > x_puwg || nmtData.eur < x_puwg || nmtData.nll > y_puwg || nmtData.nur < y_puwg) { if (nmtData.ell > x_puwg || nmtData.eur < x_puwg || nmtData.nll > y_puwg || nmtData.nur < y_puwg) {
// Punkt poza granicą bieżącego kwadratu. // Punkt poza granicą bieżącego kwadratu.
Coord.convertPUWG1992ToWGS84(y_puwg, x_puwg, geo); Coord.convertPUWG1992ToWGS84(y_puwg, x_puwg, geo);
x = Coord.zamienDlugoscGeoNaIdKwadratuX(geo.lon); x = Coord.convertLonToGridX(geo.lon);
y = Coord.zamienSzerokoscGeoNaIdKwadratuY(geo.lat); y = Coord.convertLatToGridY(geo.lat);
final int x1 = x; final int x1 = x;
final int y1 = y; final int y1 = y;
nmtData = nmtDataHashMap.computeIfAbsent(new Coord.Grid(x1, y1), k -> new NMTData(x1, y1, 0, 0)); nmtData = nmtDataHashMap.computeIfAbsent(new Coord.Grid(x1, y1), k -> new NmtData(x1, y1, 0, 0));
if (nmtData.nur == 0) { if (nmtData.nur == 0) {
// Kwadrat jeszcze nie był odczytany (czysty). // Kwadrat jeszcze nie był odczytany (czysty).
// Współrzędne geo środka kwadratu. // Współrzędne geo środka kwadratu.
geo.lon = Coord.zamienIdKwadratuXNaDlugoscGeo(x); geo.lon = Coord.convertGridXToLon(x);
geo.lat = Coord.zamienIdKwadratuYNaSzerokoscGeo(y); geo.lat = Coord.covertGridYToLat(y);
// Wyznacz współrzędne PUWG lewego dolnego rogu kwadratu. // Wyznacz współrzędne PUWG lewego dolnego rogu kwadratu.
Coord.convertWGS84ToPUWG1992(geo.lat - MapConsts.DELTA_Y / 2, geo.lon - MapConsts.DELTA_X / 2, puwgCoord); Coord.convertWGS84ToPUWG1992(geo.lat - MapConsts.SS_DELTA_LAT / 2, geo.lon - MapConsts.SS_DELTA_LON / 2, puwgCoord);
nmtData.ell = (int) puwgCoord.easting; nmtData.ell = (int) puwgCoord.easting;
nmtData.nll = (int) puwgCoord.northing; nmtData.nll = (int) puwgCoord.northing;
// Wyznacz współrzędne PUWG prawego górnego rogu kwadratu. // Wyznacz współrzędne PUWG prawego górnego rogu kwadratu.
Coord.convertWGS84ToPUWG1992(geo.lat + MapConsts.DELTA_Y / 2, geo.lon + MapConsts.DELTA_X / 2, puwgCoord); Coord.convertWGS84ToPUWG1992(geo.lat + MapConsts.SS_DELTA_LAT / 2, geo.lon + MapConsts.SS_DELTA_LON / 2, puwgCoord);
nmtData.eur = (int) puwgCoord.easting; nmtData.eur = (int) puwgCoord.easting;
nmtData.nur = (int) puwgCoord.northing; nmtData.nur = (int) puwgCoord.northing;
} }
} }
if (H_MIN < h && h < H_MAX) { nmtData.sum += h;
// Filtracja danych z rozsądnego zakresu dla Polski. nmtData.count++;
nmtData.sum += h;
nmtData.count++;
} else {
logger.trace("!!!Dane poza zakresem: h= {}, row={}", h, row);
}
line = br.readLine(); line = br.readLine();
row++; row++;
} }

View File

@@ -18,8 +18,11 @@ import java.util.stream.Stream;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
public class NMTDataProvider { /**
private static final Logger LOGGER = LoggerFactory.getLogger(NMTDataProvider.class); * Klasa odpowiedzialna za pozyskanie danych wysokościowych (NMT) ze stron geoportal.
*/
public class NmtDataProvider {
private static final Logger LOGGER = LoggerFactory.getLogger(NmtDataProvider.class);
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@@ -35,7 +38,7 @@ public class NMTDataProvider {
// HashMap<String, String> map = new HashMap<>(); // HashMap<String, String> map = new HashMap<>();
// String fn0 = "D:/nmt/gugik_SkorowidzNMT20"; // String fn0 = "D:/nmt/gugik_SkorowidzNMT20";
// for (int i = 18; i < 26; i++) { // for (int i = 18; i < 26; i++) {
// readFileLinksFromGUGiKxml(fn0 + i + ".gml", map); // readFileLinksFromGugikXml(fn0 + i + ".gml", map);
// } // }
// saveLinks("D:/nmt/gugik_links.txt", map); // saveLinks("D:/nmt/gugik_links.txt", map);
@@ -161,7 +164,7 @@ public class NMTDataProvider {
// Funkcja wykorzystana jednokrotnie w celu integracji w jednym pliku wszystkich linków // Funkcja wykorzystana jednokrotnie w celu integracji w jednym pliku wszystkich linków
// do zasobów rozproszonych w wielu plikach. // do zasobów rozproszonych w wielu plikach.
private static void readFileLinksFromGUGiKxml(String fn, HashMap<String, String> map) throws Exception { private static void readFileLinksFromGugikXml(String fn, HashMap<String, String> map) throws Exception {
XMLInputFactory factory = XMLInputFactory.newInstance(); XMLInputFactory factory = XMLInputFactory.newInstance();
FileInputStream is = new FileInputStream(fn); FileInputStream is = new FileInputStream(fn);
BufferedInputStream bis = new BufferedInputStream(is); BufferedInputStream bis = new BufferedInputStream(is);

View File

@@ -1,12 +1,8 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pl.wat.ms4ds.terrain.Coord; import pl.wat.ms4ds.terrain.Coord;
import pl.wat.ms4ds.terrain.MapConsts;
import java.io.*;
import java.nio.ByteBuffer;
public class CoordTest { public class CoordTest {
static Logger logger = LoggerFactory.getLogger(CoordTest.class); static Logger logger = LoggerFactory.getLogger(CoordTest.class);

View File

@@ -1,10 +1,10 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
import pl.wat.ms4ds.terrain.Coord; import pl.wat.ms4ds.terrain.Coord;
import pl.wat.ms4ds.terrain.Teren; import pl.wat.ms4ds.terrain.Teren;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pl.wat.ms4ds.terrain.nmt.NMTData; import pl.wat.ms4ds.terrain.nmt.NmtData;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.FileReader; import java.io.FileReader;
@@ -26,7 +26,7 @@ public class CoordUtils {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
HashMap<Coord.Grid, NMTData> daneWysokHashMap = new HashMap(); HashMap<Coord.Grid, NmtData> daneWysokHashMap = new HashMap();
if (args.length > 0) { if (args.length > 0) {
dataDir = args[0]; dataDir = args[0];
} }
@@ -34,7 +34,7 @@ public class CoordUtils {
String nmt_fn = args[i]; String nmt_fn = args[i];
daneWysokHashMap.clear(); daneWysokHashMap.clear();
readData(nmt_fn, daneWysokHashMap); readData(nmt_fn, daneWysokHashMap);
for (NMTData daneWysok : daneWysokHashMap.values()) { for (NmtData daneWysok : daneWysokHashMap.values()) {
// Square kw = Teren.getKwadrat(daneWysok.idKw.x, daneWysok.idKw.y); // Square kw = Teren.getKwadrat(daneWysok.idKw.x, daneWysok.idKw.y);
// kw.setWysokoscSrednia((int) (daneWysok.suma / daneWysok.licz + 0.5)); // kw.setWysokoscSrednia((int) (daneWysok.suma / daneWysok.licz + 0.5));
} }
@@ -43,14 +43,11 @@ public class CoordUtils {
logger.debug("Koniec zapisu danych dla regionu " + nmt_fn + " >> " + i + "/" + (args.length - 1)); logger.debug("Koniec zapisu danych dla regionu " + nmt_fn + " >> " + i + "/" + (args.length - 1));
Teren.reset(); Teren.reset();
} }
logger.debug("Start: poprawy danych wysokosciowych");
Teren.poprawDaneWysokosciowe();
logger.debug("Koniec: poprawy danych wysokosciowych");
} }
private static void readData(String fileName, HashMap<Coord.Grid, NMTData> daneWysokHashMap) throws IOException { private static void readData(String fileName, HashMap<Coord.Grid, NmtData> daneWysokHashMap) throws IOException {
try { try {
StringBuilder sb = new StringBuilder(100); StringBuilder sb = new StringBuilder(100);
sb.append(dataDir); sb.append(dataDir);
@@ -93,9 +90,9 @@ public class CoordUtils {
} }
Coord.convertPUWG1992ToWGS84(puwgCoord.northing, puwgCoord.easting, latLon); Coord.convertPUWG1992ToWGS84(puwgCoord.northing, puwgCoord.easting, latLon);
Coord.Grid idKw = new Coord.Grid(latLon.lon, latLon.lat); Coord.Grid idKw = new Coord.Grid(latLon.lon, latLon.lat);
NMTData daneWysok = daneWysokHashMap.get(idKw); NmtData daneWysok = daneWysokHashMap.get(idKw);
if (daneWysok == null) { if (daneWysok == null) {
daneWysok = new NMTData(idKw.x, idKw.y, wysokosc, 1); daneWysok = new NmtData(idKw.x, idKw.y, wysokosc, 1);
daneWysokHashMap.put(idKw, daneWysok); daneWysokHashMap.put(idKw, daneWysok);
} else { } else {
daneWysok.sum += wysokosc; daneWysok.sum += wysokosc;

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
public enum EAreaFeature { public enum EAreaFeature {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
public enum ELinearFeature { public enum ELinearFeature {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
public enum EOSMAmenity { public enum EOSMAmenity {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
public enum EOSMBridge { public enum EOSMBridge {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
public enum EOSMBuilding { public enum EOSMBuilding {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
public enum EOSMHighway { public enum EOSMHighway {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
public enum EOSMLandcover { public enum EOSMLandcover {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
public enum EOSMLanduse { public enum EOSMLanduse {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
public enum EOSMNatural { public enum EOSMNatural {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
public enum EOSMWater { public enum EOSMWater {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
public enum EOSMWaterway { public enum EOSMWaterway {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
import org.nocrala.tools.gis.data.esri.shapefile.ShapeFileReader; 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.ValidationPreferences;
@@ -88,19 +88,19 @@ public class EsriFileReader {
nodeId++; nodeId++;
currNode.lon = points[j].getX() + 180; currNode.lon = points[j].getX() + 180;
currNode.lat = points[j].getY() + 90; currNode.lat = points[j].getY() + 90;
if (currNode.lon >= MapConsts.X_REF && currNode.lon <= MapConsts.X_REF + MapConsts.DX_REF if (currNode.lon >= MapConsts.REF_LON && currNode.lon <= MapConsts.REF_LON + MapConsts.DELTA_LON_REF
&& currNode.lat >= MapConsts.Y_REF && currNode.lat <= MapConsts.Y_REF + MapConsts.DY_REF) { && currNode.lat >= MapConsts.REF_LAT && currNode.lat <= MapConsts.REF_LAT + MapConsts.DELTA_LAT_REF) {
jest_wezel_z_obszaru = true; jest_wezel_z_obszaru = true;
} }
currNode.lon = Math.max(currNode.lon, MapConsts.X_REF); currNode.lon = Math.max(currNode.lon, MapConsts.REF_LON);
currNode.lon = Math.min(currNode.lon, MapConsts.X_REF + MapConsts.DX_REF); currNode.lon = Math.min(currNode.lon, MapConsts.REF_LON + MapConsts.DELTA_LON_REF);
currNode.lon -= 180; currNode.lon -= 180;
currNode.lat = Math.max(currNode.lat, MapConsts.Y_REF); currNode.lat = Math.max(currNode.lat, MapConsts.REF_LAT);
currNode.lat = Math.min(currNode.lat, MapConsts.Y_REF + MapConsts.DY_REF); currNode.lat = Math.min(currNode.lat, MapConsts.REF_LAT + MapConsts.DELTA_LAT_REF);
currNode.lat -= 90; currNode.lat -= 90;
currNode.idX = Coord.zamienDlugoscGeoNaIdKwadratuX(currNode.lon); currNode.idX = Coord.convertLonToGridX(currNode.lon);
currNode.idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(currNode.lat); currNode.idY = Coord.convertLatToGridY(currNode.lat);
if (currNode.idX > 0 || currNode.idY > 0) { if (currNode.idX > 0 || currNode.idY > 0) {
currWay.nodes.add(currNode); currWay.nodes.add(currNode);
} }

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
/** /**
* *

View File

@@ -1,8 +1,9 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
import pl.wat.ms4ds.terrain.Square; import pl.wat.ms4ds.terrain.Square;
import pl.wat.ms4ds.terrain.MapConsts; import pl.wat.ms4ds.terrain.MapConsts;
import pl.wat.ms4ds.terrain.Teren; import pl.wat.ms4ds.terrain.Teren;
import pl.wat.ms4ds.terrain.TerrainType;
/** /**
* *
@@ -69,11 +70,8 @@ public class Node {
public void writeAreaFeatureIntoSquare(EAreaFeature type) { public void writeAreaFeatureIntoSquare(EAreaFeature type) {
if (buildingsCount >= BUILDINGS_COUNT) { if (buildingsCount >= BUILDINGS_COUNT) {
Square kw = Teren.getKwadrat(idX, idY); Square kw = Teren.getSquare(idX, idY);
kw.stopienZabudowy = 1.0f; kw.terrainType = TerrainType.BUILDINGS;
} else if (buildingsCount > 0) {
Square kw = Teren.getKwadrat(idX, idY);
kw.stopienZabudowy = 0.5f;
} }
} }

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
import pl.wat.ms4ds.terrain.Coord; import pl.wat.ms4ds.terrain.Coord;
import pl.wat.ms4ds.terrain.Teren; import pl.wat.ms4ds.terrain.Teren;
@@ -238,8 +238,8 @@ public class OpenStreetMapReader {
switch (reader.getLocalName()) { switch (reader.getLocalName()) {
case "node": case "node":
if (currNode != null) { if (currNode != null) {
currNode.idX = Coord.zamienDlugoscGeoNaIdKwadratuX(currNode.lon); currNode.idX = Coord.convertLonToGridX(currNode.lon);
currNode.idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(currNode.lat); currNode.idY = Coord.convertLatToGridY(currNode.lat);
if ("zabudowa".equals(genGoal) && currNode.buildingsCount > 0) { if ("zabudowa".equals(genGoal) && currNode.buildingsCount > 0) {
buildingNodesMap.put(currNode.id, currNode); buildingNodesMap.put(currNode.id, currNode);
} }

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
import pl.wat.ms4ds.common.EGeoDirection; import pl.wat.ms4ds.common.EGeoDirection;
import pl.wat.ms4ds.terrain.*; import pl.wat.ms4ds.terrain.*;
@@ -148,47 +148,47 @@ public class Way {
if (nodes.size() < 3) { if (nodes.size() < 3) {
return; return;
} }
boolean toDelete[] = new boolean[nodes.size()]; boolean[] toDelete = new boolean[nodes.size()];
Node node_i; Node curr_node;
Node node_i_next; Node next_node;
Node node_i_prev; Node prev_node;
boolean collinearFound = false; boolean collinearFound = false;
int dlMax = nodes.size(); int lenMax = nodes.size();
int iStart = 0; int iStart = 0;
if (!isPolygon) { if (!isPolygon) {
// łamana otwarta // łamana otwarta
dlMax = nodes.size() - 1; lenMax = nodes.size() - 1;
iStart = 1; iStart = 1;
} }
for (int i = iStart; i < dlMax; i++) { for (int curr = iStart; curr < lenMax; curr++) {
int i_plus_1 = (i + 1) % nodes.size(); int next = (curr + 1) % nodes.size();
int i_minus_1 = (i + nodes.size() - 1) % nodes.size(); int prev = (curr + nodes.size() - 1) % nodes.size();
node_i = nodes.get(i); curr_node = nodes.get(curr);
node_i_next = nodes.get(i_plus_1); next_node = nodes.get(next);
node_i_prev = nodes.get(i_minus_1); prev_node = nodes.get(prev);
if (GeomUtils.include(node_i_prev.idX, node_i_prev.idY, node_i_next.idX, node_i_next.idY, if (GeomUtils.include(prev_node.idX, prev_node.idY, next_node.idX, next_node.idY,
node_i.idX, node_i.idY)) { curr_node.idX, curr_node.idY)) {
// i-ty do usuniecia // i-ty do usuniecia
toDelete[i] = true; toDelete[curr] = true;
collinearFound = true; collinearFound = true;
} else if (GeomUtils.include(node_i.idX, node_i.idY, node_i_next.idX, node_i_next.idY, } else if (GeomUtils.include(curr_node.idX, curr_node.idY, next_node.idX, next_node.idY,
node_i_prev.idX, node_i_prev.idY)) { prev_node.idX, prev_node.idY)) {
// i-1-ty do usuniecia // i-1-ty do usuniecia
toDelete[i_minus_1] = true; toDelete[prev] = true;
collinearFound = true; collinearFound = true;
} else if (GeomUtils.include(node_i_prev.idX, node_i_prev.idY, node_i.idX, node_i.idY, } else if (GeomUtils.include(prev_node.idX, prev_node.idY, curr_node.idX, curr_node.idY,
node_i_next.idX, node_i_next.idY)) { next_node.idX, next_node.idY)) {
// i+1-ty do usuniecia // i+1-ty do usuniecia
toDelete[i_plus_1] = true; toDelete[next] = true;
collinearFound = true; collinearFound = true;
} }
} }
if (collinearFound) { if (collinearFound) {
ArrayList<Node> newList = new ArrayList<Node>(); ArrayList<Node> newList = new ArrayList<Node>();
for (int i = 0; i < nodes.size(); i++) { for (int i = 0; i < nodes.size(); i++) {
node_i = nodes.get(i); curr_node = nodes.get(i);
if (!toDelete[i]) { if (!toDelete[i]) {
newList.add(node_i); newList.add(curr_node);
} }
} }
// logger.trace("Liczba oryg. wezlow= {}, liczba niewspolliniowych wezlow= {}, roznica= {}", nodes.size(), newList.size(), nodes.size() - newList.size()); // logger.trace("Liczba oryg. wezlow= {}, liczba niewspolliniowych wezlow= {}, roznica= {}", nodes.size(), newList.size(), nodes.size() - newList.size());
@@ -203,20 +203,20 @@ public class Way {
} }
boolean toDelete[] = new boolean[nodes.size()]; boolean toDelete[] = new boolean[nodes.size()];
Node node_i; Node node_i;
Node node_j; Node node_ii;
Node node_k; Node node_iii;
boolean bylSchodek = false; boolean bylSchodek = false;
for (int i = 0; i < nodes.size() - 2; i++) { for (int i = 0; i < nodes.size() - 2; i++) {
node_i = nodes.get(i); node_i = nodes.get(i);
node_j = nodes.get(i + 1); node_ii = nodes.get(i + 1);
node_k = nodes.get(i + 2); node_iii = nodes.get(i + 2);
int absX_i_j = Math.abs(node_j.idX - node_i.idX); int absX_i_ii = Math.abs(node_ii.idX - node_i.idX);
int absY_i_j = Math.abs(node_j.idY - node_i.idY); int absY_i_ii = Math.abs(node_ii.idY - node_i.idY);
int absX_j_k = Math.abs(node_k.idX - node_j.idX); int absX_ii_iii = Math.abs(node_iii.idX - node_ii.idX);
int absY_j_k = Math.abs(node_k.idY - node_j.idY); int absY_ii_iii = Math.abs(node_iii.idY - node_ii.idY);
if (absX_i_j + absY_i_j + absX_j_k + absY_j_k == 2) { if (absX_i_ii + absY_i_ii + absX_ii_iii + absY_ii_iii == 2) {
// wezly moga tworzyc schodek // wezly moga tworzyc schodek
if (absX_i_j + absX_j_k == 1) { if (absX_i_ii + absX_ii_iii == 1) {
// wezly tworza schodek, zatem srodkowy wezel schodka do usuniecia // wezly tworza schodek, zatem srodkowy wezel schodka do usuniecia
toDelete[i + 1] = true; toDelete[i + 1] = true;
bylSchodek = true; bylSchodek = true;
@@ -253,27 +253,27 @@ public class Way {
Coord.Grid id0; Coord.Grid id0;
Coord.Grid id1; Coord.Grid id1;
EGeoDirection kier; EGeoDirection kier;
Coord.Grid[] kwadraty = GeomUtils.kwadratyLamanej2(punktyLamanej); Coord.Grid[] kwadraty = GeomUtils.generateSquaresOfSegments(punktyLamanej);
// float dlug = GeomUtils.dlugoscDrogiPoKwadratch(kwadraty); // float dlug = GeomUtils.dlugoscDrogiPoKwadratch(kwadraty);
for (int i = 0; i < kwadraty.length - 1; i++) { for (int i = 0; i < kwadraty.length - 1; i++) {
try { try {
id0 = kwadraty[i]; id0 = kwadraty[i];
kw0 = Teren.getKwadrat(id0.x, id0.y); kw0 = Teren.getSquare(id0.x, id0.y);
id1 = kwadraty[i + 1]; id1 = kwadraty[i + 1];
kw1 = Teren.getKwadrat(id1.x, id1.y); kw1 = Teren.getSquare(id1.x, id1.y);
kier = GeomUtils.kierunekDlaSasiada(id0, id1); kier = GeomUtils.kierunekDlaSasiada(id0, id1);
switch (type) { switch (type) {
case ROAD: case ROAD:
kw0.jestDroga[kier.id] = true; kw0.roads[kier.id] = 2;
kw0.jestDroga[kier.oppositeDirect().id] = true; kw0.roads[kier.oppositeDirect().id] = 2;
break; break;
case WATER_WAY: case WATER_WAY:
kw0.jestPrzeszkodaWodna[kier.id] = true; kw0.watercourses[kier.id] = 3;
kw0.jestPrzeszkodaWodna[kier.oppositeDirect().id] = true; kw0.watercourses[kier.oppositeDirect().id] = 3;
break; break;
case DITCH: case DITCH:
kw0.jestRow[kier.id] = true; kw0.watercourses[kier.id] = 1;
kw0.jestRow[kier.oppositeDirect().id] = true; kw0.watercourses[kier.oppositeDirect().id] = 1;
break; break;
default: default:
} }
@@ -347,30 +347,27 @@ public class Way {
maxX = Math.max(polygon[i].x, maxX); maxX = Math.max(polygon[i].x, maxX);
maxY = Math.max(polygon[i].y, maxY); maxY = Math.max(polygon[i].y, maxY);
} }
Coord.Grid idTest = new Coord.Grid();
boolean inside; boolean inside;
for (int j = maxY; j >= minY; j--) { for (int y = maxY; y >= minY; y--) {
for (int i = minX; i <= maxX; i++) { for (int x = minX; x <= maxX; x++) {
idTest.x = i; Square kw = Teren.getSquare(x, y);
idTest.y = j;
Square kw = Teren.getKwadrat(idTest.x, idTest.y);
if (kw == Square.EMPTY) { if (kw == Square.EMPTY) {
continue; continue;
} }
inside = GeomUtils.insidePolygon(polygon, idTest); inside = GeomUtils.insidePolygon(polygon, x, y);
if (inside) { if (inside) {
switch (type) { switch (type) {
case FOREST: case FOREST:
kw.stopienZalesienia = val; kw.terrainType = TerrainType.FOREST;
break; break;
case WATER: case WATER:
kw.stopienZawodnienia = val; kw.terrainType = TerrainType.WATER;
break; break;
case SWAMP: case SWAMP:
kw.stopienZabagnienia = val; kw.terrainType = TerrainType.SWAMP;
break; break;
case BUILDINGS: case BUILDINGS:
kw.stopienZabudowy = val; kw.terrainType = TerrainType.BUILDINGS;
break; break;
default: default:
} }
@@ -382,30 +379,27 @@ public class Way {
public static void writeAreaFeatureIntoSquares(EAreaFeature type, boolean clearFeature, Coord.Grid[] polygon, public static void writeAreaFeatureIntoSquares(EAreaFeature type, boolean clearFeature, Coord.Grid[] polygon,
int minX, int maxX, int minY, int maxY) { int minX, int maxX, int minY, int maxY) {
float val = (clearFeature) ? 0.0f : 1.0f; float val = (clearFeature) ? 0.0f : 1.0f;
Coord.Grid idTest = new Coord.Grid();
boolean inside; boolean inside;
for (int i = minX; i <= maxX; i++) { for (int x = minX; x <= maxX; x++) {
for (int j = minY; j <= maxY; j++) { for (int y = minY; y <= maxY; y++) {
idTest.x = i; Square kw = Teren.getSquare(x, y);
idTest.y = j;
Square kw = Teren.getKwadrat(idTest.x, idTest.y);
if (kw == Square.EMPTY) { if (kw == Square.EMPTY) {
continue; continue;
} }
inside = GeomUtils.insidePolygon(polygon, idTest); inside = GeomUtils.insidePolygon(polygon, x, y);
if (inside) { if (inside) {
switch (type) { switch (type) {
case FOREST: case FOREST:
kw.stopienZalesienia = val; kw.terrainType = TerrainType.FOREST;
break; break;
case WATER: case WATER:
kw.stopienZawodnienia = val; kw.terrainType = TerrainType.WATER;
break; break;
case SWAMP: case SWAMP:
kw.stopienZabagnienia = val; kw.terrainType = TerrainType.SWAMP;
break; break;
case BUILDINGS: case BUILDINGS:
kw.stopienZabudowy = val; kw.terrainType = TerrainType.BUILDINGS;
break; break;
default: default:
} }
@@ -421,41 +415,41 @@ public class Way {
Square kw; Square kw;
float val = (clearFeature) ? 0.0f : 1.0f; float val = (clearFeature) ? 0.0f : 1.0f;
if (nodes.size() == 1) { if (nodes.size() == 1) {
kw = Teren.getKwadrat(nodes.get(0).idX, nodes.get(0).idY); kw = Teren.getSquare(nodes.get(0).idX, nodes.get(0).idY);
switch (type) { switch (type) {
case FOREST: case FOREST:
kw.stopienZalesienia = val; kw.terrainType = TerrainType.FOREST;
break; break;
case WATER: case WATER:
kw.stopienZawodnienia = val; kw.terrainType = TerrainType.WATER;
break; break;
case SWAMP: case SWAMP:
kw.stopienZabagnienia = val; kw.terrainType = TerrainType.SWAMP;
break; break;
case BUILDINGS: case BUILDINGS:
kw.stopienZabudowy = val; kw.terrainType = TerrainType.BUILDINGS;
break; break;
default: default:
} }
return; return;
} }
if (nodes.size() == 2) { if (nodes.size() == 2) {
Coord.Grid[] kwadraty = GeomUtils.kwadratyOdcinka(nodes.get(0).idX, nodes.get(0).idY, Coord.Grid[] kwadraty = GeomUtils.generateSquaresOfSegment(nodes.get(0).idX, nodes.get(0).idY,
nodes.get(1).idX, nodes.get(1).idY); nodes.get(1).idX, nodes.get(1).idY);
for (int i = 0; i < kwadraty.length; i++) { for (int i = 0; i < kwadraty.length; i++) {
kw = Teren.getKwadrat(kwadraty[i].x, kwadraty[i].y); kw = Teren.getSquare(kwadraty[i].x, kwadraty[i].y);
switch (type) { switch (type) {
case FOREST: case FOREST:
kw.stopienZalesienia = val; kw.terrainType = TerrainType.FOREST;
break; break;
case WATER: case WATER:
kw.stopienZawodnienia = val; kw.terrainType = TerrainType.WATER;
break; break;
case SWAMP: case SWAMP:
kw.stopienZabagnienia = val; kw.terrainType = TerrainType.SWAMP;
break; break;
case BUILDINGS: case BUILDINGS:
kw.stopienZabudowy = val; kw.terrainType = TerrainType.BUILDINGS;
break; break;
default: default:
} }
@@ -476,41 +470,41 @@ public class Way {
Square kw; Square kw;
float val = (clearFeature) ? 0.0f : 1.0f; float val = (clearFeature) ? 0.0f : 1.0f;
if (nodes.size() == 1) { if (nodes.size() == 1) {
kw = Teren.getKwadrat(nodes.get(0).idX, nodes.get(0).idY); kw = Teren.getSquare(nodes.get(0).idX, nodes.get(0).idY);
switch (type) { switch (type) {
case FOREST: case FOREST:
kw.stopienZalesienia = val; kw.terrainType = TerrainType.FOREST;
break; break;
case WATER: case WATER:
kw.stopienZawodnienia = val; kw.terrainType = TerrainType.WATER;
break; break;
case SWAMP: case SWAMP:
kw.stopienZabagnienia = val; kw.terrainType = TerrainType.SWAMP;
break; break;
case BUILDINGS: case BUILDINGS:
kw.stopienZabudowy = val; kw.terrainType = TerrainType.BUILDINGS;
break; break;
default: default:
} }
return; return;
} }
if (nodes.size() == 2) { if (nodes.size() == 2) {
Coord.Grid[] kwadraty = GeomUtils.kwadratyOdcinka(nodes.get(0).idX, nodes.get(0).idY, Coord.Grid[] kwadraty = GeomUtils.generateSquaresOfSegment(nodes.get(0).idX, nodes.get(0).idY,
nodes.get(1).idX, nodes.get(1).idY); nodes.get(1).idX, nodes.get(1).idY);
for (int i = 0; i < kwadraty.length; i++) { for (int i = 0; i < kwadraty.length; i++) {
kw = Teren.getKwadrat(kwadraty[i].x, kwadraty[i].y); kw = Teren.getSquare(kwadraty[i].x, kwadraty[i].y);
switch (type) { switch (type) {
case FOREST: case FOREST:
kw.stopienZalesienia = val; kw.terrainType = TerrainType.FOREST;
break; break;
case WATER: case WATER:
kw.stopienZawodnienia = val; kw.terrainType = TerrainType.WATER;
break; break;
case SWAMP: case SWAMP:
kw.stopienZabagnienia = val; kw.terrainType = TerrainType.SWAMP;
break; break;
case BUILDINGS: case BUILDINGS:
kw.stopienZabudowy = val; kw.terrainType = TerrainType.BUILDINGS;
break; break;
default: default:
} }
@@ -543,37 +537,34 @@ public class Way {
} }
return; return;
} }
Coord.Grid idTest = new Coord.Grid();
boolean nalezyDoWielokata; boolean nalezyDoWielokata;
// int liczKw = 0; // int liczKw = 0;
// int liczKwObszaru = 0; // int liczKwObszaru = 0;
// for (int j = maxY; j >= minY; j--) { // for (int j = maxY; j >= minY; j--) {
// for (int i = minX; i <= maxX; i++) { // for (int i = minX; i <= maxX; i++) {
for (int i = minX; i <= maxX; i++) { for (int x = minX; x <= maxX; x++) {
for (int j = minY; j <= maxY; j++) { for (int y = minY; y <= maxY; y++) {
idTest.x = i;
idTest.y = j;
// char c = ' '; // char c = ' ';
// liczKw++; // liczKw++;
kw = Teren.getKwadrat(idTest.x, idTest.y); kw = Teren.getSquare(x, y);
if (kw == Square.EMPTY) { if (kw == Square.EMPTY) {
continue; continue;
} }
nalezyDoWielokata = GeomUtils.insidePolygon(wielokat, idTest); nalezyDoWielokata = GeomUtils.insidePolygon(wielokat, x, y);
if (nalezyDoWielokata) { if (nalezyDoWielokata) {
// c = 'O'; // c = 'O';
switch (type) { switch (type) {
case FOREST: case FOREST:
kw.stopienZalesienia = val; kw.terrainType = TerrainType.FOREST;
break; break;
case WATER: case WATER:
kw.stopienZawodnienia = val; kw.terrainType = TerrainType.WATER;
break; break;
case SWAMP: case SWAMP:
kw.stopienZabagnienia = val; kw.terrainType = TerrainType.SWAMP;
break; break;
case BUILDINGS: case BUILDINGS:
kw.stopienZabudowy = val; kw.terrainType = TerrainType.BUILDINGS;
break; break;
default: default:
} }

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.konwersja; package pl.wat.ms4ds.terrain.osm;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -40,14 +40,10 @@ public class Worker extends Thread {
@Override @Override
public void run() { public void run() {
try { try {
int ileKwTest = (maxX - minX) * (maxY - minY); int ileKwTest = (maxX - minX + 1) * (maxY - minY + 1);
synchronized (OpenStreetMapReader.synch) { logger.debug("{} >>> polygon.lent= {}, ileKwTest= {}", Thread.currentThread().getName(), polygon.length, ileKwTest);
logger.debug(Thread.currentThread().getName() + " >>> polygon.lent= " + polygon.length + ", ileKwTest= " + Integer.toString(ileKwTest));
}
Way.writeAreaFeatureIntoSquares(type, clearFeature, polygon, minX, maxX, minY, maxY); Way.writeAreaFeatureIntoSquares(type, clearFeature, polygon, minX, maxX, minY, maxY);
synchronized (OpenStreetMapReader.synch) { logger.debug("{} <<< polygon.lent= {}, ileKwTest= {}", Thread.currentThread().getName(), polygon.length, ileKwTest);
logger.debug(Thread.currentThread().getName() + " <<< polygon.lent= " + polygon.length + ", ileKwTest= " + Integer.toString(ileKwTest));
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@@ -1,66 +0,0 @@
package pl.wat.ms4ds.terrain.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);
}
}

View File

@@ -1,23 +0,0 @@
package pl.wat.ms4ds.terrain.osm.shapefile;
public class Main {
static void main(String[] args) {
try {
// GET DIRECTORY
String curDir = (args.length > 0) ? args[0] : "";
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();
}
}
}

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.osm.shapefile; package pl.wat.ms4ds.terrain.osmshp;
public class DbfField { public class DbfField {

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.osm.shapefile; package pl.wat.ms4ds.terrain.osmshp;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;

View File

@@ -0,0 +1,130 @@
package pl.wat.ms4ds.terrain.osmshp;
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.
*/
String name;
String roadRef;
boolean oneway;
int roadMaxSpeed;
int roadLayer;
boolean bridge;
boolean tunnel;
int waterwayWidth;
String buildingType;
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");
}
// Zamiana znaków spoza zakresu UTF-8 (ujemnych) na spację.
for (int i = 0; i < data.length; i++) {
if (data[i] < 0) {
data[i] = 32;
}
}
String str = new String(data, StandardCharsets.UTF_8);
// Na pozycji 0 jest tzw. flag byte, dane startują od pozycji 1.
int from = 1;
int to = from + header.fields[0].size;
// Pomijam czytanie osm id, gdyż nie jest wykorzystywane.
// 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);
fclass = fclass.substring(0, fclass.indexOf(' '));
from = to;
to += header.fields[3].size;
name = str.substring(from, to);
if (header.fields.length > 4) {
String s;
for (int i = 4; i < header.fields.length; i++) {
from = to;
to += header.fields[i].size;
s = str.substring(from, to);
if (header.fields[i].type == 'N') {
// Wartość numeryczna (int), zatem usuwam poprzedzające spacje
s = s.stripLeading();
}
switch (header.fields[i].name) {
case "ref":
roadRef = s;
break;
case "oneway":
oneway = !s.equals("B");
break;
case "maxspeed":
roadMaxSpeed = Integer.parseInt(s);
break;
case "layer":
roadLayer = Integer.parseInt(s);
break;
case "bridge":
bridge = s.equals("T");
break;
case "tunnel":
tunnel = s.equals("T");
break;
case "width":
waterwayWidth = Integer.parseInt(s);
break;
case "type":
buildingType = s;
break;
default:
}
}
}
// Additional attributes for roads
//ref - VARCHAR(20) Reference number of this road ('A 5', 'L 605', ...) ref=*
//oneway VARCHAR(1) Is this a oneway road? “F” means that only driving
//in direction of the linestring is allowed. “T” means
//that only the opposite direction is allowed. “B”
//(default value) means that both directions are ok.
//oneway=*
//maxspeed SMALLINT Max allowed speed in km/h maxspeed=*
//layer SMALLINT Relative layering of roads (-5, ..., 0, ..., 5) layer=*
//bridge VARCHAR(1) Is this road on a bridge? (“T” = true, “F” = false) bridge=*
//tunnel VARCHAR(1) Is this road in a tunnel? (“T” = true, “F” = false) tunnel=*
}
}

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.osm.shapefile; package pl.wat.ms4ds.terrain.osmshp;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
@@ -49,9 +49,10 @@ public class OsmShapeFileReader {
// wetland 8221 // wetland 8221
/** /**
* Konstruktor obiektu readera danych OSM Shp.
*
* <pre> * <pre>
* init the ShapeFile, and load the following files: * init the ShapeFile, and load the following files:
* "path + filename.shx",
* "path + filename.dbf", * "path + filename.dbf",
* "path + filename.shp" * "path + filename.shp"
* </pre> * </pre>
@@ -63,16 +64,21 @@ public class OsmShapeFileReader {
public OsmShapeFileReader(String path, String filename) throws Exception { public OsmShapeFileReader(String path, String filename) throws Exception {
File dir = new File(path); File dir = new File(path);
File shpFile = new File(dir, filename + ".shp"); File shpFile = new File(dir, filename + ".shp");
FileInputStream is = new FileInputStream(shpFile); bisShp = new BufferedInputStream(new FileInputStream(shpFile));
bisShp = new BufferedInputStream(is);
shpHeader = new ShpHeader(bisShp); shpHeader = new ShpHeader(bisShp);
File dbfFile = new File(dir, filename + ".dbf"); File dbfFile = new File(dir, filename + ".dbf");
bisDbf = new BufferedInputStream(new FileInputStream(dbfFile)); bisDbf = new BufferedInputStream(new FileInputStream(dbfFile));
dbfHeader = new DbfHeader(bisDbf); dbfHeader = new DbfHeader(bisDbf);
} }
/**
* Metoda odczytuje i zwraca obiekt reprezentujący określony kształt wraz z dodatkową informacją.
*
* @return
* @throws Exception
*/
public ShpShape nextShape() throws Exception { public ShpShape nextShape() throws Exception {
boolean hasNext = false; boolean hasNext;
try { try {
hasNext = hasNextShape(); hasNext = hasNextShape();
} catch (IOException e) { } catch (IOException e) {
@@ -82,44 +88,33 @@ public class OsmShapeFileReader {
return null; return null;
} }
ShpShape shape = null; ShpShape shape = null;
DbfRecord info = null; DbfRecord info;
switch (shpHeader.shapeType) { switch (shpHeader.shapeType) {
case Point, PointZ, PointM: case Point, PointZ, PointM:
shape = new ShpPoint(shpHeader.shapeType); shape = new ShpPoint(shpHeader.shapeType);
shape.read(bisShp); break;
info = new DbfRecord();
info.read(bisDbf, dbfHeader);
shape.setInfo(info);
return shape;
case PolyLine, PolyLineZ, PolyLineM: case PolyLine, PolyLineZ, PolyLineM:
shape = new ShpPolyLine(shpHeader.shapeType); shape = new ShpPolyLine(shpHeader.shapeType);
shape.read(bisShp); break;
info = new DbfRecord();
info.read(bisDbf, dbfHeader);
shape.setInfo(info);
return shape;
case Polygon, PolygonZ, PolygonM: case Polygon, PolygonZ, PolygonM:
shape = new ShpPolygon(shpHeader.shapeType); shape = new ShpPolygon(shpHeader.shapeType);
shape.read(bisShp); break;
info = new DbfRecord();
info.read(bisDbf, dbfHeader);
shape.setInfo(info);
return shape;
case MultiPoint, MultiPointZ, MultiPointM: case MultiPoint, MultiPointZ, MultiPointM:
shape = new ShpMultiPoint(shpHeader.shapeType); shape = new ShpMultiPoint(shpHeader.shapeType);
shape.read(bisShp); break;
info = new DbfRecord();
info.read(bisDbf, dbfHeader);
shape.setInfo(info);
return shape;
default: default:
return shape; return shape;
} }
shape.read(bisShp);
info = new DbfRecord();
info.read(bisDbf, dbfHeader);
shape.setInfo(info);
return shape;
} }
public boolean hasNextShape() throws IOException { public boolean hasNextShape() throws IOException {
return bisShp.available() > 0; return bisShp.available() > 0;
} }
} }

View File

@@ -0,0 +1,581 @@
package pl.wat.ms4ds.terrain.osmshp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pl.wat.ms4ds.common.EGeoDirection;
import pl.wat.ms4ds.terrain.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class OsmShpDataGenerator {
private static final Logger logger = LoggerFactory.getLogger(OsmShpDataGenerator.class);
static void main(String[] args) {
try {
// GET DIRECTORY
// "C:/Workspace/osm/warminsko-mazurskie-251217-free.shp/"
// "dolnoslaskie"
// "kujawsko-pomorskie"
// "lodzkie"
// "lubelskie"
// "lubuskie"
// "malopolskie"
// "mazowieckie"
// "opolskie"
// "podkarpackie"
// "podlaskie"
// "pomorskie"
// "slaskie"
// "swietokrzyskie"
// "warminsko-mazurskie"
// "wielkopolskie"
// "zachodniopomorskie"
// String[] regions = new String[]{"dolnoslaskie", "kujawsko-pomorskie", "lodzkie", "lubelskie",
// "lubuskie", "malopolskie", "mazowieckie", "opolskie",
// "podkarpackie", "podlaskie", "pomorskie", "slaskie",
// "swietokrzyskie", "warminsko-mazurskie", "wielkopolskie", "zachodniopomorskie"};
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
String ext = "-251217-free.shp/";
String inDir = "C:/Workspace/osm/";
String outDir = "D:/work/kwadraty_nmt/temp/100m/";
// final String[] areaLayers = new String[]{"landuse_a", "buildings_a", "water_a", "pois_a", "pofw_a"};
// final String[] pointLayers = new String[]{"pois", "pofw"};
// final String[] linearLayers = new String[]{"waterways", "roads"};
final String[] areaLayers = new String[]{"landuse_a", "buildings_a", "water_a"};
final String[] pointLayers = new String[]{"pois", "pofw"};
final String[] linearLayers = new String[]{"waterways", "roads"};
double d = 3 * MapConsts.SS_DELTA_LON;
// final int concurrency = 2;
//// String layerName = "gis_osm_" + areaLayers[0] + "_free_1";
// for (int j = 0; j < 8; j++) {
// Future[] futures = new Future[concurrency];
// for (int i = 0; i < concurrency; i++) {
// final int ii = concurrency * j + i;
// futures[i] = executor.submit(() -> {
// for (int k = 0; k < areaLayers.length; k++) {
// logger.info("Work started: region= {}, layer= {}", regions[ii], areaLayers[k]);
// String ln = "gis_osm_" + areaLayers[k] + "_free_1";
// HashSet<ArrayList<Coord.Grid[]>>[] data = generateDataFromAreaLayer(inDir + regions[ii] + ext, ln);
// writeAreaFeatures(data);
// int size = 0;
// for (HashSet<ArrayList<Coord.Grid[]>> datum : data) {
// if (datum != null) {
// size += datum.size();
// datum.clear();
// }
// }
// logger.info("Work finished: region= {}, layer= {}, data.size= {}", regions[ii], areaLayers[k]);
// }
// for (int k = 0; k < pointLayers.length; k++) {
// logger.info("Work started: region= {}, layer= {}", regions[ii], pointLayers[k]);
// String ln = "gis_osm_" + pointLayers[k] + "_free_1";
// HashSet<Coord.Grid> data = generateDataFromPointLayer(inDir + regions[ii] + ext, ln);
// writeAreaFeatureIntoSquares(TerrainType.BUILDINGS, false, data);
// int size = data.size();
// data.clear();
// logger.info("Work finished: region= {}, layer= {}, data.size= {}", regions[ii], pointLayers[k], size);
// }
// for (int k = 0; k < linearLayers.length; k++) {
// logger.info("Work started: region= {}, layer= {}", regions[ii], linearLayers[k]);
// String ln = "gis_osm_" + linearLayers[k] + "_free_1";
// HashSet<ArrayList<Coord.Grid[]>>[] data = generateDataFromLinearLayer(inDir + regions[ii] + ext, ln);
// writeLinearFeatures(data, k);
// int size = 0;
// for (HashSet<ArrayList<Coord.Grid[]>> datum : data) {
// if (datum != null) {
// size += datum.size();
// datum.clear();
// }
// }
// logger.info("Work finished: region= {}, layer= {}, data.size= {}", regions[ii], linearLayers[k], size);
// }
// });
// }
// for (Future future : futures) {
// future.get();
// }
// Teren.saveToFiles(outDir);
// }
// String layerName = "gis_osm_" + areaLayers[0] + "_free_1";
String[] regions = new String[]{"dolnoslaskie", "kujawsko-pomorskie", "lodzkie", "lubelskie",
"lubuskie", "malopolskie", "opolskie", "mazowieckie", "warminsko-mazurskie",
"podkarpackie", "podlaskie", "pomorskie", "slaskie",
"swietokrzyskie", "wielkopolskie", "zachodniopomorskie"};
// String[] regions = new String[]{"mazowieckie", "warminsko-mazurskie"};
for (int i = 0; i < regions.length; i++) {
for (int k = 0; k < areaLayers.length; k++) {
logger.info("Work started: region= {}, layer= {}", regions[i], areaLayers[k]);
String ln = "gis_osm_" + areaLayers[k] + "_free_1";
HashSet<ArrayList<Coord.Grid[]>>[] data = generateDataFromAreaLayer(inDir + regions[i] + ext, ln);
writeAreaFeatures(data);
for (HashSet<ArrayList<Coord.Grid[]>> datum : data) {
if (datum != null) {
datum.clear();
}
}
logger.info("Work finished: region= {}, layer= {}", regions[i], areaLayers[k]);
}
for (int k = 0; k < pointLayers.length; k++) {
logger.info("Work started: region= {}, layer= {}", regions[i], pointLayers[k]);
String ln = "gis_osm_" + pointLayers[k] + "_free_1";
HashSet<Coord.Grid> data = generateDataFromPointLayer(inDir + regions[i] + ext, ln);
writeAreaFeatureIntoSquares(TerrainType.BUILDINGS, false, data);
data.clear();
logger.info("Work finished: region= {}, layer= {}", regions[i], pointLayers[k]);
}
for (int k = 0; k < linearLayers.length; k++) {
logger.info("Work started: region= {}, layer= {}", regions[i], linearLayers[k]);
String ln = "gis_osm_" + linearLayers[k] + "_free_1";
HashSet<ArrayList<Coord.Grid[]>>[] data = generateDataFromLinearLayer(inDir + regions[i] + ext, ln);
writeLinearFeatures(data, k);
for (HashSet<ArrayList<Coord.Grid[]>> datum : data) {
if (datum != null) {
datum.clear();
}
}
logger.info("Work finished: region= {}, layer= {}", regions[i], linearLayers[k]);
}
Teren.saveToFiles(outDir);
}
// HashSet<ArrayList<Coord.Grid[]>>[] data = generateDataFromAreaLayer(inDir + regions[0] + ext, "gis_osm_pois_a_free_1");
// writeAreaFeatures(data);
// String ln = "gis_osm_" + pointLayers[1] + "_free_1";
// HashSet<Coord.Grid> data2 = generateDataFromPointLayer(inDir + regions[0] + ext, ln);
// writeAreaFeatureIntoSquares(TerrainType.BUILDINGS, false, data2);
// writeLinearFeatures(data, 1);
// Teren.saveToFiles(outDir);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Funkcja zapisuje dane dotyczace określonych charakterystyk terenowych
* (odpowiadające indeksom głównej tablicy) do kwadratów.
* <p></p>
* Każda cecha przetwarzana jest osobno (indeks tablicy). W ramach cechy przetwarzane są obszary.
* Każdy obszar opisany jest listą wielokątów określających zewnętrzne granice oraz opcjonalnie dziury.
*
* @param data
*/
public static void writeAreaFeatures(HashSet<ArrayList<Coord.Grid[]>>[] data) {
HashSet<Coord.Grid> squareSet = new HashSet<>();
// Indeksy odpowiadają numeracji (id) wartości w TerrainType.
for (int typeId = 1; typeId < data.length; typeId++) {
HashSet<ArrayList<Coord.Grid[]>> set = data[typeId];
if (set == null || set.isEmpty()) {
continue;
}
TerrainType terrainType = TerrainType.valueFromId(typeId);
for (ArrayList<Coord.Grid[]> area : set) {
collectSquaresOfArea(area, squareSet, true);
writeAreaFeatureIntoSquares(terrainType, false, squareSet);
squareSet.clear();
}
}
}
/**
* Funkcja gromadzi współrzędne (gridowe) kwadratów należących do obszaru opisanego wielokątami.
* Pierwszy wielokąt opisuje zewnętrzne granice obszaru.
* Kolejne wielokąty opisują granice obszarów wewnętrznych, będących dziurami.
*
* @param area
* @param squareSet
*/
public static void collectSquaresOfArea(ArrayList<Coord.Grid[]> area, HashSet<Coord.Grid> squareSet, boolean onlyOuter) {
Coord.Grid[] outerPolygon = area.getFirst();
if (outerPolygon == null) {
return;
}
int[] bounds = GeomUtils.getBounds(outerPolygon);
int minX = bounds[0];
int minY = bounds[1];
int maxX = bounds[2];
int maxY = bounds[3];
boolean inside;
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
inside = GeomUtils.insidePolygon(outerPolygon, x, y);
if (inside) {
squareSet.add(new Coord.Grid(x, y));
}
}
}
if (onlyOuter) {
return;
}
int count = squareSet.size();
// Pozostałe wielokąty opisują obszary wewnętrzne będące tzw. dziurami.
boolean removed;
Coord.Grid[] innerPolygon;
Coord.Grid test;
for (int i = 1; i < area.size(); i++) {
innerPolygon = area.get(i);
bounds = GeomUtils.getBounds(innerPolygon);
minX = bounds[0];
minY = bounds[1];
maxX = bounds[2];
maxY = bounds[3];
test = new Coord.Grid();
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
inside = GeomUtils.insidePolygon(outerPolygon, x, y);
if (inside) {
test.x = x;
test.y = y;
removed = squareSet.remove(test);
}
}
}
}
int countOfRemoved = count - squareSet.size();
logger.trace("Num of outer= {}, num of inner= {}", count, countOfRemoved);
}
public static void writeAreaFeatureIntoSquares(TerrainType type, boolean clearFeature, HashSet<Coord.Grid> squareSet) {
TerrainType val = (clearFeature) ? TerrainType.NONE : type;
for (Coord.Grid coord : squareSet) {
Square square = Teren.getSquare(coord.x, coord.y);
if (square == Square.EMPTY) {
continue;
}
synchronized (square) {
square.terrainType = val;
}
}
}
/**
* Funkcja zwraca id wartości typu wyliczeniowego {@link TerrainType} dla obiektów obszarowych.
* <p>Wartość 0 - NONE, 1 - GRASS, 2 - SWAMP, 3 - WATER, 4 - SCRUB_BUSHES, 5 - BUILDINGS, 6 - FOREST.
*
* @param shpShape
* @return
*/
public static int mapFclassToTerrainType(ShpShape shpShape) {
if (shpShape.info.code == 1500) {
return TerrainType.BUILDINGS.id;
}
return switch (shpShape.info.fclass) {
// case "residential", "industrial", "commercial", "retail", "farmyard" -> TerrainType.BUILDINGS.id;
case "police", "fire_station", "post_office", "library", "town_hall", "courthouse", "prison", "embassy",
"theatre", "nightclub", "cinema", "nursing_home", "market_place", "university", "school",
"kindergarten", "college", "public_building", "pharmacy", "hospital", "clinic", "doctors", "dentist",
"veterinary", "restaurant", "fast_food", "cafe", "pub", "hotel", "motel", "bed_and_breakfast",
"guesthouse", "hostel", "supermarket", "bakery", "mall", "department_store", "bank", "museum",
"castle", "bookshop", "clothes", "general", "hairdresser",
"jeweller", "optician" -> TerrainType.BUILDINGS.id;
case "christian", "christian_anglican", "christian_catholic", "christian_evangelical",
"christian_lutheran", "christian_methodist", "christian_orthodox", "christian_protestant",
"christian_baptist", "christian_mormon" -> TerrainType.BUILDINGS.id;
case "forest", "woodland", "park", "orchard" -> TerrainType.FOREST.id;
case "grass", "meadow", "farmland", "recreation_ground", "heath" -> TerrainType.GRASS.id;
case "scrub", "vineyard", "allotments" -> TerrainType.SCRUB_BUSHES.id;
case "water", "reservoir", "river", "dock" -> TerrainType.WATER.id;
case "wetland" -> TerrainType.SWAMP.id;
default -> TerrainType.NONE.id;
};
}
/**
* Generuje dane obszarowe w zakresie typu terenu {@link TerrainType}.
* <p>
* "gis_osm_landuse_a_free_1", "gis_osm_water_a_free_1", "gis_osm_buildings_a_free_1", "gis_osm_pois_a_free_1", "gis_osm_pofw_a_free_1"
*
* @param path
*/
static HashSet<ArrayList<Coord.Grid[]>>[] generateDataFromAreaLayer(String path, String filename) {
HashSet<ArrayList<Coord.Grid[]>>[] result = new HashSet[TerrainType.values().length];
result[1] = new HashSet<>();
result[2] = new HashSet<>();
result[3] = new HashSet<>();
result[4] = new HashSet<>();
result[5] = new HashSet<>();
result[6] = new HashSet<>();
try {
OsmShapeFileReader osmShapeFileReader = new OsmShapeFileReader(path, filename);
int pos = 0;
int typeId;
while (osmShapeFileReader.hasNextShape()) {
ShpShape shape = osmShapeFileReader.nextShape();
if (shape instanceof ShpPolygon shpPolygon) {
typeId = mapFclassToTerrainType(shpPolygon);
String fclass = shpPolygon.info.fclass;
if (shpPolygon.info.code == 1500) {
// Warstwa obszarowa dot. budynków nie ma zdefiniowanej fclass, zatem sprawdzam code
// i ewentualnie zmieniam typeId.
typeId = TerrainType.BUILDINGS.id;
fclass = "building1500";
}
if (typeId == 0) {
continue;
}
logger.trace("Shape pos = {}, shape type = {}, fclass= {}, numParts= {}", pos, shape.getShapeType(), fclass, shpPolygon.numberOfParts);
ArrayList<Coord.Grid[]> polygons = generatePolylines(shpPolygon);
result[typeId].add(polygons);
pos++;
}
}
logger.info("End, num={}", pos);
} catch (Exception e) {
}
return result;
}
enum WatercourseType {
NONE(0), DITCH_DRAIN(1), STREAM(2), RIVER(3);
public final int id;
WatercourseType(int id) {
this.id = id;
}
public static WatercourseType valueFromId(int id) {
return values[id];
}
static final WatercourseType[] values = WatercourseType.values();
}
/**
* Funkcja zwraca id wartości typu wyliczeniowego dla obiektów liniowych typu cieki wodne oraz drogi.
* <p>Wartość 0 - brak, 1 - DITCH_DRAIN/SMALL, 2 - STREAM/MINOR, 3 - RIVER/MAJOR
*
* @param shpShape
* @return typeId of linear feature: 0 - NONE, 1 - DITCH_DRAIN/SMALL, 2 - STREAM/MINOR, 3 - RIVER/MAJOR
*/
public static int mapFclassToLineTypeId(ShpShape shpShape) {
return switch (shpShape.info.fclass) {
case "river" -> WatercourseType.RIVER.id;
case "stream", "canal" -> WatercourseType.STREAM.id;
case "drain" -> WatercourseType.DITCH_DRAIN.id;
case "motorway", "trunk", "primary", "secondary", "tertiary", "motorway_link", "trunk_link", "primary_link",
"secondary_link", "tertiary_link" -> RoadType.MAJOR.id;
case "unclassified", "residential", "living_street" -> RoadType.MINOR.id;
case "service", "track", "track_grade1", "track_grade2", "track_grade3", "track_grade4", "track_grade5" ->
RoadType.SMALL.id;
default -> 0;
};
}
/**
* Generuje dane liniowe w zakresie cieków/przeszkód wodnych.
* (RIVER, STREAM, DITCH_DRAIN).
* (MAJOR_ROADS, MINOR_ROADS, SMALL_ROADS)
* <p>
* "gis_osm_waterways_free_1", "gis_osm_roads_free_1"
*
* @param path
*/
static HashSet<ArrayList<Coord.Grid[]>>[] generateDataFromLinearLayer(String path, String filename) {
HashSet<ArrayList<Coord.Grid[]>>[] result = new HashSet[]{new HashSet<>(), new HashSet<>(), new HashSet<>(), new HashSet<>()};
int width;
try {
OsmShapeFileReader osmShapeFileReader = new OsmShapeFileReader(path, filename);
int pos = 0;
int typeId;
while (osmShapeFileReader.hasNextShape()) {
ShpShape shape = osmShapeFileReader.nextShape();
typeId = mapFclassToLineTypeId(shape);
if (typeId == 0) {
continue;
}
if (shape instanceof ShpPolyLine shpPolyLine) {
width = shpPolyLine.info.waterwayWidth;
logger.trace("Shape pos = {}, shape type = {}, fclass= {}, numParts= {}, width= {}", pos, shape.getShapeType(), shape.info.fclass, shpPolyLine.numberOfParts, width);
ArrayList<Coord.Grid[]> polylines = generatePolylines(shpPolyLine);
result[typeId].add(polylines);
pos++;
}
}
logger.info("End, num={}", pos);
} catch (Exception e) {
}
return result;
}
enum RoadType {
NONE(0), SMALL(1), MINOR(2), MAJOR(3);
public final int id;
RoadType(int id) {
this.id = id;
}
public static RoadType valueFromId(int id) {
return values[id];
}
static final RoadType[] values = RoadType.values();
}
/**
* Funkcja generalna odpowiedzialna za przekształcenie danych liniowych i zapis do kwadratów.
*
* @param data
* @param featureCategory kategoria danych liniowych (0 - cieki wodne, 1 - drogi)
*/
public static void writeLinearFeatures(HashSet<ArrayList<Coord.Grid[]>>[] data, int featureCategory) {
ArrayList<Coord.Grid[]> polylineList = new ArrayList<>();
// Indeksy odpowiadają numeracji (id) wartości w typach wyliczeniowych danej charakterystyki.
for (int typeId = 0; typeId < data.length; typeId++) {
HashSet<ArrayList<Coord.Grid[]>> set = data[typeId];
if (set == null || set.isEmpty()) {
continue;
}
for (ArrayList<Coord.Grid[]> polylines : set) {
collectSquaresOfPolylines(polylines, polylineList);
writeLinearFeatureIntoSquares((byte) typeId, false, polylineList, featureCategory);
polylineList.clear();
}
}
}
/**
* Funkcja gromadzi sekwencje współrzędnych kwadratów tworzących łamane.
*
* @param polylines list of polylines defined by vertices
* @param polylineList set of detailed polylines defined by squares sequances
*/
public static void collectSquaresOfPolylines(ArrayList<Coord.Grid[]> polylines, ArrayList<Coord.Grid[]> polylineList) {
Coord.Grid[] squares;
for (Coord.Grid[] polyline : polylines) {
squares = GeomUtils.generateSquaresOfSegments(polyline);
squares = GeomUtils.removeSteps(squares);
polylineList.add(squares);
}
logger.trace("Num of polylines= {}", polylines.size());
}
/**
*
* @param type type of feature (depends on the feature category)
* @param clearFeature
* @param polylineList polylines defined by squares sequences
* @param featureCategory feature category to write (0 - watercourses, 1 - roads)
*/
public static void writeLinearFeatureIntoSquares(byte type, boolean clearFeature, ArrayList<Coord.Grid[]> polylineList, int featureCategory) {
byte val = (clearFeature) ? 0 : type;
for (Coord.Grid[] grids : polylineList) {
for (int i = 0; i < grids.length - 1; i++) {
int x0 = grids[i].x;
int y0 = grids[i].y;
int x1 = grids[i + 1].x;
int y1 = grids[i + 1].y;
Square curr_square = Teren.getSquare(x0, y0);
EGeoDirection outDirection = GeomUtils.neighborDirection(x0, y0, x1, y1);
if (curr_square != Square.EMPTY) {
synchronized (curr_square) {
if (featureCategory == 0) {
curr_square.watercourses[outDirection.id] = val;
} else {
curr_square.roads[outDirection.id] = val;
}
}
}
EGeoDirection inDirection = outDirection.oppositeDirect();
Square next_square = Teren.getSquare(x1, y1);
if (next_square != Square.EMPTY) {
synchronized (next_square) {
if (featureCategory == 0) {
next_square.watercourses[inDirection.id] = val;
} else {
next_square.roads[inDirection.id] = val;
}
}
}
}
}
}
/**
* Generuje dane obszarowe w zakresie zabudowy {@link TerrainType}.
* <p>
* "gis_osm_pois_free_1", "gis_osm_pofw_free_1"
*
* @param path
*/
static HashSet<Coord.Grid> generateDataFromPointLayer(String path, String filename) {
HashSet<Coord.Grid> result = new HashSet<>();
try {
OsmShapeFileReader osmShapeFileReader = new OsmShapeFileReader(path, filename);
int pos = 0;
int typeId;
int x;
int y;
while (osmShapeFileReader.hasNextShape()) {
ShpShape shape = osmShapeFileReader.nextShape();
if (shape instanceof ShpPoint shpPoint) {
typeId = mapFclassToTerrainType(shpPoint);
if (typeId != TerrainType.BUILDINGS.id) {
continue;
}
logger.trace("Shape pos = {}, shape type = {}, fclass= {}", pos, shape.getShapeType(), shape.info.fclass);
x = Coord.convertLonToGridX(shpPoint.x);
y = Coord.convertLatToGridY(shpPoint.y);
Coord.Grid coord = new Coord.Grid(x, y);
result.add(coord);
pos++;
}
}
logger.info("End, num={}", pos);
} catch (Exception e) {
}
return result;
}
/**
* Funkcja generuje dane geometryczne na siatce kwadratów.
* <p> Lista łamanych (otwartych lub zamkniętych) opisujących kształt obiektu klasy {@link ShpPolyShape}.
* <p> W przypadku obiektów obszarowych pierwszy element opisuje zewnętrzną powłokę, kolejne tzw. dziury.</p>
* <p> W przypadku obiektów liniowych zawiera jedną łamaną.</p>
*
* @param shpPolyShape
* @return
*/
static ArrayList<Coord.Grid[]> generatePolylines(ShpPolyShape shpPolyShape) {
ArrayList<Coord.Grid[]> polygons = new ArrayList<>();
int start;
int stop;
Coord.Grid[] polygon;
for (int i = 0; i < shpPolyShape.numberOfParts; i++) {
start = shpPolyShape.partsPos[i];
int next = i + 1;
if (next < shpPolyShape.numberOfParts) {
stop = shpPolyShape.partsPos[next];
} else {
stop = shpPolyShape.numberOfPoints;
}
polygon = new Coord.Grid[stop - start];
for (int j = 0; j < polygon.length; j++) {
int x = Coord.convertLonToGridX(shpPolyShape.pointsX[start + j]);
int y = Coord.convertLatToGridY(shpPolyShape.pointsY[start + j]);
polygon[j] = new Coord.Grid(x, y);
}
// boolean b1 = GeomUtils.isClockwise(polygon);
polygon = GeomUtils.removeAdjacentDuplicates(polygon);
polygon = GeomUtils.removeCollinearity(polygon, true);
// boolean b2 = GeomUtils.isClockwise(polygon);
polygons.add(polygon);
logger.trace("Part id = {}, numOfPoints= {}", i, polygon.length);
}
return polygons;
}
}

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.osm.shapefile; package pl.wat.ms4ds.terrain.osmshp;
import java.io.*; import java.io.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@@ -67,17 +67,17 @@ public class ShpHeader {
} }
/** /**
* get the type ShapeType the shapeFile contains.<br> * Get the ShapeType the shapeFile contains.<br>
* a shapeFile contains only one type of shape.<br> * A shapeFile contains only one type of shape.<br>
* *
* @return ShpShape.Type * @return the type of shape
*/ */
public ShpShape.Type getShapeType() { public ShpShape.Type getShapeType() {
return shapeType; return shapeType;
} }
/** /**
* data storage: [3][2] --> [x,y,z][min, max]. * Data storage: [3][2] --> [x,y,z][min, max].
* *
* @return boundingbox as double[][] * @return boundingbox as double[][]
*/ */
@@ -86,43 +86,41 @@ public class ShpHeader {
} }
/** /**
* get measure range.<br> * Get measure range.<br>
* data storage: [2] --> [min, max] * [min, max]
* *
* @return double[] * @return measure range as double[]
*/ */
public double[] getMeasureRange() { public double[] getMeasureRange() {
return rangeM; return rangeM;
} }
/** /**
* get length in bytes of the shapeFile. * Get length in bytes of the shapeFile.
* *
* @return length in bytes. * @return length in bytes
*/ */
public int getFileLengthBytes() { public int getFileLength() {
return fileLength; return fileLength;
} }
/** /**
* get Verions on the shapeFile. * Get Verions on the shapeFile.
* *
* @return should return 1000. * @return should return 1000
*/ */
public int getVersion() { public int getVersion() {
return SHAPE_FILE_VERSION; return SHAPE_FILE_VERSION;
} }
/** /**
* get MAGIC NUMBER of shapeFile. * Get MAGIC NUMBER of shapeFile.
* *
* @return should return 9994. * @return should return 9994
*/ */
public int getMagicNumber() { public int getMagicNumber() {
return SHAPE_FILE_CODE; return SHAPE_FILE_CODE;
} }
public void print() {
}
} }

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.osm.shapefile; package pl.wat.ms4ds.terrain.osmshp;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@@ -35,7 +35,7 @@ public class ShpMultiPoint extends ShpShape {
} }
@Override @Override
protected void readRecordContent(ByteBuffer bb) { protected void readContent(ByteBuffer bb) {
xMin = bb.getDouble(); // x-min xMin = bb.getDouble(); // x-min
yMin = bb.getDouble(); // y-min yMin = bb.getDouble(); // y-min
xMax = bb.getDouble(); // x-max xMax = bb.getDouble(); // x-max
@@ -49,7 +49,7 @@ public class ShpMultiPoint extends ShpShape {
pointsY[i] = bb.getDouble(); // y - coordinate pointsY[i] = bb.getDouble(); // y - coordinate
} }
// if SHAPE-TYPE: 18 // if SHAPE-TYPE: 18
if (type.hasZvalues()) { if (type.hasZ()) {
zMin = bb.getDouble(); // z-min zMin = bb.getDouble(); // z-min
zMax = bb.getDouble(); // z-max zMax = bb.getDouble(); // z-max
for (int i = 0; i < numberOfPoints; i++) { for (int i = 0; i < numberOfPoints; i++) {
@@ -57,7 +57,7 @@ public class ShpMultiPoint extends ShpShape {
} }
} }
// if SHAPE-TYPE: 18 | 28 // if SHAPE-TYPE: 18 | 28
if (type.hasMvalues()) { if (type.hasM()) {
mMin = bb.getDouble(); // m-min mMin = bb.getDouble(); // m-min
mMax = bb.getDouble(); // m-max mMax = bb.getDouble(); // m-max
valuesM = new double[numberOfPoints]; valuesM = new double[numberOfPoints];

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.osm.shapefile; package pl.wat.ms4ds.terrain.osmshp;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@@ -28,15 +28,15 @@ public class ShpPoint extends ShpShape {
} }
@Override @Override
protected void readRecordContent(ByteBuffer bb) { protected void readContent(ByteBuffer bb) {
x = bb.getDouble(); // x - coordinate x = bb.getDouble(); // x - coordinate
y = bb.getDouble(); // y - coordinate y = bb.getDouble(); // y - coordinate
// if SHAPE-TYPE: 11 // if SHAPE-TYPE: 11
if (type.hasZvalues()) { if (type.hasZ()) {
z = bb.getDouble(); // z - coordinate z = bb.getDouble(); // z - coordinate
} }
// if SHAPE-TYPE: 11 | 21 // if SHAPE-TYPE: 11 | 21
if (type.hasMvalues()) { if (type.hasM()) {
m = bb.getDouble(); // m - value m = bb.getDouble(); // m - value
} }
} }

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.osm.shapefile; package pl.wat.ms4ds.terrain.osmshp;
/** /**
* Shape: PolyLine.<br> * Shape: PolyLine.<br>
@@ -17,7 +17,7 @@ package pl.wat.ms4ds.terrain.osm.shapefile;
* @author jrulka * @author jrulka
* *
*/ */
public class ShpPolyLine extends ShpPollyShape { public class ShpPolyLine extends ShpPolyShape {
public ShpPolyLine(Type shape_type) { public ShpPolyLine(Type shape_type) {
super(shape_type); super(shape_type);

View File

@@ -1,11 +1,12 @@
package pl.wat.ms4ds.terrain.osm.shapefile; package pl.wat.ms4ds.terrain.osmshp;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
/** /**
* Base class for PollyLine, Pollygon * Base class for {@link ShpPolyLine}, {@link ShpPolygon}.
* <p></p> Contains common attributes and methods.
*/ */
public abstract class ShpPollyShape extends ShpShape { public abstract class ShpPolyShape extends ShpShape {
// SHAPE RECORD CONTENT // SHAPE RECORD CONTENT
double xMin; double xMin;
double yMin; double yMin;
@@ -15,20 +16,20 @@ public abstract class ShpPollyShape extends ShpShape {
double yMax; double yMax;
double zMax; double zMax;
double mMax; double mMax;
private int numberOfParts; int numberOfParts;
private int numberOfPoints; int numberOfPoints;
private int[] partsPos; int[] partsPos;
double[] pointsX; // [number of points][x,y,z] double[] pointsX; // [number of points][x,y,z]
double[] pointsY; double[] pointsY;
double[] pointsZ; double[] pointsZ;
double[] valuesM; // [number of points][m-value] double[] valuesM; // [number of points][m-value]
public ShpPollyShape(ShpShape.Type shape_type) { public ShpPolyShape(ShpShape.Type shape_type) {
super(shape_type); super(shape_type);
} }
@Override @Override
protected void readRecordContent(ByteBuffer bb) { protected void readContent(ByteBuffer bb) {
xMin = bb.getDouble(); // x-min xMin = bb.getDouble(); // x-min
yMin = bb.getDouble(); // y-min yMin = bb.getDouble(); // y-min
xMax = bb.getDouble(); // x-max xMax = bb.getDouble(); // x-max
@@ -46,7 +47,7 @@ public abstract class ShpPollyShape extends ShpShape {
pointsY[i] = bb.getDouble(); // y - coordinate pointsY[i] = bb.getDouble(); // y - coordinate
} }
// if SHAPE-TYPE: 13 // if SHAPE-TYPE: 13
if (type.hasZvalues()) { if (type.hasZ()) {
zMin = bb.getDouble(); // z-min zMin = bb.getDouble(); // z-min
zMax = bb.getDouble(); // z-max zMax = bb.getDouble(); // z-max
for (int i = 0; i < numberOfPoints; i++) { for (int i = 0; i < numberOfPoints; i++) {
@@ -54,7 +55,7 @@ public abstract class ShpPollyShape extends ShpShape {
} }
} }
// if SHAPE-TYPE: 13 | 23 // if SHAPE-TYPE: 13 | 23
if (type.hasMvalues()) { if (type.hasM()) {
mMin = bb.getDouble(); // m-min mMin = bb.getDouble(); // m-min
mMax = bb.getDouble(); // m-max mMax = bb.getDouble(); // m-max
valuesM = new double[numberOfPoints]; valuesM = new double[numberOfPoints];

View File

@@ -1,4 +1,4 @@
package pl.wat.ms4ds.terrain.osm.shapefile; package pl.wat.ms4ds.terrain.osmshp;
/** /**
@@ -17,7 +17,7 @@ package pl.wat.ms4ds.terrain.osm.shapefile;
* @author jrulka * @author jrulka
* *
*/ */
public class ShpPolygon extends ShpPollyShape { public class ShpPolygon extends ShpPolyShape {
public ShpPolygon(Type shape_type) { public ShpPolygon(Type shape_type) {
super(shape_type); super(shape_type);

View File

@@ -1,11 +1,12 @@
package pl.wat.ms4ds.terrain.osm.shapefile; package pl.wat.ms4ds.terrain.osmshp;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
/** /**
* Base class for Shapes. * Klasa bazowa reprezentująca kształt w formacie SHP wraz z dodatkową informacją opisową.
* Mozliwe typy kształtów zawiera klasa enumeratora {@link Type}
* *
* @author jrulka * @author jrulka
* *
@@ -35,7 +36,7 @@ public abstract class ShpShape {
} }
ByteBuffer bb = ByteBuffer.wrap(data); ByteBuffer bb = ByteBuffer.wrap(data);
// 1) READ RECORD HEADER // 1) READ RECORD HEADER
readRecordHeader(bb); readHeader(bb);
// Content length in words (16 bits) // Content length in words (16 bits)
byte[] dataContent = new byte[contentLength * 2]; byte[] dataContent = new byte[contentLength * 2];
if (bis.read(dataContent) != contentLength * 2) { if (bis.read(dataContent) != contentLength * 2) {
@@ -49,7 +50,7 @@ public abstract class ShpShape {
try { try {
Type shape_type = Type.getByCode(shapeTypeCode); Type shape_type = Type.getByCode(shapeTypeCode);
if (shape_type == type) { if (shape_type == type) {
readRecordContent(bb); readContent(bb);
} else if (shape_type != type) { } else if (shape_type != type) {
throw new Exception("(Shape) shape_type = " + shape_type + ", but expected " + type); throw new Exception("(Shape) shape_type = " + shape_type + ", but expected " + type);
} }
@@ -58,20 +59,24 @@ public abstract class ShpShape {
} }
} }
protected void readRecordHeader(ByteBuffer bb) { protected void readHeader(ByteBuffer bb) {
bb.order(ByteOrder.BIG_ENDIAN); bb.order(ByteOrder.BIG_ENDIAN);
recordNumber = bb.getInt(); recordNumber = bb.getInt();
contentLength = bb.getInt(); contentLength = bb.getInt();
} }
protected abstract void readRecordContent(ByteBuffer bb); /**
* Reads geometric data from buffer.
* @param bb
*/
protected abstract void readContent(ByteBuffer bb);
void setInfo(DbfRecord info) { void setInfo(DbfRecord info) {
this.info = info; this.info = info;
} }
/** /**
* get the record number of the shape. * Gets the record number of the shape.
* *
* @return record number * @return record number
*/ */
@@ -80,17 +85,17 @@ public abstract class ShpShape {
} }
/** /**
* get the Type of the Shape. * Gets the type of the shape.
* *
* @return ShpShape.Type * @return {@link Type}
*/ */
public Type getShapeType() { public Type getShapeType() {
return type; return type;
} }
//---------------------------------------------------------------------------- /**
// Shape Types * Shape types.
//---------------------------------------------------------------------------- */
public enum Type { public enum Type {
/** /**
* ID= 0 * ID= 0
@@ -151,28 +156,28 @@ public abstract class ShpShape {
public final int code; public final int code;
boolean has_z_values; boolean hasZ;
boolean has_m_values; boolean hasM;
Type(int code, boolean has_z_values, boolean has_m_values) { Type(int code, boolean hasZ, boolean hasM) {
this.has_z_values = has_z_values; this.hasZ = hasZ;
this.has_m_values = has_m_values; this.hasM = hasM;
this.code = code; this.code = code;
} }
public static Type getByCode(int ID) throws Exception { public static Type getByCode(int code) throws Exception {
for (Type st : Type.values()) for (Type st : Type.values())
if (st.code == ID) if (st.code == code)
return st; return st;
throw new Exception("ShapeType: " + ID + " does not exist"); throw new Exception("ShapeType: " + code + " does not exist");
} }
public boolean hasZvalues() { public boolean hasZ() {
return has_z_values; return hasZ;
} }
public boolean hasMvalues() { public boolean hasM() {
return has_m_values; return hasM;
} }
public boolean isTypeOfPolygon() { public boolean isTypeOfPolygon() {

View File

@@ -4,9 +4,9 @@ x_ref=14
y_ref=49 y_ref=49
dx_ref=11 dx_ref=11
dy_ref=7 dy_ref=7
#kwadraty_dir=D:/work/kwadraty_nmt/withElevation/ #kwadraty_dir=D:/work/terrain/
#kwadraty_dir=D:/Workspace/_data/new/ kwadraty_dir=D:/work/kwadraty_nmt/temp/
kwadraty_dir=C:/Workspace/_data/swdt/ms4ds/teren/kwadraty/ #kwadraty_dir=C:/Workspace/_data/swdt/ms4ds/teren/kwadraty/
drogi_dir=au2data/new_teren/Polska/drogi/ drogi_dir=au2data/new_teren/Polska/drogi/
# #
#Rozdzielczosc terenu dl_mk=200 | 100 | 50 | 25 | 20 #Rozdzielczosc terenu dl_mk=200 | 100 | 50 | 25 | 20