Files
terrain-utilities/src/main/java/pl/wat/ms4ds/terrain/Square.java

259 lines
7.6 KiB
Java

package pl.wat.ms4ds.terrain;
import pl.wat.ms4ds.terrain.nmt.NMTDataReader;
public class Square {
/**
* The height above the level of the sea. Unit of measure meter [m].
*/
public float elevation;
/**
* Terrain type. <p></p>Possible values:
* 0 - BARE_GROUND
* 1 - GRASS
* 2 - SWAMP
* 3 - WATER
* 4 - SCRUB, BUSHES
* 5 - BUILDINGS
* 6 - FOREST
*/
public short terrainType;
/**
* 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
*/
public final byte[] watercourses;
/**
* 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
*/
public final byte[] roads;
/// /////////////////////////////////////
/// tymczasowo
public float stopienZabudowy;
public float stopienZalesienia;
public float stopienZawodnienia;
public float stopienZabagnienia;
public boolean[] jestDroga;
public boolean[] jestRow;
public boolean[] jestPrzeszkodaWodna;
public int roznicaWzniesien;
public int wysokoscSrednia;
public static final Square EMPTY = new Square(-1, -1);
public Square() {
this(-2, -2);
}
public Square(int x, int y) {
this.x = x;
this.y = y;
roads = new byte[8];
watercourses = new byte[8];
}
public Square(int x, int y, short elevation, byte terrainType, byte majorRoads, byte minorRoads, byte smallRoads, byte rivers, byte streams, byte drains) {
this.x = x;
this.y = y;
roads = new byte[8];
watercourses = new byte[8];
// Konwersja na metry a[0.25m] -> b[m]
this.elevation = (float) (elevation) / 4;
this.terrainType = terrainType;
int bit = 1;
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;
}
}
public int writeToBufferElevationOnly(byte[] buffer, int offset) {
// Konwersja [m] -> [0.25m].
int elev = (short) (elevation * 4);
byte b1 = (byte) (elev & 0xFF);
elev >>= 8;
byte b0 = (byte) (elev & 0xFF);
if (b0 == -1 && b1 == -4) {
System.out.println("a");
}
buffer[offset] = b0;
buffer[offset + 1] = b1;
buffer[offset + 2] = 0;
buffer[offset + 3] = 0;
buffer[offset + 4] = 0;
buffer[offset + 5] = 0;
buffer[offset + 6] = 0;
buffer[offset + 7] = 0;
buffer[offset + 8] = 0;
return offset + 9;
}
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);
elev = (elev << 8) | (buffer[offset + 1] & 0xFF);
// Rzutowanie "elev" na short zachowuje znak liczby.
short v = (short) elev;
elevation = (float) (v) / 4;
// Konwersja na metry a[0.25m] -> b[m]
// elevation = (float) ((short) elev) / 4;
if (elevation > NMTDataReader.H_MAX) {
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;
}
public final int x;
public final int y;
@Override
public final boolean equals(Object o) {
if (!(o instanceof Square SQUARE)) return false;
return x == SQUARE.x && y == SQUARE.y;
}
@Override
public int hashCode() {
int result = 7;
result = 31 * result + x;
result = 31 * result + y;
return result;
}
@Override
public String toString() {
StringBuilder linia = new StringBuilder(100);
linia.append("[");
char c = switch (terrainType) {
case 1 -> 'G';
case 2 -> 'S';
case 3 -> 'W';
case 4 -> 'R';
case 5 -> 'B';
case 6 -> 'F';
default -> ' ';
};
linia.append(c);
linia.append(' ');
String s = String.format("%7.2f", elevation);
linia.append(s);
linia.append(' ');
for (byte road : roads) {
c = switch (road) {
case 1 -> '1';
case 2 -> '2';
case 3 -> '3';
default -> '0';
};
linia.append(c);
}
linia.append(' ');
for (byte watercours : watercourses) {
c = switch (watercours) {
case 1 -> '1';
case 2 -> '2';
case 3 -> '3';
default -> '0';
};
linia.append(c);
}
linia.append(']');
return linia.toString();
}
}