diff --git a/src/main/java/pl/wat/ms4ds/terrain/BigSquare.java b/src/main/java/pl/wat/ms4ds/terrain/BigSquare.java index 29518aa..43b5a92 100644 --- a/src/main/java/pl/wat/ms4ds/terrain/BigSquare.java +++ b/src/main/java/pl/wat/ms4ds/terrain/BigSquare.java @@ -1,5 +1,8 @@ package pl.wat.ms4ds.terrain; + +import javafx.scene.image.ImageView; + abstract class BigSquare { abstract Square getKwadrat(int x, int y); @@ -9,6 +12,7 @@ abstract class BigSquare { public transient int liczbaZmian = 0; // TODO zamienic na 100 static final int LICZBA_ZMIAN_DO_ZAPISU = 100000; + public ImageView imageView = null; } diff --git a/src/main/java/pl/wat/ms4ds/terrain/GeomUtils.java b/src/main/java/pl/wat/ms4ds/terrain/GeomUtils.java index cc07918..bb79893 100644 --- a/src/main/java/pl/wat/ms4ds/terrain/GeomUtils.java +++ b/src/main/java/pl/wat/ms4ds/terrain/GeomUtils.java @@ -514,7 +514,7 @@ public class GeomUtils { } } - private static final float PRZEKATNA_MK = MapConsts.DL_MK * (float) Math.sqrt(2); + private static final float PRZEKATNA_MK = MapConsts.SS_SIZE * (float) Math.sqrt(2); /** * Funkcja wyznacza odległość między środkami kwadratów sąsiednich na zadanym kierunku @@ -528,7 +528,7 @@ public class GeomUtils { case SOUTH: case EAST: case WEST: - return MapConsts.DL_MK; + return MapConsts.SS_SIZE; case NORTHEAST: case NORTHWEST: case SOUTHEAST: @@ -860,8 +860,8 @@ public class GeomUtils { float dyf = (float) dy; a = dyf / dxf; // wspolrzedne srodka kwadratu (xp, yp) - int xxp = xp * MapConsts.DL_MK + MapConsts.DL_MK / 2; - int yyp = yp * MapConsts.DL_MK + MapConsts.DL_MK / 2; + int xxp = xp * MapConsts.SS_SIZE + MapConsts.SS_SIZE / 2; + int yyp = yp * MapConsts.SS_SIZE + MapConsts.SS_SIZE / 2; b = yyp - a * xxp; if (dx > 0) { @@ -877,14 +877,14 @@ public class GeomUtils { int xd, xg; int yd, yg; int y1, y2; - xd = (x - 1) * MapConsts.DL_MK; - xg = x * MapConsts.DL_MK; + xd = (x - 1) * MapConsts.SS_SIZE; + xg = x * MapConsts.SS_SIZE; float ydf = a * xd + b; float ygf = a * xg + b; yd = (int) ydf; yg = (int) ygf; - y1 = yd / MapConsts.DL_MK + 1; - y2 = yg / MapConsts.DL_MK + 1; + y1 = yd / MapConsts.SS_SIZE + 1; + y2 = yg / MapConsts.SS_SIZE + 1; temp[dl] = new Coord.Grid(); temp[dl].x = x; temp[dl].y = y1; @@ -1225,7 +1225,7 @@ public class GeomUtils { int yy = p1.y - p2.y; yy *= yy; float odl = (float) Math.sqrt(xx + yy); - odl *= MapConsts.DL_MK; + odl *= MapConsts.SS_SIZE; return odl; } @@ -1245,7 +1245,7 @@ public class GeomUtils { int yy = y1 - y2; yy *= yy; float odl = (float) Math.sqrt(xx + yy); - odl *= MapConsts.DL_MK; + odl *= MapConsts.SS_SIZE; return odl; } @@ -1258,7 +1258,7 @@ public class GeomUtils { */ public static float odleglosc(int dx, int dy) { float odl = (float) Math.sqrt(dx * dx + dy * dy); - odl *= MapConsts.DL_MK; + odl *= MapConsts.SS_SIZE; return odl; } diff --git a/src/main/java/pl/wat/ms4ds/terrain/RightBigSquare.java b/src/main/java/pl/wat/ms4ds/terrain/RightBigSquare.java index 1f38ee4..acacaae 100644 --- a/src/main/java/pl/wat/ms4ds/terrain/RightBigSquare.java +++ b/src/main/java/pl/wat/ms4ds/terrain/RightBigSquare.java @@ -2,111 +2,20 @@ package pl.wat.ms4ds.terrain; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pl.wat.ms4ds.terrain.konwersja.CoordUtils; import java.io.*; -public class RightBigSquare extends BigSquare implements Serializable { +public class RightBigSquare extends BigSquare { private static final Logger logger = LoggerFactory.getLogger(RightBigSquare.class); - private Square squares[][]; + private Square[][] squares; Square getKwadrat(int ssX, int ssY) { return squares[ssX][ssY]; } - /** - * Funkcja zapisująca do pliku duży kwadrat.

- * Zapis następuje w trybie wskazywanym przez atrybut: RightBigSquare.binary. - * - * @param wymuszony flag informujacy o trybie zapisu pliku - * @param fName nazwa pliku - * @throws IOException generowany wyjątek - */ - void updateFile(boolean wymuszony, String fName) throws IOException { - if (wymuszony) { - if (this.liczbaZmian == 0) { - // nie bylo modyfikacji od ostatniego zapisu - return; - } - this.liczbaZmian = -1; - } - this.liczbaZmian++; - this.liczbaZmian %= LICZBA_ZMIAN_DO_ZAPISU; - if (this.liczbaZmian > 0) { - return; - } - if (fName != null) { - fileName = fName; - } - StringBuilder sb = new StringBuilder(100); - sb.append(MapConsts.KWADRATY_DIR); - sb.append(fileName); - sb.append(".bin"); - ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString())); - for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) { - for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) { - float f = squares[x][y].stopienZalesienia * 100.0f; - int hex = (int) f; - hex = (hex > 100) ? 100 : hex; - hex = (hex < 0) ? 0 : hex; - out.writeByte(hex); - f = squares[x][y].stopienZawodnienia * 100.0f; - hex = (int) f; - hex = (hex > 100) ? 100 : hex; - hex = (hex < 0) ? 0 : hex; - out.writeByte(hex); - f = squares[x][y].stopienZabudowy * 100.0f; - hex = (int) f; - hex = (hex > 100) ? 100 : hex; - hex = (hex < 0) ? 0 : hex; - out.writeByte(hex); - f = squares[x][y].stopienZabagnienia * 100.0f; - hex = (int) f; - hex = (hex > 100) ? 100 : hex; - hex = (hex < 0) ? 0 : hex; - out.writeByte(hex); - out.writeInt(squares[x][y].wysokoscSrednia); - out.writeInt(squares[x][y].roznicaWzniesien); - - hex = 0; - int 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; - 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; - 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(); - logger.debug("Zapisano plik mapy: " + sb.toString()); - } - static final int NORTH = 0; static final int NORTH_EAST = 1; static final int EAST = 2; @@ -124,24 +33,54 @@ public class RightBigSquare extends BigSquare implements Serializable { static final byte WEST_CODE = 64; static final byte NORTH_WEST_CODE = -128; - public void save(String dir) throws IOException { - StringBuilder sb = new StringBuilder(100); - sb.append(dir); + public void saveToFile(String dir) throws IOException { // Utworzenie katalogów, gdyby nie istniały. File directory = new File(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++) { - - + 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: " + sb); + logger.debug("Zapisano nowy plik mapy: {}.", path); + } + + /** + * Funkcja zapisująca do pliku duży kwadrat.

+ * + * @param newDir opcjonalna nowa lokalizacja pliku + * @throws IOException generowany wyjątek + */ + void writeToFile(String newDir) throws IOException { + String fn; + if (newDir != null) { + fn = newDir + fileName + ".bin"; + } else { + fn = MapConsts.KWADRATY_DIR + fileName + ".bin"; + } + BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fn)); + byte[] buf = new byte[9 * 256]; + int offset = 0; + for (int x = 0; x < squares.length; x++) { + for (int y = 0; y < squares[0].length; y++) { + Square square = squares[x][y]; + offset = square.writeToBuffer(buf, offset); + if (offset >= buf.length) { + out.write(buf); + offset = 0; + } + } + } + if (offset > 0) { + out.write(buf, 0, offset); + } + out.close(); + logger.debug("Zapisano plik mapy: {}", fn); } /** @@ -153,7 +92,7 @@ public class RightBigSquare extends BigSquare implements Serializable { * @throws IOException generowany wyjątek */ public void saveNewFileWithNewScale20m(String dir, int dlmk) throws IOException { - if (MapConsts.DL_MK != 100) { + if (MapConsts.SS_SIZE != 100) { // operacja tylko dla danych terenowych o kwadratach 200m return; } @@ -318,7 +257,8 @@ public class RightBigSquare extends BigSquare implements Serializable { hex = TerrainType.SWAMP.ID; } ss[i][j].terrainType = (byte) hex; - ss[i][j].elevation = (short) squares[x][y].wysokoscSrednia; + // Konwersja [m] -> [0.25m] + ss[i][j].elevation = (short) (squares[x][y].wysokoscSrednia * 4); } } } @@ -327,7 +267,7 @@ public class RightBigSquare extends BigSquare implements Serializable { for (int i = 0; i < m; i++) { for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) { for (int j = 0; j < m; j++) { - ss_all[x][y][i][j].save(out); + ss_all[x][y][i][j].write(out); } } } @@ -343,8 +283,8 @@ public class RightBigSquare extends BigSquare implements Serializable { * @param dlmk * @throws IOException */ - public void saveNewFileWithNewFormatZero(String dir, int dlmk) throws IOException { - if (MapConsts.DL_MK != 100) { + public void saveNewFileWithNewFormatWithElevetion(String dir, int dlmk) throws IOException { + if (MapConsts.SS_SIZE != 100) { // operacja tylko dla danych terenowych o kwadratach 200m return; } @@ -376,10 +316,11 @@ public class RightBigSquare extends BigSquare implements Serializable { 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++) { - ss.elevation = (short) squares[x][y].wysokoscSrednia; + // 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.save(out); + ss.write(out); } } } @@ -388,78 +329,211 @@ public class RightBigSquare extends BigSquare implements Serializable { logger.debug("Zapisano nowy plik mapy: {} dla rozmiaru MK= {}", sb, dlmk); } - void load(String FName) throws IOException { - try { - fileName = FName; - StringBuilder sb = new StringBuilder(100); - sb.append(MapConsts.KWADRATY_DIR); - sb.append(fileName); + /** + * 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) { + // operacja tylko dla danych terenowych o kwadratach 200m + return; + } + final 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 + ".bin"); + Square.RawData ss = new Square.RawData(); + BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(sb.toString())); + byte[] buf = new byte[9 * 256]; + int offset = 0; + for (int x = 0; x < squares.length; x++) { + for (int y = 0; y < squares[0].length; y++) { + Square square = squares[x][y]; + square.elevation = square.wysokoscSrednia; + if (square.elevation > 2660) { + logger.warn("Elevation: {}, fn= {} ", square.elevation, fileName); + } + for (int i = 0; i < m * m; i++) { + offset = square.writeToBuffer(buf, offset); + if (offset >= buf.length) { + out.write(buf); + offset = 0; + } + } + } + } + if (offset > 0) { + out.write(buf, 0, offset); + } + out.close(); + logger.debug("Zapisano plik mapy: {}", fileName); + } + + public void saveFileFromNewToOldFormat(String dir) throws IOException { + StringBuilder sb = new StringBuilder(100); + sb.append(dir); + // Utworzenie katalogów, gdyby nie istniały. + File directory = new File(sb.toString()); + directory.mkdirs(); + sb.append(fileName); + if (fileName.indexOf('.') < 0) { sb.append(".bin"); - Square.RawData ss = new Square.RawData(); - ObjectInputStream in = new ObjectInputStream(new FileInputStream(sb.toString())); + } + Square.RawData ss = new Square.RawData(); + ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString())); + for (int x = 0; x < squares.length; x++) { + for (int y = 0; y < squares[0].length; y++) { + float f; + int hex = 0; + int hex_s = 0; + int hex_w = 0; + int hex_b = 0; + int hex_f = 0; + switch (squares[x][y].terrainType) { +// case 0, 1, 4: +// hex = 0; +// break; + case 2: + hex_s = 100; + break; + case 3: + hex_w = 100; + break; + case 5: + hex_b = 100; + break; + case 6: + hex_f = 100; + break; + default: + } + out.writeByte(hex_f); + out.writeByte(hex_w); + out.writeByte(hex_b); + out.writeByte(hex_s); + int elevation = (int) squares[x][y].elevation; + out.writeInt(elevation); + out.writeInt(squares[x][y].roznicaWzniesien); + int bit_1; + hex = 0; + bit_1 = 1; + byte[] roads = squares[x][y].roads; + for (int i = 0; i < roads.length; i++) { + // jest odcinek drogi na tym kierunku + if (roads[i] > 0) { + hex |= bit_1; + } + bit_1 <<= 1; + } + out.writeByte(hex); + hex = 0; + bit_1 = 1; + byte[] watercourses = squares[x][y].watercourses; + for (int i = 0; i < watercourses.length; i++) { + // jest odcinek przeszkody wodnej na tym kierunku + if (watercourses[i] > 1) { + hex |= bit_1; + } + bit_1 <<= 1; + } + out.writeByte(hex); + hex = 0; + bit_1 = 1; + for (int i = 0; i < watercourses.length; i++) { + // jest odcinek rowu na tym kierunku + if (watercourses[i] == 1) { + hex |= bit_1; + } + bit_1 <<= 1; + } + out.writeByte(hex); + } + } + out.close(); + logger.debug("Zapisano nowy plik mapy: {}", sb); + } + + void readFromFileNew(String dir) throws IOException { + if (fileName == null) { + 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]; - int x0 = idX * MapConsts.SS_PER_BS_X; - int y0 = idY * 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(x0 + x, y0 + 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; - ss.load(in); - switch (ss.terrainType) { - case 0: - break; - case 1: - break; - case 4: - break; - case 2: - kw.stopienZabagnienia = 1.f; - break; - case 3: - kw.stopienZawodnienia = 1.f; - break; - case 5: - kw.stopienZabudowy = 1.f; - break; - case 6: - kw.stopienZalesienia = 1.f; - break; - } + } + } + in.close(); + logger.debug("Doczytano plik mapy: " + fullPath); + } catch (IOException e) { + squares = null; + throw e; + } + } - kw.wysokoscSrednia = ss.elevation; - kw.roznicaWzniesien = 0; - - int bit_1 = 1; - int hex = ss.majorRoads; - for (int i = 0; i < kw.jestDroga.length; i++) { - // jest odcinek rowu na tym kierunku - if ((hex & bit_1) != 0) { - kw.jestDroga[i] = true; - } - bit_1 <<= 1; + 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); } - bit_1 = 1; - hex = ss.rivers; - for (int i = 0; i < kw.jestPrzeszkodaWodna.length; i++) { - // jest odcinek rowu na tym kierunku - if ((hex & bit_1) != 0) { - kw.jestPrzeszkodaWodna[i] = true; - } - bit_1 <<= 1; - } - bit_1 = 1; - hex = ss.drains; - for (int i = 0; i < kw.jestRow.length; i++) { - // jest odcinek rowu na tym kierunku - if ((hex & bit_1) != 0) { - kw.jestRow[i] = true; - } - bit_1 <<= 1; + if (kw.elevation < -3) { + logger.warn("Elevation: {}, fn= {} ", kw.elevation, fileName); } } } in.close(); - logger.debug("Doczytano plik mapy: " + sb.toString()); + logger.debug("Doczytano plik mapy: " + fullPath); } catch (IOException e) { squares = null; throw e; @@ -478,7 +552,7 @@ public class RightBigSquare extends BigSquare implements Serializable { boolean zalesienie, boolean zawodnienie, boolean zabudowa, boolean zabagnienie, boolean wysokosc, boolean roznicaWzniesien, boolean drogi, boolean rzeki, boolean rowy) throws IOException { - if (MapConsts.DL_MK != 200) { + if (MapConsts.SS_SIZE != 200) { // operacja tylko dla danych terenowych o kwadratach 200m return; } @@ -602,20 +676,28 @@ public class RightBigSquare extends BigSquare implements Serializable { public RightBigSquare() { } - // konstruktor ladujacy duzy kwadrat z pliku binarnego - RightBigSquare(String FName) throws IOException { + /** + * konstruktor ladujacy duzy kwadrat z pliku binarnego w starym formacie + * + * @param fname nazwa pliku z danymi + */ + RightBigSquare(String fname, String dir) throws IOException { try { - fileName = FName + ".bin"; + File f = new File(fname); + fileName = f.getName(); + fileName = fileName.substring(0, fileName.lastIndexOf('.')); StringBuilder sb = new StringBuilder(100); - sb.append(MapConsts.KWADRATY_DIR); - sb.append(fileName); + if (dir == null) { + sb.append(MapConsts.KWADRATY_DIR); + } else { + sb.append(dir); + } + sb.append(fileName + ".bin"); ObjectInputStream in = new ObjectInputStream(new FileInputStream(sb.toString())); squares = new Square[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y]; - int x0 = idX * MapConsts.SS_PER_BS_X; - int y0 = idY * 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(x0 + x, y0 + y); + Square kw = new Square(x, y); squares[x][y] = kw; int hex = in.readByte(); kw.stopienZalesienia = (float) hex * (1.0f / 100.f); @@ -626,9 +708,18 @@ public class RightBigSquare extends BigSquare implements Serializable { 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) { + logger.warn("Elevation: {}, fn= {} ", kw.wysokoscSrednia, fileName); + } kw.roznicaWzniesien = in.readInt(); int bit_1 = 1; hex = in.readByte(); + if (kw.jestDroga == null) { + kw.jestDroga = new boolean[8]; + } for (int i = 0; i < kw.jestDroga.length; i++) { // jest odcinek rowu na tym kierunku if ((hex & bit_1) != 0) { @@ -638,6 +729,9 @@ public class RightBigSquare extends BigSquare implements Serializable { } bit_1 = 1; hex = in.readByte(); + if (kw.jestPrzeszkodaWodna == null) { + kw.jestPrzeszkodaWodna = new boolean[8]; + } for (int i = 0; i < kw.jestPrzeszkodaWodna.length; i++) { // jest odcinek rowu na tym kierunku if ((hex & bit_1) != 0) { @@ -647,6 +741,9 @@ public class RightBigSquare extends BigSquare implements Serializable { } bit_1 = 1; hex = in.readByte(); + if (kw.jestRow == null) { + kw.jestRow = new boolean[8]; + } for (int i = 0; i < kw.jestRow.length; i++) { // jest odcinek rowu na tym kierunku if ((hex & bit_1) != 0) { diff --git a/src/main/java/pl/wat/ms4ds/terrain/Square.java b/src/main/java/pl/wat/ms4ds/terrain/Square.java index c9e8454..ba0d33f 100644 --- a/src/main/java/pl/wat/ms4ds/terrain/Square.java +++ b/src/main/java/pl/wat/ms4ds/terrain/Square.java @@ -1,6 +1,7 @@ package pl.wat.ms4ds.terrain; +import java.io.DataInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -8,9 +9,9 @@ import java.io.ObjectOutputStream; public class Square { /** - * The height above the level of the sea. Unit of measure decimeter [m]. + * The height above the level of the sea. Unit of measure meter [m]. */ - float elevation; + public float elevation; /** * Terrain type.

Possible values: @@ -22,21 +23,21 @@ public class Square { * 5 - BUILDINGS * 6 - FOREST */ - short terrainType; + public short terrainType; /** * Type of watercourse (water obstacle) in a given direction. Each index corresponds to a given direction. *

Possible values: 0 - no watercourse, 1 - drain, ditch, 2 - canal, stream, 3 - river */ - byte[] watercourses; + public final byte[] watercourses; /** * Type of road in a given direction. Each index corresponds to a given direction. *

Possible values: 0 - no road, 1 - small roads, 2 - minor roads, 3 - major roads */ - byte[] roads; + public final byte[] roads; - //////////////////////////////////////// + /// ///////////////////////////////////// /// tymczasowo public float stopienZabudowy; public float stopienZalesienia; @@ -47,11 +48,12 @@ public class Square { public boolean[] jestPrzeszkodaWodna; public int roznicaWzniesien; public int wysokoscSrednia; - //////////////////////////////////////// + + /// ///////////////////////////////////// public static class RawData { /** - * The height above the level of the sea. Unit of measure decimeter [dm]. + * The height above the level of the sea. Unit of measure [0.25m]. */ short elevation; /** @@ -107,7 +109,7 @@ public class Square { rivers = 0; } - public void save(ObjectOutputStream out) throws IOException { + public void write(ObjectOutputStream out) throws IOException { out.writeShort(elevation); out.writeByte(terrainType); out.writeByte(smallRoads); @@ -118,7 +120,7 @@ public class Square { out.writeByte(rivers); } - public void load(ObjectInputStream in) throws IOException { + public void read(ObjectInputStream in) throws IOException { elevation = in.readShort(); terrainType = in.readByte(); smallRoads = in.readByte(); @@ -140,7 +142,7 @@ public class Square { public RawData(Square kw) { terrainType = (byte) kw.terrainType; // Konwersja na decymetry. - elevation = (short) (kw.elevation * 10); + elevation = (short) (kw.elevation * 4); byte bit = 1; for (int i = 0; i < kw.watercourses.length; i++) { switch (kw.watercourses[i]) { @@ -156,10 +158,6 @@ public class Square { default: break; } - bit <<= 1; - } - bit = 1; - for (int i = 0; i < kw.roads.length; i++) { switch (kw.roads[i]) { case 1: smallRoads |= bit; @@ -176,6 +174,43 @@ public class Square { 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; + } + } + } public static final Square EMPTY = new Square(-1, -1); @@ -189,13 +224,122 @@ public class Square { this.y = y; roads = new byte[8]; watercourses = new byte[8]; - // Brak danych o wysokości. - elevation = -1000; } public Square(int x, int y, RawData rawData) { - this(x, y); - elevation = rawData.elevation / 10.f; + this.x = x; + this.y = y; + roads = new byte[8]; + watercourses = new byte[8]; + // 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 int writeToBuffer(byte[] buffer, int offset) { + // Konwersja [m] -> [0.25m]. + int elev = (short) (elevation * 4); + byte bit = 1; + byte drains = 0; + byte streams = 0; + byte rivers = 0; + byte smallRoads = 0; + byte minorRoads = 0; + byte majorRoads = 0; + for (int i = 0; i < watercourses.length; i++) { + switch (watercourses[i]) { + case 1: + drains |= bit; + break; + case 2: + streams |= bit; + break; + case 3: + rivers |= bit; + break; + default: + break; + } + switch (roads[i]) { + case 1: + smallRoads |= bit; + break; + case 2: + minorRoads |= bit; + break; + case 3: + majorRoads |= bit; + break; + default: + break; + } + bit <<= 1; + } + byte b1 = (byte) (elev & 0xFF); + elev >>= 8; + byte b0 = (byte) (elev & 0xFF); + if (b0 == -1 && b1 == -4) { + System.out.println("a"); + } + buffer[offset + 1] = b1; + buffer[offset] = b0; + buffer[offset + 2] = (byte) terrainType; + buffer[offset + 3] = smallRoads; + buffer[offset + 4] = minorRoads; + buffer[offset + 5] = majorRoads; + buffer[offset + 6] = drains; + buffer[offset + 7] = streams; + buffer[offset + 8] = rivers; + return offset + 9; + } + + public int readFromBuffer(byte[] buffer, int offset) { + int elev = buffer[offset] & 0xFF; + elev = (elev << 8) + (buffer[offset + 1] & 0xFF); + short v = (short) elev; + // Konwersja na metry a[0.25m] -> b[m] + elevation = (float) (v) / 4; + if (elevation > 2660) { + System.out.println("h=" + elevation); + } + terrainType = buffer[offset + 2]; + byte smallRoads = buffer[offset + 3]; + byte minorRoads = buffer[offset + 4]; + byte majorRoads = buffer[offset + 5]; + byte drains = buffer[offset + 6]; + byte streams = buffer[offset + 7]; + byte rivers = buffer[offset + 8]; + int bit = 1; + // 8 kierunków geograficznych (0 - NORTH, 1 - NORTH_EAST, ...) + for (int i = 0; i < 8; i++) { + int b1 = ((majorRoads & bit) > 0) ? 3 : 0; + int b2 = ((minorRoads & bit) > 0) ? 2 : 0; + int b3 = ((smallRoads & bit) > 0) ? 1 : 0; + roads[i] = (byte) (b1 + b2 + b3); + b1 = ((rivers & bit) > 0) ? 3 : 0; + b2 = ((streams & bit) > 0) ? 2 : 0; + b3 = ((drains & bit) > 0) ? 1 : 0; + watercourses[i] = (byte) (b1 + b2 + b3); + bit <<= 1; + } + return offset + 9; + } + + 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++) { @@ -213,12 +357,6 @@ public class Square { public final int x; public final int y; - public double sumaWysokosci; - public int count = 1; - public double ell; - public double nll; - public double eur; - public double nur; @Override @@ -250,7 +388,7 @@ public class Square { }; linia.append(c); linia.append(' '); - String s = String.format("%5.1f", elevation); + String s = String.format("%7.2f", elevation); linia.append(s); linia.append(' '); for (byte road : roads) { diff --git a/src/main/java/pl/wat/ms4ds/terrain/Teren.java b/src/main/java/pl/wat/ms4ds/terrain/Teren.java index 5f96522..01535e5 100644 --- a/src/main/java/pl/wat/ms4ds/terrain/Teren.java +++ b/src/main/java/pl/wat/ms4ds/terrain/Teren.java @@ -41,17 +41,16 @@ public class Teren { private static double maxKatNachylTerenuNaPrzelaj; /** - * Jawne wywolanie zapisu do pliku bufora zmian terenu + * Jawne wywolanie zapisu do pliku bufora zmian terenu. Zapisane zostaną aktywne/załadowane duże kwadraty. */ - public static void zapisBuforaMapyDoPliku() { + public static void saveToFiles(String dir) { for (int i = 0; i < bigSquares.length; i++) { for (int j = 0; j < bigSquares[i].length; j++) { BigSquare bs = bigSquares[i][j]; - if (null != bs && bs instanceof RightBigSquare) { - RightBigSquare rbs = (RightBigSquare) bigSquares[i][j]; + if (bs instanceof RightBigSquare rbs) { try { - rbs.liczbaZmian++; - rbs.updateFile(true, null); + rbs.writeToFile(dir); + bigSquares[i][j] = null; } catch (IOException e) { LOGGER.warn("Błąd zapisu pliku mapy: " + rbs.fileName); } @@ -73,107 +72,6 @@ public class Teren { System.gc(); } - /** - * Funkcja zamienia reprezentację w postaci (stopnie, minuty, sekundy) długości geograficznej WGS-84 - * na wartość w milisekundach. - * - * @param wspolrzedneUtm - * @return - */ - public static int zamienWspSMSNaWspXms(String wspolrzedneUtm) { - String d = wspolrzedneUtm.substring(8, 10); - int ms = Integer.parseInt(d) * MapConsts.DEG_MS; - d = wspolrzedneUtm.substring(10, 12); - ms += Integer.parseInt(d) * 60000; - d = wspolrzedneUtm.substring(12, 14); - ms += Integer.parseInt(d) * 1000; - if (wspolrzedneUtm.charAt(14) == 'W') { - ms = -ms; - } - ms += 180 * MapConsts.DEG_MS; - return ms; - } - - /** - * Funkcja zamienia reprezentację w postaci (stopnie, minuty, sekundy) szerokości geograficznej WGS-84 - * na wartość w milisekundach. - * - * @param wspolrzedneUtm - * @return - */ - public static int zamienWspSMSNaWspYms(String wspolrzedneUtm) { - String d = wspolrzedneUtm.substring(0, 2); - int ms = Integer.parseInt(d) * MapConsts.DEG_MS; - d = wspolrzedneUtm.substring(2, 4); - ms += Integer.parseInt(d) * 60000; - d = wspolrzedneUtm.substring(4, 6); - ms += Integer.parseInt(d) * 1000; - if (wspolrzedneUtm.charAt(6) == 'S') { - ms = -ms; - } - ms += 90 * MapConsts.DEG_MS; - return ms; - } - - /** - * Zamienia współrzędne geograficzne WGS-84 w milisekundach (xms,yms) na reprezentację stopnie, minuty, sekundy. - * - * @param xms - * @param yms - * @return - */ - public static String zamienWspXmsYmsNaWspSMS(long xms, long yms) { - char cx = 'E'; - // stopnie dlugosci geograficznej - long x_st = xms / MapConsts.DEG_MS - 180; - if (x_st < 0) { - x_st = -x_st; - cx = 'W'; - } - long reszta = xms % MapConsts.DEG_MS; - // minuty dlugosci geograficznej - long x_m = reszta / 60000; - // sekundy dlugosci geograficznej - long x_s = reszta % 60000; - x_s /= 1000; - - char cy = 'N'; - // stopnie szerokosci geograficznej - long y_st = yms / MapConsts.DEG_MS - 90; - if (y_st < 0) { - y_st = -y_st; - cy = 'S'; - } - reszta = yms % MapConsts.DEG_MS; - // minuty szerokosci geograficznej - long y_m = reszta / 60000; - // sekundy szerokosci geograficznej - long y_s = reszta % 60000; - y_s /= 1000; - - return String.format( - "%1$02d%2$02d%3$02d%4$c%5$03d%6$02d%7$02d%8$c", y_st, y_m, y_s, cy, x_st, x_m, x_s, cx); - } - - // funkcja wyznacza wspolrzedne UTM ze wspolrzednych dziesietnych - // Zalozenie: wspolrzedne w zakresie dlugosc wschodnia do 100 stopni, szerokosc polnocna - public static String zamienWspGeoDziesietnieNaWspSMS(float lon, float lat) { - int x_st = (int) lon; - int y_st = (int) lat; - - float s = (lon - x_st) * 3600; - int x_s = (int) s; - int x_m = x_s / 60; - x_s = x_s % 60; - - s = (lat - y_st) * 3600; - int y_s = (int) s; - int y_m = y_s / 60; - y_s = y_s % 60; - - return String.format("%1$02d%2$02d%3$02dN%4$03d%5$02d%6$02dE", y_st, y_m, y_s, x_st, x_m, x_s); - } - /** * Zwraca nazwę pliku na podstawie współrzędnych geograficznych. * @@ -182,17 +80,14 @@ public class Teren { * @return Nazwa zwracanego pliku z danymi (null - gdy niepoprawne współrzędne). */ public static String getFileName(double lat, double lon) { - int idX = Coord.zamienDlugoscGeoNaIdKwadratuX(lon); - int idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(lat); + int idX = Coord.zamienDlugoscGeoNaIdKwadratuX(lon); + int idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(lat); int bigX = idX / MapConsts.SS_PER_BS_X; int bigY = idY / MapConsts.SS_PER_BS_Y; return getFileName(bigX, bigY); } private static String getFileName(int bsX, int bsY) { - if ((bsX < 0) || (bsY < 0)) { - return null; - } int x_stop = MapConsts.X_REF + bsX / MapConsts.BS_PER_DEG_X - 180; char cLon = (x_stop < 0) ? 'W' : 'E'; if (x_stop < 0) { @@ -200,7 +95,6 @@ public class Teren { } int dx = bsX % MapConsts.BS_PER_DEG_X; char cx = LITERALS.charAt(dx); - int y_stop = MapConsts.Y_REF + bsY / MapConsts.BS_PER_DEG_Y - 90; char cLat = (y_stop < 0) ? 'S' : 'N'; if (y_stop < 0) { @@ -209,14 +103,12 @@ public class Teren { int dy = bsY % MapConsts.BS_PER_DEG_Y; char cy = LITERALS.charAt(dy); // przykładowa nazwa pliku: E024B_N50F - + // StringBuilder sb = new StringBuilder(); -// sb.append(MapConsts.KWADRATY_DIR); sb.append(cLon); - if (x_stop < 100) { - sb.append('0'); - } if (x_stop < 10) { + sb.append("00"); + } else if (x_stop < 100) { sb.append('0'); } sb.append(x_stop); @@ -231,21 +123,22 @@ public class Teren { return sb.toString(); } - private static BigSquare loadArea(int bsX, int bsY) { - String fName = getFileName(bsX, bsY); + private static BigSquare loadAreaOld(int bsX, int bsY) { + String fName = getFileName(bsX, bsY) + ".bin"; try { - return new RightBigSquare(fName); + return new RightBigSquare(fName, null); } catch (IOException e) { LOGGER.warn("Brak pliku mapy: {}{}{}", MapConsts.KWADRATY_DIR, fName, ".bin"); return EmptyBigSquare.EMPTY_BIG_SQUARE; } } - private static BigSquare loadAreaNew(int bsX, int bsY) { + private static BigSquare loadArea(int bsX, int bsY) { String fName = getFileName(bsX, bsY); try { RightBigSquare bs = new RightBigSquare(); - bs.load(fName); + bs.fileName = fName; + bs.readFromFile(MapConsts.KWADRATY_DIR); return bs; } catch (IOException e) { LOGGER.warn("Brak pliku mapy: {}{}{}", MapConsts.KWADRATY_DIR, fName, ".bin"); @@ -262,48 +155,53 @@ public class Teren { } public static Square getKwadrat(double lat, double lon) { - int idX = Coord.zamienDlugoscGeoNaIdKwadratuX(lon); - int idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(lat); + int idX = Coord.zamienDlugoscGeoNaIdKwadratuX(lon); + int idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(lat); return getKwadrat(idX, idY); } - public static Square getKwadrat(int idX, int idY) { - if (idX < 0 || idY < 0) { + /** + * Zwraca kwadrat o podanych współrzędnych siatki (grida). + * + * @param x współrzędna pozioma (indeks kolumny) + * @param y współrzędna pionowa (indeks wiersza) + * @return obiekt reprezentujący charakterystyki fragmentu terenu + */ + public static Square getKwadrat(int x, int y) { + if (x < 0 || y < 0) { return EMPTY; } // wspolrzędna x dużego kwadratu - int bsX = idX / MapConsts.SS_PER_BS_X; + int bsX = x / MapConsts.SS_PER_BS_X; // wspolrzędna y dużego kwadratu - int bsY = idY / 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) { return EMPTY; } // wspolrzędna x małego kwadratu w ramach dużego kwadratu - int ssX = idX % MapConsts.SS_PER_BS_X; + int ssX = x % MapConsts.SS_PER_BS_X; // wspolrzędna y małego kwadratu w ramach dużego kwadratu - int ssY = idY % MapConsts.SS_PER_BS_Y; + int ssY = y % MapConsts.SS_PER_BS_Y; synchronized (bsSynch) { if (bigSquares[bsX][bsY] == null) { makeRoom(bsX, bsY); bigSquares[bsX][bsY] = loadArea(bsX, bsY); -// bigSquares[bsX][bsY] = loadAreaNew(bsX, bsY); } } return bigSquares[bsX][bsY].getKwadrat(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 void makeRoom(int bigX, int bigY) { if (bigSquaresInMemory >= MapConsts.MAX_BIG_SQUARES_IN_MEMORY) { // najpierw zapisuję w pliku dokonane zmiany - if (bigSquares[history[0].x][history[0].y] instanceof RightBigSquare) { - RightBigSquare rbs = (RightBigSquare) bigSquares[history[0].x][history[0].y]; + if (bigSquares[history[0].x][history[0].y] instanceof RightBigSquare rbs) { try { //!! dla potrzeb generowania danych rbs.liczbaZmian = 1; - rbs.updateFile(true, null); + rbs.writeToFile(null); } catch (IOException e) { e.printStackTrace(); } @@ -332,8 +230,8 @@ public class Teren { private static final double TANG_ALFA_MAX_NA_DRODZE; private static final double TANG_ALFA_MIN_NA_DRODZE; - private static double a1; - private static double b1; + private static final double a1; + private static final double b1; /** * Funkcja opisujaca zmianę stopnia przejezdności podczas ruchu na drodze dla kątów w przedziale <22.5, 45> @@ -352,8 +250,8 @@ public class Teren { private static final double TANG_ALFA_MAX_NA_PRZELAJ; private static final double TANG_ALFA_MIN_NA_PRZELAJ; - private static double a2; - private static double b2; + private static final double a2; + private static final double b2; /** * Funkcja opisujaca zmianę stopnia przejezdności podczas ruchu na przełaj dla kątów w przedziale <22.5, 45> @@ -378,7 +276,7 @@ public class Teren { static { 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"); minStopienPrzejezd = Double.parseDouble(MapConsts.ustawienia.getProperty("minimalny_stopien_przejezdnosci")); @@ -496,19 +394,40 @@ public class Teren { LOGGER.debug("start"); // Teren.normalizujDanePokrycia(); - String dir = "C:/users/jrulka/Workspace/_data/new/"; - Square kw = getKwadrat(1500, 2100); + String newDir = "D:/work/kwadraty_nmt/temp/25/"; + String dir1 = "D:/work/nowe/25m/"; + String inDir = "D:/work/kwadraty_nmt/withElevation/25m/"; + String dir2 = "C:/Workspace/_data/swdt/ms4ds/teren/kwadraty/100m/"; + +// Square kw = getKwadrat(1500, 2100); // System.out.println(kw); // kw = getKwadrat(2100, 1500); // System.out.println(kw); + Set fileNames = NMTDataProvider.listFiles(dir1); +// String fn = "E017B_N54E"; +// RightBigSquare rbs = new RightBigSquare(dir2 + fn + ".bin", null); +// rbs.writeToFileOldToNewFormatWithElevetion(dir1, 25); - Set fileNames = NMTDataProvider.listFiles(MapConsts.KWADRATY_DIR); - Teren.wygenerujNoweDane(fileNames, dir, 100); -// Teren.wygenerujCzysteDane(100, false, false, false, false, true, false, false, false, false); + RightBigSquare rbs = new RightBigSquare(); + rbs.fileName = "E017B_N54E"; + rbs.readFromFileNew(dir1); +// Teren.generateData(fileNames, dir1, newDir); + +// Teren.generateDataOldToNewFormat(fileNames, dir2, dir1, 25); // Teren.wygenerujCzysteDane(dir, 25, false, false, false, false, true, false, false, false, false); // Teren.wyzerujDane(); // Teren.zapisBuforaMapyDoPliku(); +// String dir1 = "D:/work/kwadraty_nmt/withElevation/25m/"; +// Set fileNames = NMTDataProvider.listFiles(dir1); +// 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(dir1); +// } +// rbs.writeToFile(newDir); } @@ -523,7 +442,7 @@ public class Teren { // wyzerowanie wszystkiego poza wysokością i różnicą wzniesień rbs.resetSquares(true, true, true, true, true, true, true, true, true); rbs.liczbaZmian = 1; - rbs.updateFile(true, null); + rbs.writeToFile(null); } } catch (IOException e) { // e.printStackTrace(); @@ -578,10 +497,9 @@ public class Teren { for (int y = 0; y < bigSquares[x].length; y++) { try { BigSquare bs = bigSquares[x][y]; - if (bs != null && bs instanceof RightBigSquare) { - RightBigSquare rbs = (RightBigSquare) bs; + if (bs instanceof RightBigSquare rbs) { rbs.liczbaZmian = 1; - rbs.updateFile(true, null); + rbs.writeToFile(null); } } catch (IOException e) { // e.printStackTrace(); @@ -615,10 +533,9 @@ public class Teren { for (int y = 0; y < bigSquares[x].length; y++) { try { BigSquare bs = bigSquares[x][y]; - if (bs != null && bs instanceof RightBigSquare) { - RightBigSquare rbs = (RightBigSquare) bs; + if (bs instanceof RightBigSquare rbs) { rbs.liczbaZmian = 1; - rbs.updateFile(true, null); + rbs.writeToFile(null); } } catch (IOException e) { // e.printStackTrace(); @@ -628,14 +545,32 @@ public class Teren { } /** - * @param dir katalog z danymi terenowymi np. "d:/Workspace2/kwadraty/czyste-wysokosc/" - * @param dlmk docelowy rozmiar generowanych kwadratów terenu + * 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 dlmk docelowy rozmiar generowanych kwadratów terenu */ - public static void wygenerujNoweDane(Set fileNames, String dir, int dlmk) throws IOException { - // WYGENEROWANIE CZYSTYCH PLIKÓW DANYCH Z ZACHOWANIEM TYLKO WYSOKOSCI I ROZNICY POZIOMOW WZNIESIEN + public static void generateDataOldToNewFormat(Set fileNames, String inDir, String outDir, int dlmk) throws IOException { for (String fileName : fileNames) { - RightBigSquare rbs = new RightBigSquare(fileName); - rbs.saveNewFileWithNewFormatZero(dir, dlmk); + RightBigSquare rbs = new RightBigSquare(fileName, null); + rbs.writeToFileOldToNewFormatWithElevetion(outDir, dlmk); + } + + } + + /** + * Generuje pliki z danymi w starym formacie na podstawie danych w nowym formacie. + * + * @param outDir katalog z danymi terenowymi np. "d:/Workspace2/kwadraty/czyste-wysokosc/" + */ + public static void generateData(Set 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.readFromFileNew(inDir); +// rbs.writeToFile(outDir); } } diff --git a/src/main/java/pl/wat/ms4ds/terrain/konwersja/CoordTest.java b/src/main/java/pl/wat/ms4ds/terrain/konwersja/CoordTest.java index cc2a4da..0dbec75 100644 --- a/src/main/java/pl/wat/ms4ds/terrain/konwersja/CoordTest.java +++ b/src/main/java/pl/wat/ms4ds/terrain/konwersja/CoordTest.java @@ -3,13 +3,105 @@ package pl.wat.ms4ds.terrain.konwersja; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pl.wat.ms4ds.terrain.Coord; +import pl.wat.ms4ds.terrain.MapConsts; + +import java.io.*; +import java.nio.ByteBuffer; public class CoordTest { static Logger logger = LoggerFactory.getLogger(CoordTest.class); static void main() { + byte[] INT_BYTE_ARRAY = new byte[]{ + (byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE + }; + int intValue = 0xCAFEBABE; + int v1 = 32000; + short value = 32033; + byte[] bytes1 = new byte[Short.BYTES]; + int length = bytes1.length; + for (int i = 0; i < length; i++) { + bytes1[length - i - 1] = (byte) (value & 0xFF); + value >>= 8; + } + value = 0; + for (byte b : bytes1) { + value = (short) ((value << 8) + (b & 0xFF)); + } + v1 = bytes1[0] & 0xFF; + v1 = (v1 << 8) + (bytes1[1] & 0xFF); + value = (short) v1; +// try { +// BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("./CoordTest.bin")); + short[] val1 = {-4, -100, 32035, 32036, 32037}; + byte[] val2 = {24, 25, 26, 27, 28}; + byte[] val3 = {7, 8, 9, 10, 11}; + int pos = 0; + byte[] buf = new byte[4 * 5]; + for (int i = 0; i < 5; i++) { + // 4 * i - pozycja startowa i-tego recordu + pos = 4 * i; + short val = val1[i]; + buf[pos + 1] = (byte) (val & 0xFF); + val >>= 8; + buf[pos] = (byte) (val & 0xFF); + buf[pos + 2] = val2[i]; + buf[pos + 3] = val3[i]; + } +// out.write(buf); +// out.flush(); +// out.close(); + +// BufferedInputStream in = new BufferedInputStream(new FileInputStream("./CoordTest.bin"), 8); +// byte[] buf = new byte[4 * 5]; +// in.read(buf2); + for (int i = 0; i < 5; i++) { + // 4 * i - pozycja startowa i-tego recordu + pos = 4 * i; + v1 = buf[pos] & 0xFF; + v1 = (v1 << 8) | (buf[pos + 1] & 0xFF); + val1[i] = (short) v1; + val2[i] = buf[pos + 2]; + val3[i] = buf[pos + 3]; + } +// in.close(); + +// } catch (IOException e) { +// System.out.println(e.getMessage()); +// } + + + short e1 = 110; + float elevation = (float) (e1) / 4; + e1 = 111; + elevation = (float) (e1) / 4; + float f1 = 101.237f; + f1 *= 4; + f1 = (int) f1; + f1 /= 4; + f1 = 101.257f; + f1 *= 4; + f1 = (int) f1; + f1 /= 4; + f1 = 101.25f; + f1 *= 4; + f1 = (int) f1; + f1 /= 4; + f1 = 101.75f; + f1 *= 4; + f1 = (int) f1; + f1 /= 4; + f1 = 101.0237f; + f1 *= 4; + f1 = (int) f1; + f1 /= 4; + f1 = 101.82f; + f1 *= 4; + f1 = (int) f1; + f1 /= 4; + String s = String.format("e = %9.4f", Math.E); logger.debug(" "); diff --git a/src/main/java/pl/wat/ms4ds/terrain/konwersja/CoordUtils.java b/src/main/java/pl/wat/ms4ds/terrain/konwersja/CoordUtils.java index e361794..dfdc303 100644 --- a/src/main/java/pl/wat/ms4ds/terrain/konwersja/CoordUtils.java +++ b/src/main/java/pl/wat/ms4ds/terrain/konwersja/CoordUtils.java @@ -39,7 +39,7 @@ public class CoordUtils { // kw.setWysokoscSrednia((int) (daneWysok.suma / daneWysok.licz + 0.5)); } logger.debug("Poczatek zapisu danych dla regionu " + nmt_fn + " >> " + i + "/" + (args.length - 1)); - Teren.zapisBuforaMapyDoPliku(); + Teren.saveToFiles(null); logger.debug("Koniec zapisu danych dla regionu " + nmt_fn + " >> " + i + "/" + (args.length - 1)); Teren.reset(); } diff --git a/src/main/java/pl/wat/ms4ds/terrain/konwersja/EsriFileReader.java b/src/main/java/pl/wat/ms4ds/terrain/konwersja/EsriFileReader.java index 3c41a02..b668d2d 100644 --- a/src/main/java/pl/wat/ms4ds/terrain/konwersja/EsriFileReader.java +++ b/src/main/java/pl/wat/ms4ds/terrain/konwersja/EsriFileReader.java @@ -15,6 +15,7 @@ import pl.wat.ms4ds.terrain.MapConsts; import pl.wat.ms4ds.terrain.Teren; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; @@ -149,7 +150,7 @@ public class EsriFileReader { } } LOGGER.debug("Poczatek zapisu danych o pokryciu wodami"); - Teren.zapisBuforaMapyDoPliku(); + Teren.saveToFiles(null); // Teren.setBinarnyFormatPliku(false); // Teren.zapisBuforaMapyDoPliku(); Teren.reset(); diff --git a/src/main/java/pl/wat/ms4ds/terrain/konwersja/OpenStreetMapReader.java b/src/main/java/pl/wat/ms4ds/terrain/konwersja/OpenStreetMapReader.java index cde4a8e..487ed9c 100644 --- a/src/main/java/pl/wat/ms4ds/terrain/konwersja/OpenStreetMapReader.java +++ b/src/main/java/pl/wat/ms4ds/terrain/konwersja/OpenStreetMapReader.java @@ -66,7 +66,7 @@ public class OpenStreetMapReader { // Teren.setBinarnyFormatPliku(true); } LOGGER.debug("Poczatek zapisu danych dla regionu " + osm_fn); - Teren.zapisBuforaMapyDoPliku(); + Teren.saveToFiles(null); LOGGER.debug("Koniec zapisu danych dla regionu " + osm_fn); } diff --git a/src/main/java/pl/wat/ms4ds/terrain/nmt/NMTDataProvider.java b/src/main/java/pl/wat/ms4ds/terrain/nmt/NMTDataProvider.java index 0a7b90a..e8e233e 100644 --- a/src/main/java/pl/wat/ms4ds/terrain/nmt/NMTDataProvider.java +++ b/src/main/java/pl/wat/ms4ds/terrain/nmt/NMTDataProvider.java @@ -22,6 +22,15 @@ public class NMTDataProvider { private static final Logger LOGGER = LoggerFactory.getLogger(NMTDataProvider.class); public static void main(String[] args) throws Exception { + + String dir = "C:/Workspace/nmt/gugik_1m/unzip/"; + Set files = listFiles(dir); + for (String file : files) { + String fn = file.substring(0, file.indexOf('.')); + zipFile(dir + fn); + File f = new File(dir + file); + f.delete(); + } // File dir = new File(System.getProperty("user.home") + "/nmt/gugik_SkorowidzNMT2018.gml"); // HashMap map = new HashMap<>(); // String fn0 = "D:/nmt/gugik_SkorowidzNMT20"; @@ -44,23 +53,6 @@ public class NMTDataProvider { // downloadFileSet(links_fn, start, end, dir); -// ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); -// executor.execute(() -> { -// try { -// downloadFileSet(links_fn, 290, 730, dir); -// } catch (IOException e) { -// throw new RuntimeException(e); -// } -// }); -// executor.execute(() -> { -// try { -// downloadFileSet(links_fn, 779, 1230, dir); -// } catch (IOException e) { -// throw new RuntimeException(e); -// } -// }); -// executor.shutdown(); -// executor.awaitTermination(25, TimeUnit.MINUTES); LOGGER.info("Koniec"); } @@ -130,7 +122,7 @@ public class NMTDataProvider { FileOutputStream fos = new FileOutputStream(sourceFile + ".zip"); ZipOutputStream zipOut = new ZipOutputStream(fos); - File fileToZip = new File(sourceFile); + File fileToZip = new File(sourceFile + ".asc"); FileInputStream fis = new FileInputStream(fileToZip); ZipEntry zipEntry = new ZipEntry(fileToZip.getName()); zipOut.putNextEntry(zipEntry); diff --git a/src/main/java/pl/wat/ms4ds/terrain/nmt/NMTDataReader.java b/src/main/java/pl/wat/ms4ds/terrain/nmt/NMTDataReader.java index 00d5a1b..806cb43 100644 --- a/src/main/java/pl/wat/ms4ds/terrain/nmt/NMTDataReader.java +++ b/src/main/java/pl/wat/ms4ds/terrain/nmt/NMTDataReader.java @@ -5,9 +5,7 @@ import org.slf4j.LoggerFactory; import pl.wat.ms4ds.terrain.*; import java.io.*; -import java.nio.file.FileSystemException; -import java.util.HashMap; -import java.util.Set; +import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -16,85 +14,295 @@ public class NMTDataReader { private static final Logger logger = LoggerFactory.getLogger(NMTDataReader.class); 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"); + // Dzieli na podstringi biorąc jako znak podziału spację i jej wielokrotność + String[] splitted2 = "b a e l.d u n g".split("[ ]+"); - HashMap nmtDataHashMap = new HashMap<>(); - - String inDir = "C:/Workspace/nmt/gugik_1m/asc/m-34/"; - String outDir = "D:/work/unzipped/"; -// String testFn = "D:\\Work\\73771_1025306_NMT-M348Dc41.xyz"; -// String testFn = "D:\\Work\\M-33-7-A-c-3-2.asc"; - String testFn = "D:\\Work\\N-34-139-A-b-2-4.asc"; - - // N-34-139-A-b-2-4.asc + String fn_list = "D:/work/nmt/m-33_files.txt"; + String inDir = "D:/work/nmt/m-33/"; + String workDir = "D:/work/temp/"; + String outDir = "D:/work/kwadraty_nmt/withElevation/25m/"; + Thread t = new Thread(() -> { + generateNMTData(fn_list, 0, 24000, inDir, workDir, outDir); + }); +// HashMap nmtDataHashMap = new HashMap<>(); // try { -//// readFromFileASC(testFn, nmtDataHashMap); -// readFromFile(testFn, nmtDataHashMap); +// readFromFile(workDir + "73232_990195_NMT-M3492Ad33.xyz", nmtDataHashMap); // } catch (IOException e) { // return; // } -// renameFiles(inDir, inDir); +// generateNMTData(workDir, workDir, outDir); + t.start(); +// t2.start(); + Scanner s = new Scanner(System.in); + // exit + // + String s1; + 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."); + +// renameFiles2(inDir, inDir); + +// Set 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; + + static synchronized boolean isStopped() { + return stop; + } + + static synchronized void stop() { + stop = true; + } + + /** + * Generuje dane na podstawie rozpakowanych danych z podanego katalogu. + * + * @param inDir + * @param workDir + * @param outDir + */ + static void generateNMTData(String inDir, String workDir, String outDir) { Set files = NMTDataProvider.listFiles(inDir); - for (String file : files) { + HashMap nmtDataHashMap = new HashMap<>(); + for (String fn : files) { + String fpath = workDir + fn; try { - String unzipfn = unzipFile(inDir + file, outDir); - String fpath = outDir + unzipfn; readFromFile(fpath, nmtDataHashMap); File f = new File(fpath); f.delete(); - } catch (IOException _) { - + } catch (Exception e) { + logger.warn("Error while reading from file: {}", fpath); + try (BufferedWriter writer = new BufferedWriter(new FileWriter("D:/Work/nmt/status.txt", true))) { + writer.write("Error while processing file: " + fn); + } catch (IOException e1) { + logger.error(e1.getMessage()); + } } } - + 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); + // Konwersja na jednostkę 0.25m i zaokrąglenie do (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(); + 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 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 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 { + BufferedWriter writer = new BufferedWriter(new FileWriter(fn)); + for (String val : fileList) { + writer.write(val); + writer.newLine(); + } + writer.close(); + } + + // usuwanie z nazwy nadmiarowych rozszerz przed rozszerzeniem static void renameFiles(String inDir, String outDir) { - try { - Set fileNames = NMTDataProvider.listFiles(inDir); - for (String fn : fileNames) { - String fn1 = fn.substring(0, fn.lastIndexOf("-") + 1); - String fn2 = fn.substring(fn.lastIndexOf("-") + 1, fn.indexOf(".")); - String ext = fn.substring(fn.indexOf(".")); - int pos; - if (fn2.length() == 5) { - pos = 1; - } else if (fn2.length() == 6) { - pos = 2; - } else { - //if (fn2.length() == 7) - pos = 3; - } - String fn3 = fn2.substring(0, pos); - String fn4 = fn2.substring(pos, pos + 1); - String fn5 = fn2.substring(pos + 1, pos + 2); - String fn6 = fn2.substring(pos + 2, pos + 3); - String fn7 = fn2.substring(pos + 3, pos + 4); - String nfn = fn1 + fn3 + '-' + fn4 + '-' + fn5 + '-' + fn6 + '-' + fn7; - File fileToMove = new File(inDir + fn); - boolean isMoved = fileToMove.renameTo(new File(outDir + nfn + ext)); - if (!isMoved) { - throw new FileSystemException(outDir + fileToMove); - } - System.out.println(nfn); - + Set fileNames = NMTDataProvider.listFiles(inDir); + for (String fn : fileNames) { + String nfn = fn.substring(0, fn.indexOf('.')); + File fileToMove = new File(inDir + fn); + boolean isMoved = fileToMove.renameTo(new File(outDir + nfn + ".zip")); + if (!isMoved) { + logger.warn("Failed to rename {} to {}", inDir + fn, outDir + nfn + ".zip"); } - } catch (Exception e) { - throw new RuntimeException(e); + System.out.println(nfn); } } + // dodanie 0 do liczb dla wyrównania długości + static void renameFiles2(String inDir, String outDir) { + Set fileNames = NMTDataProvider.listFiles(inDir); + for (String fn : fileNames) { + if (fn.length() >= 20) { + continue; + } + // M-33-70-A-d-4-3.zip + // M-33-7-A-d-4-3.zip + int pos1 = fn.indexOf('-', 3); + int pos2 = fn.indexOf('-', pos1 + 1); + String f1 = fn.substring(0, pos1 + 1); + String f2 = fn.substring(pos2); + String val = fn.substring(pos1 + 1, pos2); + int v = Integer.parseInt(val); + String val_0; + if (v < 10) { + val_0 = "00" + val; + } else if (v < 100) { + val_0 = "0" + val; + } else { + val_0 = val; + } + String nfn = f1 + val_0 + f2; + File fileToMove = new File(inDir + fn); + boolean isMoved = fileToMove.renameTo(new File(outDir + nfn)); + if (!isMoved) { + logger.warn("Failed to rename {} to {}", inDir + fn, outDir + nfn); + } + System.out.println(nfn); + } + } private static void readFromFile(String fn, HashMap nmtDataHashMap) throws IOException { - long start = System.currentTimeMillis(); File file = new File(fn); InputStream inputStream = new FileInputStream(file); try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { String line = br.readLine(); - String[] split = line.split(" "); + // Dzieli na podstringi biorąc jako znak podziału spację i jej wielokrotność + // nawias kwadratowy zawiera znaki podziału + String[] split = line.split("[ ]+"); + // Identyfikacja formatu na podstawie liczby danych w pierwszej linii. if (split.length == 2) { // ASC GRID format readASC(br, line, nmtDataHashMap); @@ -104,40 +312,53 @@ public class NMTDataReader { readXYZ(br, line, nmtDataHashMap); } } - logger.debug("Time= {}[ms]", System.currentTimeMillis() - start); } + static final int H_MIN = -70; + static final int H_MAX = 2660; + private static void readASC(BufferedReader br, String firstLine, HashMap nmtDataHashMap) throws IOException { String line = firstLine; - String[] split = line.split(" "); + // Dzieli na podstringi biorąc jako znak podziału spację i jej wielokrotność + // nawias kwadratowy zawiera znaki podziału + String[] split = line.split("[ ]+"); int ncols = Integer.parseInt(split[1]); line = br.readLine(); - split = line.split(" "); + split = line.split("[ ]+"); int nrows = Integer.parseInt(split[1]); line = br.readLine(); - split = line.split(" "); + split = line.split("[ ]+"); double xll_puwg = Double.parseDouble(split[1]); line = br.readLine(); - split = line.split(" "); + split = line.split("[ ]+"); double yll_puwg = Double.parseDouble(split[1]); line = br.readLine(); - split = line.split(" "); + split = line.split("[ ]+"); double cellsize = Double.parseDouble(split[1]); line = br.readLine(); - split = line.split(" "); + split = line.split("[ ]+"); double nodata = Double.parseDouble(split[1]); double[][] data = new double[nrows][ncols]; String s; for (int i = nrows - 1; i >= 0; i--) { line = br.readLine(); - // start od 1, gdyż wiersz zaczyna się od spacji - int start = 1; + // start od 0 (brak spacji na początku) lub 1 (wiersz zaczyna się od spacji) + int start = (line.charAt(0) == ' ') ? 1 : 0; int end; for (int j = 0; j < ncols - 1; j++) { end = line.indexOf(' ', start); + while (end - start == 0 && start < line.length() - 1) { + start = end + 1; + end = line.indexOf(' ', start); + } s = line.substring(start, end); - data[i][j] = Double.parseDouble(s); start = end + 1; + data[i][j] = Double.parseDouble(s); + } + end = line.indexOf(' ', start); + while (end - start == 0 && start < line.length() - 1) { + start = end + 1; + end = line.indexOf(' ', start); } s = line.substring(start); data[i][ncols - 1] = Double.parseDouble(s); @@ -153,7 +374,8 @@ public class NMTDataReader { double x_puwg = xll_puwg; for (int j = 0; j < ncols; j++) { h = data[i][j]; - if (h <= nodata) { + if (h == nodata) { + // Przejdź do następnej kolumny danych. x_puwg += cellsize; continue; } @@ -180,12 +402,17 @@ public class NMTDataReader { nmtData.nur = (int) puwgCoord.northing; } } - if (h > nodata) { + if (H_MIN < h && h < H_MAX) { + // Filtracja danych z rozsądnego zakresu dla Polski. nmtData.sum += h; nmtData.count++; + } else { + logger.trace("!!!Dane poza zakresem: h= {}, [i,j]=[{},{}]", h, i, j); } + // Przejdź do następnej kolumny. x_puwg += cellsize; } + // Przejdź do następnego wiersza. y_puwg += cellsize; } } @@ -194,22 +421,43 @@ public class NMTDataReader { Coord.Puwg puwgCoord = new Coord.Puwg(); Coord.Geo geo = new Coord.Geo(); String line = firstLine; - String[] split; + if (line.charAt(0) == 'S' || line.charAt(0) == 'E') { + line = br.readLine(); + } + char c = ' '; + if (line.indexOf('\t', 1) != -1) { + c = '\t'; + } double x_puwg; double y_puwg; double h; int x; int y; NMTData nmtData = new NMTData(-1, -1, 0, 0); + int start; + int end; + int row = 0; while (line != null) { + if (line.length() < 5 || line.charAt(0) == 'S' || line.charAt(0) == 'E') { + line = br.readLine(); + row++; + continue; + } // start od 0, gdyż nie ma spacji na początku - int start = 0; - int end; - end = line.indexOf(' ', start); + start = 0; + end = line.indexOf(c, start); + while (end - start == 0 && start < line.length() - 1) { + start = end + 1; + end = line.indexOf(c, start); + } String s = line.substring(start, end); x_puwg = Double.parseDouble(s); start = end + 1; - end = line.indexOf(' ', start); + end = line.indexOf(c, start); + while (end - start == 0 && start < line.length() - 1) { + start = end + 1; + end = line.indexOf(c, start); + } s = line.substring(start, end); y_puwg = Double.parseDouble(s); start = end + 1; @@ -222,7 +470,7 @@ public class NMTDataReader { y = Coord.zamienSzerokoscGeoNaIdKwadratuY(geo.lat); final int x1 = x; 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(x1, y1), k -> new NMTData(x1, y1, 0, 0)); if (nmtData.nur == 0) { // Kwadrat jeszcze nie był odczytany (czysty). // Współrzędne geo środka kwadratu. @@ -238,20 +486,27 @@ public class NMTDataReader { nmtData.nur = (int) puwgCoord.northing; } } - nmtData.sum += h; - nmtData.count++; + if (H_MIN < h && h < H_MAX) { + // Filtracja danych z rozsądnego zakresu dla Polski. + nmtData.sum += h; + nmtData.count++; + } else { + logger.trace("!!!Dane poza zakresem: h= {}, row={}", h, row); + } line = br.readLine(); + row++; } } - public static String unzipFile(String zipFileName, String destDir) throws IOException { + public static String[] unzipFile(String zipFileName, String destDir) throws IOException { byte[] buffer = new byte[1024]; - String unzipFileName = ""; + String[] unzipFileNames = new String[10]; + int i = 0; try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName))) { ZipEntry zipEntry = zis.getNextEntry(); while (zipEntry != null) { - unzipFileName = zipEntry.getName(); - File newFile = new File(destDir + unzipFileName); + unzipFileNames[i] = zipEntry.getName(); + File newFile = new File(destDir + unzipFileNames[i]); // File newFile = new File(destDir + File.separator + unzipFileName); int len; // write file content @@ -261,9 +516,15 @@ public class NMTDataReader { } fos.close(); zipEntry = zis.getNextEntry(); + i++; } zis.closeEntry(); } - return unzipFileName; + if (i > 0) { + unzipFileNames = Arrays.copyOf(unzipFileNames, i); + } else { + unzipFileNames = new String[0]; + } + return unzipFileNames; } } diff --git a/teren.properties b/teren.properties index 45cb2bd..0ceb6bc 100644 --- a/teren.properties +++ b/teren.properties @@ -4,17 +4,18 @@ x_ref=14 y_ref=49 dx_ref=11 dy_ref=7 -kwadraty_dir=C:/Workspace/_data/new/ -#kwadraty_dir=C:/Workspace/_data/swdt/ms4ds/teren/kwadraty/ +#kwadraty_dir=D:/work/kwadraty_nmt/withElevation/ +#kwadraty_dir=D:/Workspace/_data/new/ +kwadraty_dir=C:/Workspace/_data/swdt/ms4ds/teren/kwadraty/ drogi_dir=au2data/new_teren/Polska/drogi/ - +# #Rozdzielczosc terenu dl_mk=200 | 100 | 50 | 25 | 20 -dl_mk=20 - +dl_mk=100 +# #W celu wymuszenia (mimo jej braku) przejezdności terenu nalezy ustawić na: on przejezdnosc_zawsze=off minimalny_stopien_przejezdnosci=0.1 - +# #Minimalny stopień przejezdności dla ruchu na przełaj dla kwadratów przejezdnych #dla algorytmów wyznaczania dróg dla działań typu: atak, obrona, rozmieszczenie, ... stopien_przejezdnosci.minimalny_na_przelaj=0.7 @@ -33,32 +34,32 @@ stopien_przejezdnosci.na_drodze.nachylenie_terenu.kat_maksymalny=50 stopien_przejezdnosci.na_przelaj.nachylenie_terenu.kat_minimalny=15 #Maksymalny kąt nachylenia terenu wpływający na stopień przejezdności (alfa_min) dla ruchu na przełaj [stopnie] stopien_przejezdnosci.na_przelaj.nachylenie_terenu.kat_maksymalny=45 - +# #stopień przejezdności - parametr dla symulacji ruchu stopien_przejezdnosci.podwozie_gasienicowe.teren_zabudowany=0.8 stopien_przejezdnosci.podwozie_gasienicowe.teren_zalesiony=0.25 stopien_przejezdnosci.podwozie_gasienicowe.teren_zabagniony=0.2 stopien_przejezdnosci.podwozie_gasienicowe.teren_zawodniony=0.0 stopien_przejezdnosci.podwozie_gasienicowe.teren_czysty=1.0 - +# stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabudowany=0.7 stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zalesiony=0.15 stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabagniony=0.1 stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zawodniony=0.0 stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_czysty=0.9 - +# stopien_przejezdnosci.podwozie_kolowe.teren_zabudowany=0.6 stopien_przejezdnosci.podwozie_kolowe.teren_zalesiony=0.1 stopien_przejezdnosci.podwozie_kolowe.teren_zabagniony=0.05 stopien_przejezdnosci.podwozie_kolowe.teren_zawodniony=0.0 stopien_przejezdnosci.podwozie_kolowe.teren_czysty=0.8 - +# stopien_przejezdnosci.podwozie_poduszka.teren_zabudowany=0.7 stopien_przejezdnosci.podwozie_poduszka.teren_zalesiony=0.1 stopien_przejezdnosci.podwozie_poduszka.teren_zabagniony=0.9 stopien_przejezdnosci.podwozie_poduszka.teren_zawodniony=1.0 stopien_przejezdnosci.podwozie_poduszka.teren_czysty=1.0 - +# stopien_przejezdnosci.podwozie_plozy.teren_zabudowany=0.1 stopien_przejezdnosci.podwozie_plozy.teren_zalesiony=0.1 stopien_przejezdnosci.podwozie_plozy.teren_zabagniony=0.1