Wersja działająca.Raczej

This commit is contained in:
2026-01-22 11:28:46 +01:00
parent 31f424e3e9
commit fdf9110c45
12 changed files with 1010 additions and 489 deletions

View File

@@ -1,5 +1,8 @@
package pl.wat.ms4ds.terrain; package pl.wat.ms4ds.terrain;
import javafx.scene.image.ImageView;
abstract class BigSquare { abstract class BigSquare {
abstract Square getKwadrat(int x, int y); abstract Square getKwadrat(int x, int y);
@@ -9,6 +12,7 @@ abstract class BigSquare {
public transient int liczbaZmian = 0; public transient int liczbaZmian = 0;
// TODO zamienic na 100 // TODO zamienic na 100
static final int LICZBA_ZMIAN_DO_ZAPISU = 100000; static final int LICZBA_ZMIAN_DO_ZAPISU = 100000;
public ImageView imageView = null;
} }

View File

@@ -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 * Funkcja wyznacza odległość między środkami kwadratów sąsiednich na zadanym kierunku
@@ -528,7 +528,7 @@ public class GeomUtils {
case SOUTH: case SOUTH:
case EAST: case EAST:
case WEST: case WEST:
return MapConsts.DL_MK; return MapConsts.SS_SIZE;
case NORTHEAST: case NORTHEAST:
case NORTHWEST: case NORTHWEST:
case SOUTHEAST: case SOUTHEAST:
@@ -860,8 +860,8 @@ public class GeomUtils {
float dyf = (float) dy; float dyf = (float) dy;
a = dyf / dxf; a = dyf / dxf;
// wspolrzedne srodka kwadratu (xp, yp) // wspolrzedne srodka kwadratu (xp, yp)
int xxp = xp * MapConsts.DL_MK + MapConsts.DL_MK / 2; int xxp = xp * MapConsts.SS_SIZE + MapConsts.SS_SIZE / 2;
int yyp = yp * MapConsts.DL_MK + MapConsts.DL_MK / 2; int yyp = yp * MapConsts.SS_SIZE + MapConsts.SS_SIZE / 2;
b = yyp - a * xxp; b = yyp - a * xxp;
if (dx > 0) { if (dx > 0) {
@@ -877,14 +877,14 @@ public class GeomUtils {
int xd, xg; int xd, xg;
int yd, yg; int yd, yg;
int y1, y2; int y1, y2;
xd = (x - 1) * MapConsts.DL_MK; xd = (x - 1) * MapConsts.SS_SIZE;
xg = x * MapConsts.DL_MK; xg = x * MapConsts.SS_SIZE;
float ydf = a * xd + b; float ydf = a * xd + b;
float ygf = a * xg + b; float ygf = a * xg + b;
yd = (int) ydf; yd = (int) ydf;
yg = (int) ygf; yg = (int) ygf;
y1 = yd / MapConsts.DL_MK + 1; y1 = yd / MapConsts.SS_SIZE + 1;
y2 = yg / MapConsts.DL_MK + 1; y2 = yg / MapConsts.SS_SIZE + 1;
temp[dl] = new Coord.Grid(); temp[dl] = new Coord.Grid();
temp[dl].x = x; temp[dl].x = x;
temp[dl].y = y1; temp[dl].y = y1;
@@ -1225,7 +1225,7 @@ public class GeomUtils {
int yy = p1.y - p2.y; int yy = p1.y - p2.y;
yy *= yy; yy *= yy;
float odl = (float) Math.sqrt(xx + yy); float odl = (float) Math.sqrt(xx + yy);
odl *= MapConsts.DL_MK; odl *= MapConsts.SS_SIZE;
return odl; return odl;
} }
@@ -1245,7 +1245,7 @@ public class GeomUtils {
int yy = y1 - y2; int yy = y1 - y2;
yy *= yy; yy *= yy;
float odl = (float) Math.sqrt(xx + yy); float odl = (float) Math.sqrt(xx + yy);
odl *= MapConsts.DL_MK; odl *= MapConsts.SS_SIZE;
return odl; return odl;
} }
@@ -1258,7 +1258,7 @@ public class GeomUtils {
*/ */
public static float odleglosc(int dx, int dy) { public static float odleglosc(int dx, int dy) {
float odl = (float) Math.sqrt(dx * dx + dy * dy); float odl = (float) Math.sqrt(dx * dx + dy * dy);
odl *= MapConsts.DL_MK; odl *= MapConsts.SS_SIZE;
return odl; return odl;
} }

View File

@@ -2,111 +2,20 @@ 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 java.io.*; 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 static final Logger logger = LoggerFactory.getLogger(RightBigSquare.class);
private Square squares[][]; private Square[][] squares;
Square getKwadrat(int ssX, int ssY) { Square getKwadrat(int ssX, int ssY) {
return squares[ssX][ssY]; return squares[ssX][ssY];
} }
/**
* Funkcja zapisująca do pliku duży kwadrat.<p>
* Zapis następuje w trybie wskazywanym przez atrybut: RightBigSquare.binary.
*
* @param wymuszony flag informujacy o trybie zapisu pliku
* @param fName nazwa pliku
* @throws IOException generowany wyjątek
*/
void updateFile(boolean wymuszony, String fName) throws IOException {
if (wymuszony) {
if (this.liczbaZmian == 0) {
// nie bylo modyfikacji od ostatniego zapisu
return;
}
this.liczbaZmian = -1;
}
this.liczbaZmian++;
this.liczbaZmian %= LICZBA_ZMIAN_DO_ZAPISU;
if (this.liczbaZmian > 0) {
return;
}
if (fName != null) {
fileName = fName;
}
StringBuilder sb = new StringBuilder(100);
sb.append(MapConsts.KWADRATY_DIR);
sb.append(fileName);
sb.append(".bin");
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString()));
for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) {
for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) {
float f = 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 = 0;
static final int NORTH_EAST = 1; static final int NORTH_EAST = 1;
static final int EAST = 2; 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 WEST_CODE = 64;
static final byte NORTH_WEST_CODE = -128; static final byte NORTH_WEST_CODE = -128;
public void save(String dir) throws IOException { public void saveToFile(String dir) throws IOException {
StringBuilder sb = new StringBuilder(100);
sb.append(dir);
// Utworzenie katalogów, gdyby nie istniały. // Utworzenie katalogów, gdyby nie istniały.
File directory = new File(dir); File directory = new File(dir);
directory.mkdirs(); directory.mkdirs();
sb.append(fileName); String path = dir + fileName + ".bin";
sb.append(".bin"); Square.RawData ss = new Square.RawData();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString())); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path));
for (int x = 0; x < squares.length; x++) {
for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) { for (int y = 0; y < squares[0].length; y++) {
for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) { ss.read(squares[x][y]);
ss.write(out);
} }
} }
out.close(); out.close();
logger.debug("Zapisano nowy plik mapy: " + sb); logger.debug("Zapisano nowy plik mapy: {}.", path);
}
/**
* Funkcja zapisująca do pliku duży kwadrat.<p>
*
* @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 * @throws IOException generowany wyjątek
*/ */
public void saveNewFileWithNewScale20m(String dir, int dlmk) throws IOException { 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 // operacja tylko dla danych terenowych o kwadratach 200m
return; return;
} }
@@ -318,7 +257,8 @@ public class RightBigSquare extends BigSquare implements Serializable {
hex = TerrainType.SWAMP.ID; hex = TerrainType.SWAMP.ID;
} }
ss[i][j].terrainType = (byte) hex; 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 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++) { 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 * @param dlmk
* @throws IOException * @throws IOException
*/ */
public void saveNewFileWithNewFormatZero(String dir, int dlmk) throws IOException { public void saveNewFileWithNewFormatWithElevetion(String dir, int dlmk) throws IOException {
if (MapConsts.DL_MK != 100) { if (MapConsts.SS_SIZE != 100) {
// operacja tylko dla danych terenowych o kwadratach 200m // operacja tylko dla danych terenowych o kwadratach 200m
return; return;
} }
@@ -376,10 +316,11 @@ public class RightBigSquare extends BigSquare implements Serializable {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString())); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString()));
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++) {
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 i = 0; i < m; i++) {
for (int j = 0; j < m; j++) { 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); logger.debug("Zapisano nowy plik mapy: {} dla rozmiaru MK= {}", sb, dlmk);
} }
void load(String FName) throws IOException { /**
try { * Generuje nowe, wyzerowane kwadraty w danej skali w nowym formacie.
fileName = FName; *
StringBuilder sb = new StringBuilder(100); * @param dir
sb.append(MapConsts.KWADRATY_DIR); * @param dlmk
sb.append(fileName); * @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"); 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]; 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 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(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; squares[x][y] = kw;
ss.load(in); }
switch (ss.terrainType) { }
case 0: in.close();
break; logger.debug("Doczytano plik mapy: " + fullPath);
case 1: } catch (IOException e) {
break; squares = null;
case 4: throw e;
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;
}
kw.wysokoscSrednia = ss.elevation; void readFromFile(String dir) throws IOException {
kw.roznicaWzniesien = 0; try {
String fullPath = dir + fileName + ".bin";
int bit_1 = 1; Square.RawData ss = new Square.RawData();
int hex = ss.majorRoads; // DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(fullPath)));
for (int i = 0; i < kw.jestDroga.length; i++) { ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(fullPath)));
// jest odcinek rowu na tym kierunku squares = new Square[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y];
if ((hex & bit_1) != 0) { for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) {
kw.jestDroga[i] = true; for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) {
} ss.read(in);
bit_1 <<= 1; 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; if (kw.elevation < -3) {
hex = ss.rivers; logger.warn("Elevation: {}, fn= {} ", kw.elevation, fileName);
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;
} }
} }
} }
in.close(); in.close();
logger.debug("Doczytano plik mapy: " + sb.toString()); logger.debug("Doczytano plik mapy: " + fullPath);
} catch (IOException e) { } catch (IOException e) {
squares = null; squares = null;
throw e; throw e;
@@ -478,7 +552,7 @@ public class RightBigSquare extends BigSquare implements Serializable {
boolean zalesienie, boolean zawodnienie, boolean zabudowa, boolean zabagnienie, boolean zalesienie, boolean zawodnienie, boolean zabudowa, boolean zabagnienie,
boolean wysokosc, boolean roznicaWzniesien, boolean drogi, boolean wysokosc, boolean roznicaWzniesien, boolean drogi,
boolean rzeki, boolean rowy) throws IOException { boolean rzeki, boolean rowy) throws IOException {
if (MapConsts.DL_MK != 200) { if (MapConsts.SS_SIZE != 200) {
// operacja tylko dla danych terenowych o kwadratach 200m // operacja tylko dla danych terenowych o kwadratach 200m
return; return;
} }
@@ -602,20 +676,28 @@ public class RightBigSquare extends BigSquare implements Serializable {
public RightBigSquare() { 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 { try {
fileName = FName + ".bin"; File f = new File(fname);
fileName = f.getName();
fileName = fileName.substring(0, fileName.lastIndexOf('.'));
StringBuilder sb = new StringBuilder(100); StringBuilder sb = new StringBuilder(100);
sb.append(MapConsts.KWADRATY_DIR); if (dir == null) {
sb.append(fileName); 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];
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 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(x0 + x, y0 + y); Square kw = new Square(x, y);
squares[x][y] = kw; squares[x][y] = kw;
int hex = in.readByte(); int hex = in.readByte();
kw.stopienZalesienia = (float) hex * (1.0f / 100.f); kw.stopienZalesienia = (float) hex * (1.0f / 100.f);
@@ -626,9 +708,18 @@ public class RightBigSquare extends BigSquare implements Serializable {
hex = in.readByte(); hex = in.readByte();
kw.stopienZabagnienia = (float) hex * (1.0f / 100.f); kw.stopienZabagnienia = (float) hex * (1.0f / 100.f);
kw.wysokoscSrednia = in.readInt(); 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(); kw.roznicaWzniesien = in.readInt();
int bit_1 = 1; int bit_1 = 1;
hex = in.readByte(); hex = in.readByte();
if (kw.jestDroga == null) {
kw.jestDroga = new boolean[8];
}
for (int i = 0; i < kw.jestDroga.length; i++) { 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) {
@@ -638,6 +729,9 @@ public class RightBigSquare extends BigSquare implements Serializable {
} }
bit_1 = 1; bit_1 = 1;
hex = in.readByte(); hex = in.readByte();
if (kw.jestPrzeszkodaWodna == null) {
kw.jestPrzeszkodaWodna = new boolean[8];
}
for (int i = 0; i < kw.jestPrzeszkodaWodna.length; i++) { for (int i = 0; i < kw.jestPrzeszkodaWodna.length; i++) {
// jest odcinek rowu na tym kierunku // jest odcinek rowu na tym kierunku
if ((hex & bit_1) != 0) { if ((hex & bit_1) != 0) {
@@ -647,6 +741,9 @@ public class RightBigSquare extends BigSquare implements Serializable {
} }
bit_1 = 1; bit_1 = 1;
hex = in.readByte(); hex = in.readByte();
if (kw.jestRow == null) {
kw.jestRow = new boolean[8];
}
for (int i = 0; i < kw.jestRow.length; i++) { 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) {

View File

@@ -1,6 +1,7 @@
package pl.wat.ms4ds.terrain; package pl.wat.ms4ds.terrain;
import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
@@ -8,9 +9,9 @@ import java.io.ObjectOutputStream;
public class Square { 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. <p></p>Possible values: * Terrain type. <p></p>Possible values:
@@ -22,21 +23,21 @@ public class Square {
* 5 - BUILDINGS * 5 - BUILDINGS
* 6 - FOREST * 6 - FOREST
*/ */
short terrainType; public short 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.
* <p></p>Possible values: 0 - no watercourse, 1 - drain, ditch, 2 - canal, stream, 3 - river * <p></p>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. * Type of road in a given direction. Each index corresponds to a given direction.
* <p></p>Possible values: 0 - no road, 1 - small roads, 2 - minor roads, 3 - major roads * <p></p>Possible values: 0 - no road, 1 - small roads, 2 - minor roads, 3 - major roads
*/ */
byte[] roads; public final byte[] roads;
//////////////////////////////////////// /// /////////////////////////////////////
/// tymczasowo /// tymczasowo
public float stopienZabudowy; public float stopienZabudowy;
public float stopienZalesienia; public float stopienZalesienia;
@@ -47,11 +48,12 @@ public class Square {
public boolean[] jestPrzeszkodaWodna; public boolean[] jestPrzeszkodaWodna;
public int roznicaWzniesien; public int roznicaWzniesien;
public int wysokoscSrednia; public int wysokoscSrednia;
////////////////////////////////////////
/// /////////////////////////////////////
public static class RawData { 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; short elevation;
/** /**
@@ -107,7 +109,7 @@ public class Square {
rivers = 0; rivers = 0;
} }
public void save(ObjectOutputStream out) throws IOException { public void write(ObjectOutputStream out) throws IOException {
out.writeShort(elevation); out.writeShort(elevation);
out.writeByte(terrainType); out.writeByte(terrainType);
out.writeByte(smallRoads); out.writeByte(smallRoads);
@@ -118,7 +120,7 @@ public class Square {
out.writeByte(rivers); out.writeByte(rivers);
} }
public void load(ObjectInputStream in) throws IOException { public void read(ObjectInputStream in) throws IOException {
elevation = in.readShort(); elevation = in.readShort();
terrainType = in.readByte(); terrainType = in.readByte();
smallRoads = in.readByte(); smallRoads = in.readByte();
@@ -140,7 +142,7 @@ public class Square {
public RawData(Square kw) { public RawData(Square kw) {
terrainType = (byte) kw.terrainType; terrainType = (byte) kw.terrainType;
// Konwersja na decymetry. // Konwersja na decymetry.
elevation = (short) (kw.elevation * 10); elevation = (short) (kw.elevation * 4);
byte bit = 1; byte bit = 1;
for (int i = 0; i < kw.watercourses.length; i++) { for (int i = 0; i < kw.watercourses.length; i++) {
switch (kw.watercourses[i]) { switch (kw.watercourses[i]) {
@@ -156,10 +158,6 @@ public class Square {
default: default:
break; break;
} }
bit <<= 1;
}
bit = 1;
for (int i = 0; i < kw.roads.length; i++) {
switch (kw.roads[i]) { switch (kw.roads[i]) {
case 1: case 1:
smallRoads |= bit; smallRoads |= bit;
@@ -176,6 +174,43 @@ public class Square {
bit <<= 1; 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); public static final Square EMPTY = new Square(-1, -1);
@@ -189,13 +224,122 @@ public class Square {
this.y = y; this.y = y;
roads = new byte[8]; roads = new byte[8];
watercourses = new byte[8]; watercourses = new byte[8];
// Brak danych o wysokości.
elevation = -1000;
} }
public Square(int x, int y, RawData rawData) { public Square(int x, int y, RawData rawData) {
this(x, y); this.x = x;
elevation = rawData.elevation / 10.f; 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; terrainType = rawData.terrainType;
int bit = 1; int bit = 1;
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
@@ -213,12 +357,6 @@ public class Square {
public final int x; public final int x;
public final int y; public final int y;
public double sumaWysokosci;
public int count = 1;
public double ell;
public double nll;
public double eur;
public double nur;
@Override @Override
@@ -250,7 +388,7 @@ public class Square {
}; };
linia.append(c); linia.append(c);
linia.append(' '); linia.append(' ');
String s = String.format("%5.1f", elevation); String s = String.format("%7.2f", elevation);
linia.append(s); linia.append(s);
linia.append(' '); linia.append(' ');
for (byte road : roads) { for (byte road : roads) {

View File

@@ -41,17 +41,16 @@ public class Teren {
private static double maxKatNachylTerenuNaPrzelaj; 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 i = 0; i < bigSquares.length; i++) {
for (int j = 0; j < bigSquares[i].length; j++) { for (int j = 0; j < bigSquares[i].length; j++) {
BigSquare bs = bigSquares[i][j]; BigSquare bs = bigSquares[i][j];
if (null != bs && bs instanceof RightBigSquare) { if (bs instanceof RightBigSquare rbs) {
RightBigSquare rbs = (RightBigSquare) bigSquares[i][j];
try { try {
rbs.liczbaZmian++; rbs.writeToFile(dir);
rbs.updateFile(true, null); 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);
} }
@@ -73,107 +72,6 @@ public class Teren {
System.gc(); 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. * 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). * @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.zamienDlugoscGeoNaIdKwadratuX(lon);
int idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(lat); int idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(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) {
if ((bsX < 0) || (bsY < 0)) {
return null;
}
int x_stop = MapConsts.X_REF + bsX / MapConsts.BS_PER_DEG_X - 180; int x_stop = MapConsts.X_REF + 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) {
@@ -200,7 +95,6 @@ public class Teren {
} }
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.Y_REF + 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) {
@@ -209,14 +103,12 @@ public class Teren {
int dy = bsY % MapConsts.BS_PER_DEG_Y; int dy = bsY % MapConsts.BS_PER_DEG_Y;
char cy = LITERALS.charAt(dy); char cy = LITERALS.charAt(dy);
// przykładowa nazwa pliku: E024B_N50F // przykładowa nazwa pliku: E024B_N50F
//
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
// sb.append(MapConsts.KWADRATY_DIR);
sb.append(cLon); sb.append(cLon);
if (x_stop < 100) {
sb.append('0');
}
if (x_stop < 10) { if (x_stop < 10) {
sb.append("00");
} else if (x_stop < 100) {
sb.append('0'); sb.append('0');
} }
sb.append(x_stop); sb.append(x_stop);
@@ -231,21 +123,22 @@ public class Teren {
return sb.toString(); return sb.toString();
} }
private static BigSquare loadArea(int bsX, int bsY) { private static BigSquare loadAreaOld(int bsX, int bsY) {
String fName = getFileName(bsX, bsY); String fName = getFileName(bsX, bsY) + ".bin";
try { try {
return new RightBigSquare(fName); return new RightBigSquare(fName, null);
} catch (IOException e) { } catch (IOException e) {
LOGGER.warn("Brak pliku mapy: {}{}{}", MapConsts.KWADRATY_DIR, fName, ".bin"); LOGGER.warn("Brak pliku mapy: {}{}{}", MapConsts.KWADRATY_DIR, fName, ".bin");
return EmptyBigSquare.EMPTY_BIG_SQUARE; 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); String fName = getFileName(bsX, bsY);
try { try {
RightBigSquare bs = new RightBigSquare(); RightBigSquare bs = new RightBigSquare();
bs.load(fName); bs.fileName = fName;
bs.readFromFile(MapConsts.KWADRATY_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.KWADRATY_DIR, fName, ".bin");
@@ -262,48 +155,53 @@ public class Teren {
} }
public static Square getKwadrat(double lat, double lon) { public static Square getKwadrat(double lat, double lon) {
int idX = Coord.zamienDlugoscGeoNaIdKwadratuX(lon); int idX = Coord.zamienDlugoscGeoNaIdKwadratuX(lon);
int idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(lat); int idY = Coord.zamienSzerokoscGeoNaIdKwadratuY(lat);
return getKwadrat(idX, idY); 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; return EMPTY;
} }
// wspolrzędna x dużego kwadratu // 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 // 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) { if (bsX < 0 || bsX >= BIG_X_MAX || bsY < 0 || 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
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 // 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) { synchronized (bsSynch) {
if (bigSquares[bsX][bsY] == null) { if (bigSquares[bsX][bsY] == null) {
makeRoom(bsX, bsY); makeRoom(bsX, bsY);
bigSquares[bsX][bsY] = loadArea(bsX, bsY); bigSquares[bsX][bsY] = loadArea(bsX, bsY);
// bigSquares[bsX][bsY] = loadAreaNew(bsX, bsY);
} }
} }
return bigSquares[bsX][bsY].getKwadrat(ssX, ssY); 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 int bigSquaresInMemory = 0;
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 (bigSquaresInMemory >= MapConsts.MAX_BIG_SQUARES_IN_MEMORY) {
// najpierw zapisuję w pliku dokonane zmiany // najpierw zapisuję w pliku dokonane zmiany
if (bigSquares[history[0].x][history[0].y] instanceof RightBigSquare) { if (bigSquares[history[0].x][history[0].y] instanceof RightBigSquare rbs) {
RightBigSquare rbs = (RightBigSquare) bigSquares[history[0].x][history[0].y];
try { try {
//!! dla potrzeb generowania danych //!! dla potrzeb generowania danych
rbs.liczbaZmian = 1; rbs.liczbaZmian = 1;
rbs.updateFile(true, null); rbs.writeToFile(null);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -332,8 +230,8 @@ public class Teren {
private static final double TANG_ALFA_MAX_NA_DRODZE; private static final double TANG_ALFA_MAX_NA_DRODZE;
private static final double TANG_ALFA_MIN_NA_DRODZE; private static final double TANG_ALFA_MIN_NA_DRODZE;
private static double a1; private static final double a1;
private static double b1; private static final double b1;
/** /**
* Funkcja opisujaca zmianę stopnia przejezdności podczas ruchu na drodze dla kątów w przedziale <22.5, 45> * 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_MAX_NA_PRZELAJ;
private static final double TANG_ALFA_MIN_NA_PRZELAJ; private static final double TANG_ALFA_MIN_NA_PRZELAJ;
private static double a2; private static final double a2;
private static double b2; 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> * 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 { static {
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.ustawienia.getProperty("przejezdnosc_zawsze").equals("on");
minStopienPrzejezd = Double.parseDouble(MapConsts.ustawienia.getProperty("minimalny_stopien_przejezdnosci")); minStopienPrzejezd = Double.parseDouble(MapConsts.ustawienia.getProperty("minimalny_stopien_przejezdnosci"));
@@ -496,19 +394,40 @@ public class Teren {
LOGGER.debug("start"); LOGGER.debug("start");
// Teren.normalizujDanePokrycia(); // Teren.normalizujDanePokrycia();
String dir = "C:/users/jrulka/Workspace/_data/new/"; String newDir = "D:/work/kwadraty_nmt/temp/25/";
Square kw = getKwadrat(1500, 2100); 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); // 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";
// RightBigSquare rbs = new RightBigSquare(dir2 + fn + ".bin", null);
// rbs.writeToFileOldToNewFormatWithElevetion(dir1, 25);
Set<String> fileNames = NMTDataProvider.listFiles(MapConsts.KWADRATY_DIR); RightBigSquare rbs = new RightBigSquare();
Teren.wygenerujNoweDane(fileNames, dir, 100); rbs.fileName = "E017B_N54E";
// Teren.wygenerujCzysteDane(100, false, false, false, false, true, false, false, false, false); 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.wygenerujCzysteDane(dir, 25, false, false, false, false, true, false, false, false, false);
// Teren.wyzerujDane(); // Teren.wyzerujDane();
// Teren.zapisBuforaMapyDoPliku(); // Teren.zapisBuforaMapyDoPliku();
// String dir1 = "D:/work/kwadraty_nmt/withElevation/25m/";
// Set<String> 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ń // wyzerowanie wszystkiego poza wysokością i różnicą wzniesień
rbs.resetSquares(true, true, true, true, true, true, true, true, true); rbs.resetSquares(true, true, true, true, true, true, true, true, true);
rbs.liczbaZmian = 1; rbs.liczbaZmian = 1;
rbs.updateFile(true, null); rbs.writeToFile(null);
} }
} catch (IOException e) { } catch (IOException e) {
// e.printStackTrace(); // e.printStackTrace();
@@ -578,10 +497,9 @@ public class Teren {
for (int y = 0; y < bigSquares[x].length; y++) { for (int y = 0; y < bigSquares[x].length; y++) {
try { try {
BigSquare bs = bigSquares[x][y]; BigSquare bs = bigSquares[x][y];
if (bs != null && bs instanceof RightBigSquare) { if (bs instanceof RightBigSquare rbs) {
RightBigSquare rbs = (RightBigSquare) bs;
rbs.liczbaZmian = 1; rbs.liczbaZmian = 1;
rbs.updateFile(true, null); rbs.writeToFile(null);
} }
} catch (IOException e) { } catch (IOException e) {
// e.printStackTrace(); // e.printStackTrace();
@@ -615,10 +533,9 @@ public class Teren {
for (int y = 0; y < bigSquares[x].length; y++) { for (int y = 0; y < bigSquares[x].length; y++) {
try { try {
BigSquare bs = bigSquares[x][y]; BigSquare bs = bigSquares[x][y];
if (bs != null && bs instanceof RightBigSquare) { if (bs instanceof RightBigSquare rbs) {
RightBigSquare rbs = (RightBigSquare) bs;
rbs.liczbaZmian = 1; rbs.liczbaZmian = 1;
rbs.updateFile(true, null); rbs.writeToFile(null);
} }
} catch (IOException e) { } catch (IOException e) {
// e.printStackTrace(); // e.printStackTrace();
@@ -628,14 +545,32 @@ public class Teren {
} }
/** /**
* @param dir katalog z danymi terenowymi np. "d:/Workspace2/kwadraty/czyste-wysokosc/" * Generuje pliki z danymi w nowym formacie na podstawie danych w satrym formacie.
* @param dlmk docelowy rozmiar generowanych kwadratów terenu *
* @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<String> fileNames, String dir, int dlmk) throws IOException { public static void generateDataOldToNewFormat(Set<String> fileNames, String inDir, String outDir, int dlmk) throws IOException {
// WYGENEROWANIE CZYSTYCH PLIKÓW DANYCH Z ZACHOWANIEM TYLKO WYSOKOSCI I ROZNICY POZIOMOW WZNIESIEN
for (String fileName : fileNames) { for (String fileName : fileNames) {
RightBigSquare rbs = new RightBigSquare(fileName); RightBigSquare rbs = new RightBigSquare(fileName, null);
rbs.saveNewFileWithNewFormatZero(dir, dlmk); 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<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.readFromFileNew(inDir);
// rbs.writeToFile(outDir);
} }
} }

View File

@@ -3,13 +3,105 @@ package pl.wat.ms4ds.terrain.konwersja;
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);
static void main() { 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(" "); logger.debug(" ");

View File

@@ -39,7 +39,7 @@ public class CoordUtils {
// kw.setWysokoscSrednia((int) (daneWysok.suma / daneWysok.licz + 0.5)); // kw.setWysokoscSrednia((int) (daneWysok.suma / daneWysok.licz + 0.5));
} }
logger.debug("Poczatek zapisu danych dla regionu " + nmt_fn + " >> " + i + "/" + (args.length - 1)); 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)); logger.debug("Koniec zapisu danych dla regionu " + nmt_fn + " >> " + i + "/" + (args.length - 1));
Teren.reset(); Teren.reset();
} }

View File

@@ -15,6 +15,7 @@ import pl.wat.ms4ds.terrain.MapConsts;
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 java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@@ -149,7 +150,7 @@ public class EsriFileReader {
} }
} }
LOGGER.debug("Poczatek zapisu danych o pokryciu wodami"); LOGGER.debug("Poczatek zapisu danych o pokryciu wodami");
Teren.zapisBuforaMapyDoPliku(); Teren.saveToFiles(null);
// Teren.setBinarnyFormatPliku(false); // Teren.setBinarnyFormatPliku(false);
// Teren.zapisBuforaMapyDoPliku(); // Teren.zapisBuforaMapyDoPliku();
Teren.reset(); Teren.reset();

View File

@@ -66,7 +66,7 @@ public class OpenStreetMapReader {
// Teren.setBinarnyFormatPliku(true); // Teren.setBinarnyFormatPliku(true);
} }
LOGGER.debug("Poczatek zapisu danych dla regionu " + osm_fn); LOGGER.debug("Poczatek zapisu danych dla regionu " + osm_fn);
Teren.zapisBuforaMapyDoPliku(); Teren.saveToFiles(null);
LOGGER.debug("Koniec zapisu danych dla regionu " + osm_fn); LOGGER.debug("Koniec zapisu danych dla regionu " + osm_fn);
} }

View File

@@ -22,6 +22,15 @@ public class NMTDataProvider {
private static final Logger LOGGER = LoggerFactory.getLogger(NMTDataProvider.class); 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 {
String dir = "C:/Workspace/nmt/gugik_1m/unzip/";
Set<String> 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"); // File dir = new File(System.getProperty("user.home") + "/nmt/gugik_SkorowidzNMT2018.gml");
// HashMap<String, String> map = new HashMap<>(); // HashMap<String, String> map = new HashMap<>();
// String fn0 = "D:/nmt/gugik_SkorowidzNMT20"; // String fn0 = "D:/nmt/gugik_SkorowidzNMT20";
@@ -44,23 +53,6 @@ public class NMTDataProvider {
// downloadFileSet(links_fn, start, end, dir); // 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"); LOGGER.info("Koniec");
} }
@@ -130,7 +122,7 @@ public class NMTDataProvider {
FileOutputStream fos = new FileOutputStream(sourceFile + ".zip"); FileOutputStream fos = new FileOutputStream(sourceFile + ".zip");
ZipOutputStream zipOut = new ZipOutputStream(fos); ZipOutputStream zipOut = new ZipOutputStream(fos);
File fileToZip = new File(sourceFile); File fileToZip = new File(sourceFile + ".asc");
FileInputStream fis = new FileInputStream(fileToZip); FileInputStream fis = new FileInputStream(fileToZip);
ZipEntry zipEntry = new ZipEntry(fileToZip.getName()); ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
zipOut.putNextEntry(zipEntry); zipOut.putNextEntry(zipEntry);

View File

@@ -5,9 +5,7 @@ import org.slf4j.LoggerFactory;
import pl.wat.ms4ds.terrain.*; import pl.wat.ms4ds.terrain.*;
import java.io.*; import java.io.*;
import java.nio.file.FileSystemException; import java.util.*;
import java.util.HashMap;
import java.util.Set;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
@@ -16,85 +14,295 @@ public class NMTDataReader {
private static final Logger logger = LoggerFactory.getLogger(NMTDataReader.class); private static final Logger logger = LoggerFactory.getLogger(NMTDataReader.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"); // 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<Coord.Grid, NMTData> nmtDataHashMap = new HashMap<>(); String fn_list = "D:/work/nmt/m-33_files.txt";
String inDir = "D:/work/nmt/m-33/";
String inDir = "C:/Workspace/nmt/gugik_1m/asc/m-34/"; String workDir = "D:/work/temp/";
String outDir = "D:/work/unzipped/"; String outDir = "D:/work/kwadraty_nmt/withElevation/25m/";
// 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
Thread t = new Thread(() -> {
generateNMTData(fn_list, 0, 24000, inDir, workDir, outDir);
});
// HashMap<Coord.Grid, NMTData> nmtDataHashMap = new HashMap<>();
// try { // try {
//// readFromFileASC(testFn, nmtDataHashMap); // readFromFile(workDir + "73232_990195_NMT-M3492Ad33.xyz", nmtDataHashMap);
// readFromFile(testFn, nmtDataHashMap);
// } catch (IOException e) { // } catch (IOException e) {
// return; // 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<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;
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<String> files = NMTDataProvider.listFiles(inDir); Set<String> files = NMTDataProvider.listFiles(inDir);
for (String file : files) { HashMap<Coord.Grid, NMTData> nmtDataHashMap = new HashMap<>();
for (String fn : files) {
String fpath = workDir + fn;
try { try {
String unzipfn = unzipFile(inDir + file, outDir);
String fpath = outDir + unzipfn;
readFromFile(fpath, nmtDataHashMap); readFromFile(fpath, nmtDataHashMap);
File f = new File(fpath); File f = new File(fpath);
f.delete(); 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<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 {
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) { static void renameFiles(String inDir, String outDir) {
try { 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 fn1 = fn.substring(0, fn.lastIndexOf("-") + 1); File fileToMove = new File(inDir + fn);
String fn2 = fn.substring(fn.lastIndexOf("-") + 1, fn.indexOf(".")); boolean isMoved = fileToMove.renameTo(new File(outDir + nfn + ".zip"));
String ext = fn.substring(fn.indexOf(".")); if (!isMoved) {
int pos; logger.warn("Failed to rename {} to {}", inDir + fn, outDir + nfn + ".zip");
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);
} }
} catch (Exception e) { System.out.println(nfn);
throw new RuntimeException(e);
} }
} }
// dodanie 0 do liczb dla wyrównania długości
static void renameFiles2(String inDir, String outDir) {
Set<String> 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<Coord.Grid, NMTData> nmtDataHashMap) throws IOException { private static void readFromFile(String fn, HashMap<Coord.Grid, NMTData> nmtDataHashMap) throws IOException {
long start = System.currentTimeMillis();
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))) {
String line = br.readLine(); 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) { if (split.length == 2) {
// ASC GRID format // ASC GRID format
readASC(br, line, nmtDataHashMap); readASC(br, line, nmtDataHashMap);
@@ -104,40 +312,53 @@ public class NMTDataReader {
readXYZ(br, line, nmtDataHashMap); 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<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;
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]); int ncols = Integer.parseInt(split[1]);
line = br.readLine(); line = br.readLine();
split = line.split(" "); split = line.split("[ ]+");
int nrows = Integer.parseInt(split[1]); int nrows = Integer.parseInt(split[1]);
line = br.readLine(); line = br.readLine();
split = line.split(" "); split = line.split("[ ]+");
double xll_puwg = Double.parseDouble(split[1]); double xll_puwg = Double.parseDouble(split[1]);
line = br.readLine(); line = br.readLine();
split = line.split(" "); split = line.split("[ ]+");
double yll_puwg = Double.parseDouble(split[1]); double yll_puwg = Double.parseDouble(split[1]);
line = br.readLine(); line = br.readLine();
split = line.split(" "); split = line.split("[ ]+");
double cellsize = Double.parseDouble(split[1]); double cellsize = Double.parseDouble(split[1]);
line = br.readLine(); line = br.readLine();
split = line.split(" "); split = line.split("[ ]+");
double nodata = Double.parseDouble(split[1]); double nodata = Double.parseDouble(split[1]);
double[][] data = new double[nrows][ncols]; double[][] data = new double[nrows][ncols];
String s; String s;
for (int i = nrows - 1; i >= 0; i--) { for (int i = nrows - 1; i >= 0; i--) {
line = br.readLine(); line = br.readLine();
// start od 1, gdyż wiersz zaczyna się od spacji // start od 0 (brak spacji na początku) lub 1 (wiersz zaczyna się od spacji)
int start = 1; int start = (line.charAt(0) == ' ') ? 1 : 0;
int end; int end;
for (int j = 0; j < ncols - 1; j++) { for (int j = 0; j < ncols - 1; j++) {
end = line.indexOf(' ', start); end = line.indexOf(' ', start);
while (end - start == 0 && start < line.length() - 1) {
start = end + 1;
end = line.indexOf(' ', start);
}
s = line.substring(start, end); s = line.substring(start, end);
data[i][j] = Double.parseDouble(s);
start = end + 1; 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); s = line.substring(start);
data[i][ncols - 1] = Double.parseDouble(s); data[i][ncols - 1] = Double.parseDouble(s);
@@ -153,7 +374,8 @@ public class NMTDataReader {
double x_puwg = xll_puwg; double x_puwg = xll_puwg;
for (int j = 0; j < ncols; j++) { for (int j = 0; j < ncols; j++) {
h = data[i][j]; h = data[i][j];
if (h <= nodata) { if (h == nodata) {
// Przejdź do następnej kolumny danych.
x_puwg += cellsize; x_puwg += cellsize;
continue; continue;
} }
@@ -180,12 +402,17 @@ public class NMTDataReader {
nmtData.nur = (int) puwgCoord.northing; 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.sum += h;
nmtData.count++; nmtData.count++;
} else {
logger.trace("!!!Dane poza zakresem: h= {}, [i,j]=[{},{}]", h, i, j);
} }
// Przejdź do następnej kolumny.
x_puwg += cellsize; x_puwg += cellsize;
} }
// Przejdź do następnego wiersza.
y_puwg += cellsize; y_puwg += cellsize;
} }
} }
@@ -194,22 +421,43 @@ public class NMTDataReader {
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;
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 x_puwg;
double y_puwg; double y_puwg;
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 end;
int row = 0;
while (line != null) { 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 // start od 0, gdyż nie ma spacji na początku
int start = 0; start = 0;
int end; end = line.indexOf(c, start);
end = line.indexOf(' ', start); while (end - start == 0 && start < line.length() - 1) {
start = end + 1;
end = line.indexOf(c, start);
}
String s = line.substring(start, end); String s = line.substring(start, end);
x_puwg = Double.parseDouble(s); x_puwg = Double.parseDouble(s);
start = end + 1; 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); s = line.substring(start, end);
y_puwg = Double.parseDouble(s); y_puwg = Double.parseDouble(s);
start = end + 1; start = end + 1;
@@ -222,7 +470,7 @@ public class NMTDataReader {
y = Coord.zamienSzerokoscGeoNaIdKwadratuY(geo.lat); y = Coord.zamienSzerokoscGeoNaIdKwadratuY(geo.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(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.
@@ -238,20 +486,27 @@ public class NMTDataReader {
nmtData.nur = (int) puwgCoord.northing; nmtData.nur = (int) puwgCoord.northing;
} }
} }
nmtData.sum += h; if (H_MIN < h && h < H_MAX) {
nmtData.count++; // 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(); 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]; byte[] buffer = new byte[1024];
String unzipFileName = ""; String[] unzipFileNames = new String[10];
int i = 0;
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName))) { try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName))) {
ZipEntry zipEntry = zis.getNextEntry(); ZipEntry zipEntry = zis.getNextEntry();
while (zipEntry != null) { while (zipEntry != null) {
unzipFileName = zipEntry.getName(); unzipFileNames[i] = zipEntry.getName();
File newFile = new File(destDir + unzipFileName); File newFile = new File(destDir + unzipFileNames[i]);
// File newFile = new File(destDir + File.separator + unzipFileName); // File newFile = new File(destDir + File.separator + unzipFileName);
int len; int len;
// write file content // write file content
@@ -261,9 +516,15 @@ public class NMTDataReader {
} }
fos.close(); fos.close();
zipEntry = zis.getNextEntry(); zipEntry = zis.getNextEntry();
i++;
} }
zis.closeEntry(); zis.closeEntry();
} }
return unzipFileName; if (i > 0) {
unzipFileNames = Arrays.copyOf(unzipFileNames, i);
} else {
unzipFileNames = new String[0];
}
return unzipFileNames;
} }
} }

View File

@@ -4,17 +4,18 @@ x_ref=14
y_ref=49 y_ref=49
dx_ref=11 dx_ref=11
dy_ref=7 dy_ref=7
kwadraty_dir=C:/Workspace/_data/new/ #kwadraty_dir=D:/work/kwadraty_nmt/withElevation/
#kwadraty_dir=C:/Workspace/_data/swdt/ms4ds/teren/kwadraty/ #kwadraty_dir=D:/Workspace/_data/new/
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
dl_mk=20 dl_mk=100
#
#W celu wymuszenia (mimo jej braku) przejezdności terenu nalezy ustawić na: on #W celu wymuszenia (mimo jej braku) przejezdności terenu nalezy ustawić na: on
przejezdnosc_zawsze=off przejezdnosc_zawsze=off
minimalny_stopien_przejezdnosci=0.1 minimalny_stopien_przejezdnosci=0.1
#
#Minimalny stopień przejezdności dla ruchu na przełaj dla kwadratów przejezdnych #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, ... #dla algorytmów wyznaczania dróg dla działań typu: atak, obrona, rozmieszczenie, ...
stopien_przejezdnosci.minimalny_na_przelaj=0.7 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 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] #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 stopien_przejezdnosci.na_przelaj.nachylenie_terenu.kat_maksymalny=45
#
#stopień przejezdności - parametr dla symulacji ruchu #stopień przejezdności - parametr dla symulacji ruchu
stopien_przejezdnosci.podwozie_gasienicowe.teren_zabudowany=0.8 stopien_przejezdnosci.podwozie_gasienicowe.teren_zabudowany=0.8
stopien_przejezdnosci.podwozie_gasienicowe.teren_zalesiony=0.25 stopien_przejezdnosci.podwozie_gasienicowe.teren_zalesiony=0.25
stopien_przejezdnosci.podwozie_gasienicowe.teren_zabagniony=0.2 stopien_przejezdnosci.podwozie_gasienicowe.teren_zabagniony=0.2
stopien_przejezdnosci.podwozie_gasienicowe.teren_zawodniony=0.0 stopien_przejezdnosci.podwozie_gasienicowe.teren_zawodniony=0.0
stopien_przejezdnosci.podwozie_gasienicowe.teren_czysty=1.0 stopien_przejezdnosci.podwozie_gasienicowe.teren_czysty=1.0
#
stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabudowany=0.7 stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabudowany=0.7
stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zalesiony=0.15 stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zalesiony=0.15
stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabagniony=0.1 stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zabagniony=0.1
stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zawodniony=0.0 stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_zawodniony=0.0
stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_czysty=0.9 stopien_przejezdnosci.podwozie_kolowo_gasienicowe.teren_czysty=0.9
#
stopien_przejezdnosci.podwozie_kolowe.teren_zabudowany=0.6 stopien_przejezdnosci.podwozie_kolowe.teren_zabudowany=0.6
stopien_przejezdnosci.podwozie_kolowe.teren_zalesiony=0.1 stopien_przejezdnosci.podwozie_kolowe.teren_zalesiony=0.1
stopien_przejezdnosci.podwozie_kolowe.teren_zabagniony=0.05 stopien_przejezdnosci.podwozie_kolowe.teren_zabagniony=0.05
stopien_przejezdnosci.podwozie_kolowe.teren_zawodniony=0.0 stopien_przejezdnosci.podwozie_kolowe.teren_zawodniony=0.0
stopien_przejezdnosci.podwozie_kolowe.teren_czysty=0.8 stopien_przejezdnosci.podwozie_kolowe.teren_czysty=0.8
#
stopien_przejezdnosci.podwozie_poduszka.teren_zabudowany=0.7 stopien_przejezdnosci.podwozie_poduszka.teren_zabudowany=0.7
stopien_przejezdnosci.podwozie_poduszka.teren_zalesiony=0.1 stopien_przejezdnosci.podwozie_poduszka.teren_zalesiony=0.1
stopien_przejezdnosci.podwozie_poduszka.teren_zabagniony=0.9 stopien_przejezdnosci.podwozie_poduszka.teren_zabagniony=0.9
stopien_przejezdnosci.podwozie_poduszka.teren_zawodniony=1.0 stopien_przejezdnosci.podwozie_poduszka.teren_zawodniony=1.0
stopien_przejezdnosci.podwozie_poduszka.teren_czysty=1.0 stopien_przejezdnosci.podwozie_poduszka.teren_czysty=1.0
#
stopien_przejezdnosci.podwozie_plozy.teren_zabudowany=0.1 stopien_przejezdnosci.podwozie_plozy.teren_zabudowany=0.1
stopien_przejezdnosci.podwozie_plozy.teren_zalesiony=0.1 stopien_przejezdnosci.podwozie_plozy.teren_zalesiony=0.1
stopien_przejezdnosci.podwozie_plozy.teren_zabagniony=0.1 stopien_przejezdnosci.podwozie_plozy.teren_zabagniony=0.1