From 119658de07e0186382cccca88157a2a60236eb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Rulka?= Date: Wed, 14 Jan 2026 12:32:53 +0100 Subject: [PATCH] =?UTF-8?q?Wst=C4=99pnie=20dzia=C5=82a=20odczyt=20z=20plik?= =?UTF-8?q?=C3=B3w:=20asc=20i=20xyz.=20Ma=C5=82y=20kwadrat=20nazywa=20si?= =?UTF-8?q?=C4=99=20Square.=20Square.RawData=20klasa=20na=20potrzeby=20zap?= =?UTF-8?q?isu=20i=20odczytu=20danych=20terenowych.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/modules.xml | 8 - .../java/pl/wat/ms4ds/terenfunkcje/AStar.java | 10 +- .../pl/wat/ms4ds/terenfunkcje/BigSquare.java | 8 +- .../ms4ds/terenfunkcje/CoordConversion.java | 158 +++++ .../ms4ds/terenfunkcje/EmptyBigSquare.java | 4 +- .../pl/wat/ms4ds/terenfunkcje/GeoCoord.java | 10 + .../pl/wat/ms4ds/terenfunkcje/GridCoord.java | 6 +- .../pl/wat/ms4ds/terenfunkcje/Kwadrat.java | 358 ----------- .../pl/wat/ms4ds/terenfunkcje/MapConsts.java | 357 +++++----- .../ms4ds/terenfunkcje/RightBigSquare.java | 176 +++-- .../wat/ms4ds/terenfunkcje/SiecDrogowa.java | 607 +++++++++--------- .../wat/ms4ds/terenfunkcje/SmallSquare.java | 83 --- .../pl/wat/ms4ds/terenfunkcje/Square.java | 282 ++++++++ .../java/pl/wat/ms4ds/terenfunkcje/Teren.java | 594 ++--------------- .../wat/ms4ds/terenfunkcje/TerrainUtils.java | 108 +--- .../terenfunkcje/konwersja/CoordTest.java | 76 +++ .../terenfunkcje/konwersja/CoordUtils.java | 481 +++++--------- .../{DaneWysok.java => NMTData.java} | 4 +- .../ms4ds/terenfunkcje/konwersja/Node.java | 10 +- .../terenfunkcje/konwersja/PUWGCoord.java | 11 +- .../wat/ms4ds/terenfunkcje/konwersja/Way.java | 102 +-- .../terenfunkcje/nmt/NMTDataProvider.java | 9 +- .../wat/ms4ds/terenfunkcje/nmt/NMTReader.java | 287 ++++++++- .../terenfunkcje/osm/shapefile/Main.java | 3 +- .../osm/shapefile/OsmShapeFileReader.java | 56 +- 25 files changed, 1765 insertions(+), 2043 deletions(-) delete mode 100644 .idea/modules.xml create mode 100644 src/main/java/pl/wat/ms4ds/terenfunkcje/CoordConversion.java delete mode 100644 src/main/java/pl/wat/ms4ds/terenfunkcje/Kwadrat.java delete mode 100644 src/main/java/pl/wat/ms4ds/terenfunkcje/SmallSquare.java create mode 100644 src/main/java/pl/wat/ms4ds/terenfunkcje/Square.java create mode 100644 src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/CoordTest.java rename src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/{DaneWysok.java => NMTData.java} (73%) diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index aa10024..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/AStar.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/AStar.java index a23dd52..32a4c9c 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/AStar.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/AStar.java @@ -222,8 +222,9 @@ public final class AStar { } sasiedzi = aktualny.dajNiezamknietychSasiadow(); for (Node sasiad : sasiedzi) { - double stopienPrzejezdnosci = Teren.getStopienPrzejezdnosci(aktualny.x, aktualny.y, sasiad.x, sasiad.y, - aktualny.zKierunku, podwozie); +// double stopienPrzejezdnosci = Teren.getStopienPrzejezdnosci(aktualny.x, aktualny.y, sasiad.x, sasiad.y, +// aktualny.zKierunku, podwozie); + double stopienPrzejezdnosci = 1; if (stopienPrzejezdnosci < 0.005f) { continue; } @@ -310,8 +311,9 @@ public final class AStar { } sasiedzi = aktualny.dajNiezamknietychSasiadow(); for (Node sasiad : sasiedzi) { - double stopienPrzejezdnosci = Teren.getStopienPrzejezdnosciNew(aktualny.x, aktualny.y, sasiad.x, sasiad.y, - aktualny.zKierunku, podwozie, szerokoscPokonywRowow, glebokoscBrodzenia, predkoscPlywania); +// double stopienPrzejezdnosci = Teren.getStopienPrzejezdnosciNew(aktualny.x, aktualny.y, sasiad.x, sasiad.y, +// aktualny.zKierunku, podwozie, szerokoscPokonywRowow, glebokoscBrodzenia, predkoscPlywania); + double stopienPrzejezdnosci = 1; if (stopienPrzejezdnosci < 0.005f) { continue; } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/BigSquare.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/BigSquare.java index b2c273d..776d0ef 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/BigSquare.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/BigSquare.java @@ -1,12 +1,14 @@ package pl.wat.ms4ds.terenfunkcje; abstract class BigSquare { - abstract Kwadrat getKwadrat(int Id_X, int Id_Y); + abstract Square getKwadrat(int x, int y); protected transient String fileName; - public int xRefMs = 0; - public int yRefMs = 0; + public int idX = 0; + public int idY = 0; public transient int liczbaZmian = 0; // TODO zamienic na 100 static final int LICZBA_ZMIAN_DO_ZAPISU = 100000; + + } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/CoordConversion.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/CoordConversion.java new file mode 100644 index 0000000..b2b9d04 --- /dev/null +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/CoordConversion.java @@ -0,0 +1,158 @@ +package pl.wat.ms4ds.terenfunkcje; + +public class CoordConversion { + + /* + Opis: + konwersja wspolrzednych z ukladu WGS 84 do ukladu PUWG 1992 + Parametry: + B_stopnie - szerokosc geograficzna wyrazona w stopniach + L_stopnie - dlugosc geograficzna wyrazona w stopniach + Xpuwg - wskazanie na wspolrzedna X ukladu PUWG 1992 (UWAGA - wspolrzedna pionowa) + Ypuwg - wskazanie na wspolrzedna Y ukladu PUWG 1992 (UWAGA - wspolrzedna pozioma) + Zwracana wartosc: + 0 - konwersja powiodla sie + 1 - szerokosc geograficzna B poza zakresem + 2 - dlugosc geograficzna L poza zakresem + */ + public static int wgs84ToPuwg1992(double B_stopnie, double L_stopnie) { + double Xpuwg; + double Ypuwg; + // Parametry elipsoidy GRS-80 + double e = 0.0818191910428; //pierwszymimo¶ród elipsoidy + double R0 = 6367449.14577; //promieñ sfery Lagrange.a + double Snorm = 2.0E-6; //parametr normuj±cy + double xo = 5760000.0; //parametr centruj±cy + + //Wspolczynniki wielomianu + double a0 = 5765181.11148097; + double a1 = 499800.81713800; + double a2 = -63.81145283; + double a3 = 0.83537915; + double a4 = 0.13046891; + double a5 = -0.00111138; + double a6 = -0.00010504; + + // Parametry odwzorowania Gaussa-Kruegera dla uk³adu PUWG92 + double L0_stopnie = 19.0; //Pocz±tek uk³adu wsp. PUWG92 (d³ugo¶æ) + double m0 = 0.9993; + double x0 = -5300000.0; + double y0 = 500000.0; + + // Zakres stosowalnosci metody + double Bmin = 48.0 * Math.PI / 180.0; + double Bmax = 56.0 * Math.PI / 180.0; + double dLmin = -6.0 * Math.PI / 180.0; + double dLmax = 6.0 * Math.PI / 180.0; + + // Weryfikacja danych wejsciowych + double B = B_stopnie * Math.PI / 180.0; + double dL_stopnie = L_stopnie - L0_stopnie; + double dL = dL_stopnie * Math.PI / 180.0; + + if ((B < Bmin) || (B > Bmax)) + return 1; + + if ((dL < dLmin) || (dL > dLmax)) + return 2; + + //etap I - elipsoida na kulê + double U = 1.0 - e * Math.sin(B); + double V = 1.0 + e * Math.sin(B); + double K = Math.pow((U / V), (e / 2.0)); + double C = K * Math.tan(B / 2.0 + Math.PI / 4.0); + double fi = 2.0 * Math.atan(C) - Math.PI / 2.0; + double d_lambda = dL; + + // etap II - kula na walec + double p = Math.sin(fi); + double q = Math.cos(fi) * Math.cos(d_lambda); + double r = 1.0 + Math.cos(fi) * Math.sin(d_lambda); + double s = 1.0 - Math.cos(fi) * Math.sin(d_lambda); + double XMERC = R0 * Math.atan(p / q); + double YMERC = 0.5 * R0 * Math.log(r / s); + +// //etap III - walec na p³aszczyznê +// complex Z ((XMERC - xo) * Snorm, YMERC * Snorm); +// complex Zgk; +// Zgk = a0 + Z * (a1 + Z * (a2 + Z * (a3 + Z * (a4 + Z * (a5 + Z * a6))))); +// double Xgk = Zgk.real(); +// double Ygk = Zgk.imag(); +// +// //Przej¶cie do uk³adu aplikacyjnego +// Xpuwg = m0 * Xgk + x0; +// Ypuwg = m0 * Ygk + y0; + + return 0; + } + + /* +Opis: + konwersja wspolrzednych z ukladu PUWG 1992 do ukladu WGS 84 +Parametry: + Xpuwg - wskazanie na wspolrzedna X ukladu PUWG 1992 (UWAGA - wspolrzedna pionowa) + Ypuwg - wskazanie na wspolrzedna Y ukladu PUWG 1992 (UWAGA - wspolrzedna pozioma) + B_stopnie - szerokosc geograficzna wyrazona w stopniach + L_stopnie - dlugosc geograficzna wyrazona w stopniach +Zwracana wartosc: + 0 - konwersja powiodla sie + */ + public static int puwg1992ToWgs84(double Xpuwg, double Ypuwg, double B_stopnie, double L_stopnie) { + double L0_stopnie = 19.0; //Pocz±tek uk³adu wsp. PUWG92 (d³ugo¶æ) + double m0 = 0.9993; + double x0 = -5300000.0; + double y0 = 500000.0; + + double R0 = 6367449.14577; //promieñ sfery Lagrange.a + double Snorm = 2.0E-6; //parametr normuj±cy + double xo_prim = 5765181.11148097; //parametr centruj±cy + + // Wspolczynniki wielomianu + double b0 = 5760000; + double b1 = 500199.26224125; + double b2 = 63.88777449; + double b3 = -0.82039170; + double b4 = -0.13125817; + double b5 = 0.00101782; + double b6 = 0.00010778; + + // Wspolczynniki szeregu tryg. + double c2 = 0.0033565514856; + double c4 = 0.0000065718731; + double c6 = 0.0000000176466; + double c8 = 0.0000000000540; + + //Przejscie z ukladu aplikacyjnego + double Xgk, Ygk; + Xgk = (Xpuwg - x0) / m0; + Ygk = (Ypuwg - y0) / m0; + +// //etap I - (Xgk, Ygk) -> (Xmerc, Ymerc) +// complex Z ((Xgk - xo_prim) * Snorm, Ygk * Snorm); +// complex Zmerc; +// +// Zmerc = b0 + Z * (b1 + Z * (b2 + Z * (b3 + Z * (b4 + Z * (b5 + Z * b6))))); +// +// double Xmerc = Zmerc.real(); +// double Ymerc = Zmerc.imag(); +// +// //etap II - Xmerc,Ymerc -> fi, delta_lambda +// double alfa = Xmerc / R0; +// double beta = Ymerc / R0; +// +// double w = 2.0 * atan(exp(beta)) - M_PI / 2.0; +// double fi = asin(cos(w) * sin(alfa)); +// double d_lambda = atan(tan(w) / cos(alfa)); +// +// //etap III +// double B = fi + c2 * sin(2.0 * fi) + c4 * sin(4.0 * fi) + c6 * sin(6.0 * fi) + c8 * sin(8.0 * fi); +// double dL = d_lambda; +// +// //Obliczenia koncowe +// *B_stopnie = B / M_PI * 180.0; +// double dL_stopnie = dL / M_PI * 180.0; +// *L_stopnie = dL_stopnie + L0_stopnie; + + return 0; + } +} diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/EmptyBigSquare.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/EmptyBigSquare.java index 6bbff1f..7ed5020 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/EmptyBigSquare.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/EmptyBigSquare.java @@ -7,7 +7,7 @@ class EmptyBigSquare extends BigSquare { private EmptyBigSquare() { } - Kwadrat getKwadrat(int ssX, int ssY) { - return Kwadrat.EMPTY_SQUARE; + Square getKwadrat(int ssX, int ssY) { + return Square.EMPTY; } } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/GeoCoord.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/GeoCoord.java index ea93f7d..dbb0478 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/GeoCoord.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/GeoCoord.java @@ -6,4 +6,14 @@ package pl.wat.ms4ds.terenfunkcje; public class GeoCoord { public double lat; public double lon; + + public GeoCoord() {} + public GeoCoord(double lat, double lon) { + this.lat = lat; + this.lon = lon; + } + public GeoCoord(GeoCoord other) { + lat = other.lat; + lon = other.lon; + } } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/GridCoord.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/GridCoord.java index 6268c0e..f4b6f6f 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/GridCoord.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/GridCoord.java @@ -332,7 +332,7 @@ public class GridCoord { // wyznaczenie numeru kwadraty Au2 dla wspolrzednej X // np.: '153200' to 304 - int xms = Teren.zamienWspUtmNaWspXms(wspolrzedneUtm); + int xms = Teren.zamienWspSMSNaWspXms(wspolrzedneUtm); int idKwX = GridCoord.zamienWspXmsNaIdKwadratuX(xms); return idKwX; } @@ -342,7 +342,7 @@ public class GridCoord { // wspolrzedne - znaki w formacie 522644N0154232E // wyznaczenie numeru kwadraty Au2 dla wspolrzednej Y // np.: '153200' to 304 - int yms = Teren.zamienWspUtmNaWspYms(wspolrzedneUtm); + int yms = Teren.zamienWspSMSNaWspYms(wspolrzedneUtm); int idKwY = GridCoord.zamienWspYmsNaIdKwadratuY(yms); return idKwY; } @@ -361,7 +361,7 @@ public class GridCoord { public static String zamienIdKwadratuNaWspUtm(GridCoord kwadrat) { long xms = zamienIdKwadratuXNaWspXms(kwadrat.x); long yms = zamienIdKwadratuYNaWspYms(kwadrat.y); - return Teren.zamienWspXmsYmsNaWspUtm(xms, yms); + return Teren.zamienWspXmsYmsNaWspSMS(xms, yms); } /** diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/Kwadrat.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/Kwadrat.java deleted file mode 100644 index 55bbfb9..0000000 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/Kwadrat.java +++ /dev/null @@ -1,358 +0,0 @@ -package pl.wat.ms4ds.terenfunkcje; - - -import pl.wat.ms4ds.common.EGeoDirection; - -public class Kwadrat { - - public static final Kwadrat EMPTY_SQUARE = new Kwadrat(null, 0.0f, 0.0f, 0.0f, 0.0f, 200, 0, - new boolean[8], new boolean[8], new boolean[8]); - - float stopienZabudowy; - float stopienZalesienia; - float stopienZawodnienia; - float stopienZabagnienia; - boolean jestDroga[]; - boolean jestRow[]; - boolean jestPrzeszkodaWodna[]; - int roznicaWzniesien; - int wysokoscSrednia; - - /** - * The height above the level of the sea. - */ - short elevation; - /** - * 0 - BARE_GROUND - * 1 - GRASS - * 2 - SWAMP - * 3 - WATER - * 4 - SCRUB, BUSHES - * 5 - BUILDINGS - * 6 - FOREST - */ - short terrainType; - /** - * Rodzaj drogi na danym kierunku. - * 0 - no road, 1 - small roads, 2 - minor roads, 3 - major roads - */ - byte[] roads; - /** - * Rodzaj przeszkody wodnej na danym kierunku. - * 0 - no watercourse, 1 - drain, ditch, 2 - canal, stream, 3 - river - */ - byte[] waterWays; - - - - transient RightBigSquare bs; - - public float getStopienZabudowy() { - return stopienZabudowy; - } - - public float getStopienZalesienia() { - return stopienZalesienia; - } - - public float getStopienZawodnienia() { - return stopienZawodnienia; - } - - public float getStopienZabagnienia() { - return stopienZabagnienia; - } - - public int getRoznicaWzniesien() { - return roznicaWzniesien; - } - - public int getWysokoscSrednia() { - return wysokoscSrednia; - } - - public boolean[] getJestDroga() { - return jestDroga; - } - - public boolean jestOdcinekDrogi() { - for (int i = 0; i < 8; i++) { - if (jestDroga[i]) - return true; - } - return false; - } - - public boolean getJestDroga(EGeoDirection naKierunku) { - if (naKierunku == EGeoDirection.UNDEFINED) { - return false; - } - return jestDroga[naKierunku.id]; - } - - public boolean[] getJestRow() { - return jestRow; - } - - public boolean[] getJestPrzeszkodaWodna() { - return jestPrzeszkodaWodna; - } - - public void setStopienZabudowy(float stopienZabudowy) { - this.stopienZabudowy = stopienZabudowy; - normalizujDanePokrycia(); -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public void setStopienZalesienia(float stopienZalesienia) { - this.stopienZalesienia = stopienZalesienia; - normalizujDanePokrycia(); -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public void setStopienZawodnienia(float stopienZawodnienia) { - this.stopienZawodnienia = stopienZawodnienia; - normalizujDanePokrycia(); -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public void setStopienZabagnienia(float stopienZabagnienia) { - this.stopienZabagnienia = stopienZabagnienia; - normalizujDanePokrycia(); -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public void normalizujDanePokrycia() { - float suma = stopienZalesienia + stopienZawodnienia + stopienZabudowy + stopienZabagnienia; - if (suma > 1.0f) { - stopienZalesienia /= suma; - stopienZawodnienia /= suma; - stopienZabudowy /= suma; - stopienZabagnienia = 1.0f - stopienZalesienia - stopienZawodnienia - stopienZabudowy; - } - } - - public void setRoznicaWzniesien(int roznicaWzniesien) { - this.roznicaWzniesien = roznicaWzniesien; -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public void setWysokoscSrednia(int wysokoscSrednia) { - this.wysokoscSrednia = wysokoscSrednia; -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public void setJestDroga(boolean[] czyJestDroga) { - this.jestDroga = czyJestDroga; -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public void setJestDroga(EGeoDirection naKierunku, boolean czyJest) { - if (naKierunku == EGeoDirection.UNDEFINED) { - return; - } - this.jestDroga[naKierunku.id] = czyJest; -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public void setJestPrzeszkodaWodna(EGeoDirection naKierunku, boolean czyJest) { - if (naKierunku == EGeoDirection.UNDEFINED) { - return; - } - this.jestPrzeszkodaWodna[naKierunku.id] = czyJest; -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public void setJestRow(EGeoDirection naKierunku, boolean czyJest) { - if (naKierunku == EGeoDirection.UNDEFINED) { - return; - } - this.jestRow[naKierunku.id] = czyJest; -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public void setJestRow(boolean[] czyJestRow) { - this.jestRow = czyJestRow; -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public void setJestPrzeszkodaWodna(boolean[] czyJestPrzeszkodaWodna) { - this.jestPrzeszkodaWodna = czyJestPrzeszkodaWodna; -// try { -// if (null != bs) { -// bs.updateFile(false); -// } -// } catch (IOException e) { -// } - } - - public float getStopienPofaldowania() { - // TODO: dodac do normatywow w klasie Teren (parametr kalibracyjny) - float stopienPofaldowania = 0.0f; - if (this.roznicaWzniesien >= 50) - stopienPofaldowania = 1.0f; - else if (this.roznicaWzniesien >= 10) - stopienPofaldowania = 0.6f; - else if (this.roznicaWzniesien >= 5) - stopienPofaldowania = 0.4f; - else if (this.roznicaWzniesien >= 3) - stopienPofaldowania = 0.2f; - return stopienPofaldowania; - } - - public Kwadrat() { - jestDroga = new boolean[8]; - jestPrzeszkodaWodna = new boolean[8]; - jestRow = new boolean[8]; - } - - public Kwadrat(RightBigSquare _bs, float _stopienZabudowy, float _stopienZalesienia, float _stopienZabagnienia, float _stopienZawodnienia, - int _wysokoscSrednia, int _roznicaWzniesien, boolean _czyJestDroga[], boolean _czyJestRow[], boolean _czyJestPrzeszkodaWodna[]){ - bs = _bs; - stopienZabudowy = _stopienZabudowy; - stopienZalesienia = _stopienZalesienia; - stopienZabagnienia = _stopienZabagnienia; - stopienZawodnienia = _stopienZawodnienia; - wysokoscSrednia = _wysokoscSrednia; - roznicaWzniesien = _roznicaWzniesien; - jestDroga = new boolean[8]; - jestRow = new boolean[8]; - jestPrzeszkodaWodna = new boolean[8]; - for (int i = 0; i < _czyJestDroga.length; i++) { - jestDroga[i]=_czyJestDroga[i]; - } - for (int i = 0; i < jestRow.length; i++) { - jestRow[i]=_czyJestRow[i]; - } - for (int i = 0; i < _czyJestPrzeszkodaWodna.length; i++) { - jestPrzeszkodaWodna[i]=_czyJestPrzeszkodaWodna[i]; - } - } - - public String toString() { - float f = this.stopienZabudowy * 255.0f; - int hex = (int)f; - String s = String.format("%02X", hex); - String linia = s; - linia += " "; - - f = this.stopienZalesienia * 255.0f; - hex = (int)f; - s = String.format("%02X", hex); - linia += s; - linia += " "; - - f = this.stopienZabagnienia * 255.0f; - hex = (int)f; - s = String.format("%02X", hex); - linia += s; - linia += " "; - - f = this.stopienZawodnienia * 255.0f; - hex = (int)f; - s = String.format("%02X", hex); - linia += s; - linia += " "; - - s = String.format("%4d", this.wysokoscSrednia); - linia += s; - linia += " "; - - s = String.format("%4d", this.roznicaWzniesien); - linia += s; - linia += " "; - - int bity = 0; - int bit_1 = 1; - for (int i = 0; i < this.jestDroga.length; i++) { - if (this.jestDroga[i]) // jest odcinek drogi na tym kierunku - bity += bit_1; - - bit_1 = bit_1 << 1; - } - s = String.format("%02X", bity); - linia += s; - linia += " "; - - bity = 0; - bit_1 = 1; - for (int i = 0; i < this.jestPrzeszkodaWodna.length; i++) { - if (this.jestPrzeszkodaWodna[i]) // jest przeszkod na tym kierunku - bity += bit_1; - - bit_1 = bit_1 << 1; - } - s = String.format("%02X", bity); - linia += s; - linia += " "; - - bity = 0; - bit_1 = 1; - for (int i = 0; i < this.jestRow.length; i++) { - if (this.jestRow[i]) // jest row na tym kierunku - bity += bit_1; - - bit_1 = bit_1 << 1; - } - s = String.format("%02X", bity); - linia += s; - return linia; - } - - -} diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/MapConsts.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/MapConsts.java index 8060f08..f3758ad 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/MapConsts.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/MapConsts.java @@ -2,6 +2,7 @@ package pl.wat.ms4ds.terenfunkcje; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; @@ -9,49 +10,49 @@ import java.util.Properties; public final class MapConsts { - private static final Logger LOGGER = LoggerFactory.getLogger(MapConsts.class); + private static final Logger LOGGER = LoggerFactory.getLogger(MapConsts.class); - /** - * Umowny uklad odniesienia dla lokalizacji geograficznej:

- * Długość geograficzna (wsp. X) przyjmuje wartości: [0, 360) odpowiadające [-180, 180]

- * Szerokość geograficzna (wsp. Y) przyjmuje wartości: [0, 180] odpowadające [-90, 90] - */ - public static final int X_REF; - /** - * Umowny uklad odniesienia dla lokalizacji geograficznej:

- * Długość geograficzna (wsp. X) przyjmuje wartości: [0, 360) odpowiadające [-180, 180]

- * Szerokość geograficzna (wsp. Y) przyjmuje wartości: [0, 180] odpowadające [-90, 90] - */ - public static final int Y_REF; - public static final int DX_REF; - public static final int DY_REF; + /** + * Umowny uklad odniesienia dla lokalizacji geograficznej:

+ * Długość geograficzna (wsp. X) przyjmuje wartości: [0, 360) odpowiadające [-180, 180]

+ * Szerokość geograficzna (wsp. Y) przyjmuje wartości: [0, 180] odpowadające [-90, 90] + */ + public static final int X_REF; + /** + * Umowny uklad odniesienia dla lokalizacji geograficznej:

+ * Długość geograficzna (wsp. X) przyjmuje wartości: [0, 360) odpowiadające [-180, 180]

+ * Szerokość geograficzna (wsp. Y) przyjmuje wartości: [0, 180] odpowadające [-90, 90] + */ + public static final int Y_REF; + public static final int DX_REF; + public static final int DY_REF; - public static final String KWADRATY_DIR; - public static final String DROGI_DIR; + public static final String KWADRATY_DIR; + public static final String DROGI_DIR; - /** - * Nazwa pliku z konfiguracja mechanizmu odpowiedzialnego za transfer. Plik - * musi znajdowac sie w katalogu glownym aplikacji, ewentualnie musi tu byc - * podana sciezka bezwzgledna do niego. - */ - private static final String PLIK_Z_USTAWIENIAMI = "teren.properties"; + /** + * Nazwa pliku z konfiguracja mechanizmu odpowiedzialnego za transfer. Plik + * musi znajdowac sie w katalogu glownym aplikacji, ewentualnie musi tu byc + * podana sciezka bezwzgledna do niego. + */ + private static final String PLIK_Z_USTAWIENIAMI = "teren.properties"; - /** - * Dlugosc boku duzego kwadratu na osi OX w liczbie malych kwadratow. - */ - public static final int SS_PER_BS_X; - /** - * Dlugosc boku duzego kwadratu na osi OY w liczbie malych kwadratow. - */ - public static final int SS_PER_BS_Y; + /** + * Dlugosc boku duzego kwadratu na osi OX w liczbie malych kwadratow. + */ + public static final int SS_PER_BS_X; + /** + * Dlugosc boku duzego kwadratu na osi OY w liczbie malych kwadratow. + */ + public static final int SS_PER_BS_Y; /** * Dlugosc boku malego kwadratu w metrach. */ public static final int DL_MK; - /** - * Powierzchnia malego kwadratu w metrach. - */ - public static final int POW_MK; + /** + * Powierzchnia malego kwadratu w metrach. + */ + public static final int POW_MK; /** * Szerokość małego kwadratu w stopniach. */ @@ -68,49 +69,53 @@ public final class MapConsts { * Liczba duzych kwadratow na stopien geograficzny po osi OY (szerokosc geograficzna). */ public static final int BS_PER_DEG_Y = 6; - /** - * Szerokość duzych kwadratow w stopniach geograficznych po osi OX (dlugosc geograficzna). - */ - public static final double BS_DX; - /** - * Wysokość duzych kwadratow w stopniach geograficznych po osi OY (szerokosc geograficzna). - */ - public static final double BS_DY; + /** + * Szerokość duzych kwadratow w stopniach geograficznych po osi OX (dlugosc geograficzna). + */ + public static final double BS_DX; + /** + * Wysokość duzych kwadratow w stopniach geograficznych po osi OY (szerokosc geograficzna). + */ + public static final double BS_DY; - static Properties ustawienia; + /** + * Szerokości geograficzne środków kwadratów. + */ + static double[] lats; + /** + * Długości geograficzne środków kwadratów. + */ + static double[] lons; - /** - * Odczytanie ustawien z pliku konfiguracyjnego. - */ - static { - String propertiesFileName = System.getProperty("user.dir") + "\\" + PLIK_Z_USTAWIENIAMI; + static Properties ustawienia; - ustawienia = new Properties(); - try { - LOGGER.debug("Odczyt ustawien z pliku " + propertiesFileName + "."); - ustawienia.load(new FileInputStream(propertiesFileName)); - LOGGER.debug("Ustawienia wczytane."); - } catch (FileNotFoundException e) { - LOGGER.error(e.getLocalizedMessage()); - } catch (IOException e) { - LOGGER.error(e.getLocalizedMessage()); - } + static { + String propertiesFileName = System.getProperty("user.dir") + "\\" + PLIK_Z_USTAWIENIAMI; + + ustawienia = new Properties(); + try { + LOGGER.debug("Odczyt ustawien z pliku " + propertiesFileName + "."); + ustawienia.load(new FileInputStream(propertiesFileName)); + LOGGER.debug("Ustawienia wczytane."); + } catch (IOException e) { + LOGGER.error(e.getLocalizedMessage()); + } // logger.debug("Ustawienia wczytane."); - // przesuniecie o 180 stop. - // poludnik zerowy ma wartosc 180, zatem wspolrzedne zachodnie (ujemne) zawierają sie w <0, 180) - // wspolrzedne wschodnie (nieujemne) zawieraja sie w przedziale <180, 360) - X_REF = Integer.parseInt(ustawienia.getProperty("x_ref")) + 180; - // przesuniecie o 90 stop. - // rownik ma wartosc 90, zatem wspolrzedne poludniowe (ujemne) zawierają sie w <0, 90) - // wspolrzedne polnocne (nieujemne) zawieraja sie w przedziale <90, 180> - Y_REF = Integer.parseInt(ustawienia.getProperty("y_ref")) + 90; - DX_REF = Integer.parseInt(ustawienia.getProperty("dx_ref")); - DY_REF = Integer.parseInt(ustawienia.getProperty("dy_ref")); - String val = ustawienia.getProperty("dl_mk"); + // przesuniecie o 180 stop. + // poludnik zerowy ma wartosc 180, zatem wspolrzedne zachodnie (ujemne) zawierają sie w <0, 180) + // wspolrzedne wschodnie (nieujemne) zawieraja sie w przedziale <180, 360) + X_REF = Integer.parseInt(ustawienia.getProperty("x_ref")) + 180; + // przesuniecie o 90 stop. + // rownik ma wartosc 90, zatem wspolrzedne poludniowe (ujemne) zawierają sie w <0, 90) + // wspolrzedne polnocne (nieujemne) zawieraja sie w przedziale <90, 180> + Y_REF = Integer.parseInt(ustawienia.getProperty("y_ref")) + 90; + DX_REF = Integer.parseInt(ustawienia.getProperty("dx_ref")); + DY_REF = Integer.parseInt(ustawienia.getProperty("dy_ref")); + String val = ustawienia.getProperty("dl_mk"); switch (val) { - case "20": - DL_MK = 20; - break; + case "20": + DL_MK = 20; + break; case "25": DL_MK = 25; break; @@ -124,119 +129,133 @@ public final class MapConsts { DL_MK = 200; break; } - POW_MK = DL_MK * DL_MK; - DROGI_DIR = ustawienia.getProperty("drogi_dir"); - if (DL_MK == 20) { - SS_PER_BS_X = 83 * 10; - SS_PER_BS_Y = 93 * 10; - DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); - DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); - KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "20m/"; - } else if (DL_MK == 25) { + POW_MK = DL_MK * DL_MK; + DROGI_DIR = ustawienia.getProperty("drogi_dir"); + if (DL_MK == 20) { + SS_PER_BS_X = 83 * 10; + SS_PER_BS_Y = 93 * 10; + DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); + DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); + KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "20m/"; + } else if (DL_MK == 25) { SS_PER_BS_X = 83 * 8; SS_PER_BS_Y = 93 * 8; DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "25m/"; } else if (DL_MK == 50) { - SS_PER_BS_X = 83 * 4; - SS_PER_BS_Y = 93 * 4; - DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); - DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); - KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "50m/"; - } else if (DL_MK == 100) { - SS_PER_BS_X = 83 * 2; - SS_PER_BS_Y = 93 * 2; - DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); - DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); - KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "100m/"; - } else { - // domyslnie dlugosc kwadratu 200m - SS_PER_BS_X = 83; - SS_PER_BS_Y = 93; - DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); - DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); - KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "200m/"; - } - BS_DX = 1.0 / (double) BS_PER_DEG_X; - BS_DY = 1.0 / (double) BS_PER_DEG_Y; - } - - /** - * Liczba milisekund na stopien. - */ - public static final int DEG_MS = 3600000; - /** - * Liczba milisekund na 360 stopni. - */ - public static final long ANGLE_360_MS = 3600000 * 360; - /** - * Wielkosc cache'u pola walki (liczba duzych kwadratow trzymanych w RAM). - */ - public static final int MAX_BIG_SQUARES_IN_MEMORY = 500; - /** - * Wspolrzedna referencyjna X (dlugosc geograficzna) lewego dolnego rogu mapy w stopniach geograficznych. - * @return - */ - public static int getX_REF() { - return X_REF; - } + SS_PER_BS_X = 83 * 4; + SS_PER_BS_Y = 93 * 4; + DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); + DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); + KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "50m/"; + } else if (DL_MK == 100) { + SS_PER_BS_X = 83 * 2; + SS_PER_BS_Y = 93 * 2; + DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); + DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); + KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "100m/"; + } else { + // domyslnie dlugosc kwadratu 200m + SS_PER_BS_X = 83; + SS_PER_BS_Y = 93; + DELTA_X = 1.0 / (double) (BS_PER_DEG_X * SS_PER_BS_X); + DELTA_Y = 1.0 / (double) (BS_PER_DEG_Y * SS_PER_BS_Y); + KWADRATY_DIR = ustawienia.getProperty("kwadraty_dir") + "200m/"; + } + BS_DX = 1.0 / (double) BS_PER_DEG_X; + BS_DY = 1.0 / (double) BS_PER_DEG_Y; + lons = new double[DX_REF * BS_PER_DEG_X * SS_PER_BS_X]; + for (int i = 0; i < lons.length; i++) { + lons[i] = X_REF + DELTA_X * (i + 0.5); + } + lats = new double[DY_REF * BS_PER_DEG_Y * SS_PER_BS_Y]; + for (int i = 0; i < lats.length; i++) { + lats[i] = Y_REF + DELTA_Y * (i + 0.5); + } + } - /** - * Wspolrzedna referencyjna Y (szerokosc geograficzna) lewego dolnego rogu mapy w stopniach geograficznych. - * @return + /** + * Liczba milisekund na stopien. */ - public static int getY_REF() { + public static final int DEG_MS = 3600000; + /** + * Liczba milisekund na 360 stopni. + */ + public static final long ANGLE_360_MS = 3600000 * 360; + /** + * Wielkosc cache'u pola walki (liczba duzych kwadratow trzymanych w RAM). + */ + public static final int MAX_BIG_SQUARES_IN_MEMORY = 500; + + /** + * Wspolrzedna referencyjna X (dlugosc geograficzna) lewego dolnego rogu mapy w stopniach geograficznych. + * + * @return + */ + public static int getX_REF() { + return X_REF; + } + + /** + * Wspolrzedna referencyjna Y (szerokosc geograficzna) lewego dolnego rogu mapy w stopniach geograficznych. + * + * @return + */ + public static int getY_REF() { return Y_REF; } - - /** - * Szerokosc referencyjna prostokata pola walki w stopniach na osi OX (dlugosc geograficzna). - * @return + + /** + * Szerokosc referencyjna prostokata pola walki w stopniach na osi OX (dlugosc geograficzna). + * + * @return */ - public static int getDX_REF() { + public static int getDX_REF() { return DX_REF; - } - - /** - * Wysokosc referencyjna prostokata pola walki w stopniach na osi OY (szerokosc geograficzna). - * @return + } + + /** + * Wysokosc referencyjna prostokata pola walki w stopniach na osi OY (szerokosc geograficzna). + * + * @return */ - public static int getDY_REF() { + public static int getDY_REF() { return DY_REF; - } + } - public static String getKwadratyDir() { - return KWADRATY_DIR; - } + public static String getKwadratyDir() { + return KWADRATY_DIR; + } - public static String getDrogiDir() { - return DROGI_DIR; - } - /** - * Dlugosci bokow malego kwadratu w milisekundach geograficznych po osi OX (dlugosc geograficzna). - */ - public static final double SS_DX_MS = DELTA_X * DEG_MS; - /** - * Dlugosci bokow malego kwadratu w milisekundach geograficznych po osi OY (szerokosc geograficzna). - */ - public static final double SS_DY_MS = DELTA_Y * DEG_MS; - // wspolrzedne dolnego lewego rogu mapy w ms - // wspolrzedne geograficzne w milisekundach zawieraja sie w zakresie: - // 0 <= x < 360 dlugosc geograficzna - // 0 <= y <= 180 szerokosc geograficzna - public static final int X_REF_MS = X_REF * DEG_MS; - public static final int Y_REF_MS = Y_REF * DEG_MS; - public static final int DX_REF_MS = DEG_MS * DX_REF; // szerokosc pola walki w stopniach - public static final int DY_REF_MS = DEG_MS * DY_REF; // wysokosc polwa walki w stopniach + public static String getDrogiDir() { + return DROGI_DIR; + } - public static final int BS_DX_MS = (int) (BS_DX * DEG_MS); - public static final int BS_DY_MS = (int) (BS_DY * DEG_MS); + /** + * Dlugosci bokow malego kwadratu w milisekundach geograficznych po osi OX (dlugosc geograficzna). + */ + public static final double SS_DX_MS = DELTA_X * DEG_MS; + /** + * Dlugosci bokow malego kwadratu w milisekundach geograficznych po osi OY (szerokosc geograficzna). + */ + public static final double SS_DY_MS = DELTA_Y * DEG_MS; + // wspolrzedne dolnego lewego rogu mapy w ms + // wspolrzedne geograficzne w milisekundach zawieraja sie w zakresie: + // 0 <= x < 360 dlugosc geograficzna + // 0 <= y <= 180 szerokosc geograficzna + public static final int X_REF_MS = X_REF * DEG_MS; + public static final int Y_REF_MS = Y_REF * DEG_MS; + public static final int DX_REF_MS = DEG_MS * DX_REF; // szerokosc pola walki w stopniach + public static final int DY_REF_MS = DEG_MS * DY_REF; // wysokosc polwa walki w stopniach + + public static final int BS_DX_MS = (int) (BS_DX * DEG_MS); + public static final int BS_DY_MS = (int) (BS_DY * DEG_MS); + + /** + * Liczba malych kwadratow przypadajaca na bok arkusza mapy drogowej. + */ + public static final int SS_PER_SHEET = 20; - /** - * Liczba malych kwadratow przypadajaca na bok arkusza mapy drogowej. - */ - public static final int SS_PER_SHEET = 20; - } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/RightBigSquare.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/RightBigSquare.java index dba71a9..5132936 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/RightBigSquare.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/RightBigSquare.java @@ -2,15 +2,16 @@ package pl.wat.ms4ds.terenfunkcje; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import java.io.*; public class RightBigSquare extends BigSquare implements Serializable { private static final Logger logger = LoggerFactory.getLogger(RightBigSquare.class); - private Kwadrat kwadraty[][]; + private Square kwadraty[][]; - Kwadrat getKwadrat(int ssX, int ssY) { + Square getKwadrat(int ssX, int ssY) { return kwadraty[ssX][ssY]; } @@ -123,37 +124,41 @@ 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); + // 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++) { + + + } + } + out.close(); + logger.debug("Zapisano nowy plik mapy: " + sb); + } /** - * Funkcja generuje nowy plik z danymi na podstawie danych z pliku referencyjnego (kwadraty o rozm. 200m). - *

Nowy plik moze byc z danymi w innej skali (kwadraty o rozmiarach: 100m lub 50m) i/lub innym formacie (binarny, tekstowy). + * Funkcja generuje nowy plik z danymi na podstawie danych z pliku referencyjnego (kwadraty o rozm. 100m). + *

Nowy plik moze byc z danymi w innej skali (kwadraty o rozmiarach: 100m lub 50m). * * @param dir katalog docelowy dla nowego pliku * @param dlmk rozmiar kwadratow generownych danych * @throws IOException generowany wyjątek */ - public void saveNewFileWithNewScale(String dir, int dlmk) throws IOException { + public void saveNewFileWithNewScale20m(String dir, int dlmk) throws IOException { if (MapConsts.DL_MK != 100) { // operacja tylko dla danych terenowych o kwadratach 200m return; } - int m = 1; - String s = ""; - if (dlmk == 100) { - m = 1; - s = "100m/"; - } else if (dlmk == 50) { - m = 2; - s = "50m/"; - } else if (dlmk == 25) { - m = 4; - s = "25m/"; - } else if (dlmk == 20) { - m = 5; - s = "20m/"; - } else { - return; - } + final int m = 5; + String s = "20m/"; StringBuilder sb = new StringBuilder(100); sb.append(dir); sb.append(s); @@ -164,13 +169,13 @@ public class RightBigSquare extends BigSquare implements Serializable { sb.append(".bin"); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString())); - SmallSquare[][][][] ss_all = new SmallSquare[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y][][]; + Square.RawData[][][][] ss_all = new Square.RawData[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y][][]; for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) { for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) { - SmallSquare[][] ss = new SmallSquare[m][m]; + Square.RawData[][] ss = new Square.RawData[m][m]; for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { - ss[i][j] = new SmallSquare(); + ss[i][j] = new Square.RawData(); } } ss_all[x][y] = ss; @@ -331,6 +336,58 @@ public class RightBigSquare extends BigSquare implements Serializable { logger.debug("Zapisano nowy plik mapy: " + sb + " dla rozmiaru MK= " + dlmk); } + /** + * Generuje nowe, wyzerowane kwadraty w danej skali w nowym formacie. + * + * @param dir + * @param dlmk + * @throws IOException + */ + public void saveNewFileWithNewFormatZero(String dir, int dlmk) throws IOException { + if (MapConsts.DL_MK != 100) { + // operacja tylko dla danych terenowych o kwadratach 200m + return; + } + int m; + String s = ""; + if (dlmk == 100) { + m = 1; + s = "100m/"; + } else if (dlmk == 50) { + m = 2; + s = "50m/"; + } else if (dlmk == 25) { + m = 4; + s = "25m/"; + } else if (dlmk == 20) { + m = 5; + s = "20m/"; + } else { + return; + } + StringBuilder sb = new StringBuilder(100); + sb.append(dir); + sb.append(s); + // Utworzenie katalogów, gdyby nie istniały. + File directory = new File(sb.toString()); + directory.mkdirs(); + sb.append(fileName); + Square.RawData ss = new Square.RawData(); + ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString())); + for (int x = 0; x < MapConsts.SS_PER_BS_X; x++) { + for (int y = 0; y < MapConsts.SS_PER_BS_Y; y++) { + ss.elevation = (short) kwadraty[x][y].wysokoscSrednia; + for (int i = 0; i < m; i++) { + for (int j = 0; j < m; j++) { + ss.save(out); + } + } + } + } + out.close(); + logger.debug("Zapisano nowy plik mapy: {} dla rozmiaru MK= {}", sb, dlmk); + } + void load(String FName) throws IOException { try { fileName = FName; @@ -338,12 +395,15 @@ public class RightBigSquare extends BigSquare implements Serializable { sb.append(MapConsts.KWADRATY_DIR); sb.append(fileName); sb.append(".bin"); - SmallSquare ss = new SmallSquare(); + Square.RawData ss = new Square.RawData(); ObjectInputStream in = new ObjectInputStream(new FileInputStream(sb.toString())); - kwadraty = new Kwadrat[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y]; + kwadraty = 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++) { - kwadraty[x][y] = new Kwadrat(); + Square kw = new Square(x0 + x, y0 + y); + kwadraty[x][y] = kw; ss.load(in); switch (ss.terrainType) { case 0: @@ -353,50 +413,49 @@ public class RightBigSquare extends BigSquare implements Serializable { case 4: break; case 2: - kwadraty[x][y].stopienZabagnienia = 1.f; + kw.stopienZabagnienia = 1.f; break; case 3: - kwadraty[x][y].stopienZawodnienia = 1.f; + kw.stopienZawodnienia = 1.f; break; case 5: - kwadraty[x][y].stopienZabudowy = 1.f; + kw.stopienZabudowy = 1.f; break; case 6: - kwadraty[x][y].stopienZalesienia = 1.f; + kw.stopienZalesienia = 1.f; break; } - kwadraty[x][y].wysokoscSrednia = ss.elevation; - kwadraty[x][y].roznicaWzniesien = 0; + kw.wysokoscSrednia = ss.elevation; + kw.roznicaWzniesien = 0; int bit_1 = 1; int hex = ss.majorRoads; - for (int i = 0; i < kwadraty[x][y].jestDroga.length; i++) { + for (int i = 0; i < kw.jestDroga.length; i++) { // jest odcinek rowu na tym kierunku if ((hex & bit_1) != 0) { - kwadraty[x][y].jestDroga[i] = true; + kw.jestDroga[i] = true; } bit_1 <<= 1; } bit_1 = 1; hex = ss.rivers; - for (int i = 0; i < kwadraty[x][y].jestPrzeszkodaWodna.length; i++) { + for (int i = 0; i < kw.jestPrzeszkodaWodna.length; i++) { // jest odcinek rowu na tym kierunku if ((hex & bit_1) != 0) { - kwadraty[x][y].jestPrzeszkodaWodna[i] = true; + kw.jestPrzeszkodaWodna[i] = true; } bit_1 <<= 1; } bit_1 = 1; hex = ss.drains; - for (int i = 0; i < kwadraty[x][y].jestRow.length; i++) { + for (int i = 0; i < kw.jestRow.length; i++) { // jest odcinek rowu na tym kierunku if ((hex & bit_1) != 0) { - kwadraty[x][y].jestRow[i] = true; + kw.jestRow[i] = true; } bit_1 <<= 1; } - kwadraty[x][y].bs = this; } } in.close(); @@ -546,54 +605,55 @@ public class RightBigSquare extends BigSquare implements Serializable { // konstruktor ladujacy duzy kwadrat z pliku binarnego RightBigSquare(String FName) throws IOException { try { - fileName = FName; + fileName = FName + ".bin"; StringBuilder sb = new StringBuilder(100); sb.append(MapConsts.KWADRATY_DIR); sb.append(fileName); - sb.append(".bin"); ObjectInputStream in = new ObjectInputStream(new FileInputStream(sb.toString())); - kwadraty = new Kwadrat[MapConsts.SS_PER_BS_X][MapConsts.SS_PER_BS_Y]; + kwadraty = 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++) { - kwadraty[x][y] = new Kwadrat(); + Square kw = new Square(x0 + x, y0 + y); + kwadraty[x][y] = kw; int hex = in.readByte(); - kwadraty[x][y].stopienZalesienia = (float) hex * (1.0f / 100.f); + kw.stopienZalesienia = (float) hex * (1.0f / 100.f); hex = in.readByte(); - kwadraty[x][y].stopienZawodnienia = (float) hex * (1.0f / 100.f); + kw.stopienZawodnienia = (float) hex * (1.0f / 100.f); hex = in.readByte(); - kwadraty[x][y].stopienZabudowy = (float) hex * (1.0f / 100.f); + kw.stopienZabudowy = (float) hex * (1.0f / 100.f); hex = in.readByte(); - kwadraty[x][y].stopienZabagnienia = (float) hex * (1.0f / 100.f); - kwadraty[x][y].wysokoscSrednia = in.readInt(); - kwadraty[x][y].roznicaWzniesien = in.readInt(); + kw.stopienZabagnienia = (float) hex * (1.0f / 100.f); + kw.wysokoscSrednia = in.readInt(); + kw.roznicaWzniesien = in.readInt(); int bit_1 = 1; hex = in.readByte(); - for (int i = 0; i < kwadraty[x][y].jestDroga.length; i++) { + for (int i = 0; i < kw.jestDroga.length; i++) { // jest odcinek rowu na tym kierunku if ((hex & bit_1) != 0) { - kwadraty[x][y].jestDroga[i] = true; + kw.jestDroga[i] = true; } bit_1 <<= 1; } bit_1 = 1; hex = in.readByte(); - for (int i = 0; i < kwadraty[x][y].jestPrzeszkodaWodna.length; i++) { + for (int i = 0; i < kw.jestPrzeszkodaWodna.length; i++) { // jest odcinek rowu na tym kierunku if ((hex & bit_1) != 0) { - kwadraty[x][y].jestPrzeszkodaWodna[i] = true; + kw.jestPrzeszkodaWodna[i] = true; } bit_1 <<= 1; } bit_1 = 1; hex = in.readByte(); - for (int i = 0; i < kwadraty[x][y].jestRow.length; i++) { + for (int i = 0; i < kw.jestRow.length; i++) { // jest odcinek rowu na tym kierunku if ((hex & bit_1) != 0) { - kwadraty[x][y].jestRow[i] = true; + kw.jestRow[i] = true; } bit_1 <<= 1; } - kwadraty[x][y].bs = this; } } in.close(); diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/SiecDrogowa.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/SiecDrogowa.java index 1ab2104..75b9c7e 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/SiecDrogowa.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/SiecDrogowa.java @@ -6,34 +6,35 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pl.wat.ms4ds.common.EGeoDirection; public class SiecDrogowa { - static final Logger logger = LoggerFactory.getLogger(SiecDrogowa.class); + static final Logger logger = LoggerFactory.getLogger(SiecDrogowa.class); - ArrayList luki; - ArrayList wezly; - static SiecDrogowa instancja; - static String path; + ArrayList luki; + ArrayList wezly; + static SiecDrogowa instancja; + static String path; - Arkusz[][] arkusze; + Arkusz[][] arkusze; - public int liczbaZmian = 0; - static final int LICZBA_ZMIAN = 50; + public int liczbaZmian = 0; + static final int LICZBA_ZMIAN = 50; - SiecDrogowa(String dataPath) { - instancja = this; + SiecDrogowa(String dataPath) { + instancja = this; // File wd = new File("."); // PATH = wd.getPath(); - path = dataPath; - this.odczytajWezly(path + "/nodes.txt"); - logger.debug("wczytano " + this.wezly.size() + " wezlow."); - this.odczytajLuki(path + "/arcs.txt"); - logger.debug("wczytano " + this.luki.size() + " lukow."); - stworzArkusze(); + path = dataPath; + this.odczytajWezly(path + "/nodes.txt"); + logger.debug("wczytano " + this.wezly.size() + " wezlow."); + this.odczytajLuki(path + "/arcs.txt"); + logger.debug("wczytano " + this.luki.size() + " lukow."); + stworzArkusze(); // logger.debug("Liczba lukow w arkuszach:"); @@ -45,309 +46,309 @@ public class SiecDrogowa { // } // } // logger.debug("Sum. liczba lukow w arkuszach:" + ll); - } + } - void odczytajWezly(String fname) { - try { - FileReader fis = new FileReader(fname); - BufferedReader br = new BufferedReader(fis); - if (br.ready()) { - String line = br.readLine().trim(); - int licz = Integer.parseInt(line); - this.wezly = new ArrayList(licz);// + 1000); - while (null != (line = br.readLine())) { - WezelDrogowy nowyWezel = new WezelDrogowy(line); - nowyWezel.id = this.wezly.size(); //Indeksowanie od 0 - this.wezly.add(nowyWezel); - } - } - br.close(); - } catch (IOException e) { - logger.warn("Brak pliku z wezlami: " + fname); - } - } + void odczytajWezly(String fname) { + try { + FileReader fis = new FileReader(fname); + BufferedReader br = new BufferedReader(fis); + if (br.ready()) { + String line = br.readLine().trim(); + int licz = Integer.parseInt(line); + this.wezly = new ArrayList(licz);// + 1000); + while (null != (line = br.readLine())) { + WezelDrogowy nowyWezel = new WezelDrogowy(line); + nowyWezel.id = this.wezly.size(); //Indeksowanie od 0 + this.wezly.add(nowyWezel); + } + } + br.close(); + } catch (IOException e) { + logger.warn("Brak pliku z wezlami: " + fname); + } + } - void odczytajLuki(String fname) { - try { - FileReader fis = new FileReader(fname); - BufferedReader br = new BufferedReader(fis); - if (br.ready()) { - String line = br.readLine().trim(); - int licz = Integer.parseInt(line); - this.luki = new ArrayList(licz);// + 1000); - while (null != (line = br.readLine())) { - LukDrogowy nowyLuk = new LukDrogowy(line); - nowyLuk.id = this.luki.size(); //Indeksowanie od 0 - this.luki.add(nowyLuk); - } - } - br.close(); - } catch (IOException e) { - logger.warn("Brak pliku z lukami: " + fname); - } - } + void odczytajLuki(String fname) { + try { + FileReader fis = new FileReader(fname); + BufferedReader br = new BufferedReader(fis); + if (br.ready()) { + String line = br.readLine().trim(); + int licz = Integer.parseInt(line); + this.luki = new ArrayList(licz);// + 1000); + while (null != (line = br.readLine())) { + LukDrogowy nowyLuk = new LukDrogowy(line); + nowyLuk.id = this.luki.size(); //Indeksowanie od 0 + this.luki.add(nowyLuk); + } + } + br.close(); + } catch (IOException e) { + logger.warn("Brak pliku z lukami: " + fname); + } + } - void stworzArkusze() { - // wyznaczenie wymiarow pola walki w malych kwadratach - Arkusz.lx = MapConsts.getDX_REF() * MapConsts.BS_PER_DEG_X * MapConsts.SS_PER_BS_X; - Arkusz.ly = MapConsts.getDY_REF() * MapConsts.BS_PER_DEG_Y * MapConsts.SS_PER_BS_Y; - // wyznacznie liczby arkuszy mapy w obu wymiarach - Arkusz.lx = Arkusz.lx / MapConsts.SS_PER_SHEET + 1; - Arkusz.ly = Arkusz.ly / MapConsts.SS_PER_SHEET + 1; - this.arkusze = new Arkusz[Arkusz.lx][Arkusz.ly]; - for (int i = 0; i < Arkusz.lx; i++) { - for (int j = 0; j < Arkusz.ly; j++) { - this.arkusze[i][j] = new Arkusz(); - } - } - // wspolrzedne arkusza mapy - int xa, ya; - for (int i = 0; i < this.wezly.size(); i++) { - WezelDrogowy wezel = this.wezly.get(i); - xa = wezel.idKw.x / MapConsts.SS_PER_SHEET; - ya = wezel.idKw.y / MapConsts.SS_PER_SHEET; - this.arkusze[xa][ya].wezly.add(wezel); - } - int xa2, ya2; - for (int i = 0; i < this.luki.size(); i++) { - LukDrogowy luk = this.luki.get(i); - xa = luk.getWezly()[0].idKw.x / MapConsts.SS_PER_SHEET; - ya = luk.getWezly()[0].idKw.y / MapConsts.SS_PER_SHEET; - xa2 = luk.getWezly()[1].idKw.x / MapConsts.SS_PER_SHEET; - ya2 = luk.getWezly()[1].idKw.y / MapConsts.SS_PER_SHEET; - boolean b = Arkusz.mniejszeWspolrzedne(xa, ya, xa2, ya2); - if (b) { - this.arkusze[xa][ya].luki.add(luk); - } else { - this.arkusze[xa2][ya2].luki.add(luk); - } - } - } + void stworzArkusze() { + // wyznaczenie wymiarow pola walki w malych kwadratach + Arkusz.lx = MapConsts.getDX_REF() * MapConsts.BS_PER_DEG_X * MapConsts.SS_PER_BS_X; + Arkusz.ly = MapConsts.getDY_REF() * MapConsts.BS_PER_DEG_Y * MapConsts.SS_PER_BS_Y; + // wyznacznie liczby arkuszy mapy w obu wymiarach + Arkusz.lx = Arkusz.lx / MapConsts.SS_PER_SHEET + 1; + Arkusz.ly = Arkusz.ly / MapConsts.SS_PER_SHEET + 1; + this.arkusze = new Arkusz[Arkusz.lx][Arkusz.ly]; + for (int i = 0; i < Arkusz.lx; i++) { + for (int j = 0; j < Arkusz.ly; j++) { + this.arkusze[i][j] = new Arkusz(); + } + } + // wspolrzedne arkusza mapy + int xa, ya; + for (int i = 0; i < this.wezly.size(); i++) { + WezelDrogowy wezel = this.wezly.get(i); + xa = wezel.idKw.x / MapConsts.SS_PER_SHEET; + ya = wezel.idKw.y / MapConsts.SS_PER_SHEET; + this.arkusze[xa][ya].wezly.add(wezel); + } + int xa2, ya2; + for (int i = 0; i < this.luki.size(); i++) { + LukDrogowy luk = this.luki.get(i); + xa = luk.getWezly()[0].idKw.x / MapConsts.SS_PER_SHEET; + ya = luk.getWezly()[0].idKw.y / MapConsts.SS_PER_SHEET; + xa2 = luk.getWezly()[1].idKw.x / MapConsts.SS_PER_SHEET; + ya2 = luk.getWezly()[1].idKw.y / MapConsts.SS_PER_SHEET; + boolean b = Arkusz.mniejszeWspolrzedne(xa, ya, xa2, ya2); + if (b) { + this.arkusze[xa][ya].luki.add(luk); + } else { + this.arkusze[xa2][ya2].luki.add(luk); + } + } + } - public static void utworzSiecDrogowa(){ + public static void utworzSiecDrogowa() { // if (null == instancja){ // instancja = new SiecDrogowa(MapConsts.DROGI_DIR); // } - } + } - public static LukDrogowy dodajLuk(WezelDrogowy wezel1, WezelDrogowy wezel2) { - utworzSiecDrogowa(); - LukDrogowy nowyLuk = new LukDrogowy(); - nowyLuk.getWezly()[0] = wezel1; - wezel1.luki.add(nowyLuk); - nowyLuk.getWezly()[1] = wezel2; - wezel2.luki.add(nowyLuk); - instancja.luki.add(nowyLuk); - nowyLuk.id = instancja.luki.size() - 1; - return nowyLuk; - } + public static LukDrogowy dodajLuk(WezelDrogowy wezel1, WezelDrogowy wezel2) { + utworzSiecDrogowa(); + LukDrogowy nowyLuk = new LukDrogowy(); + nowyLuk.getWezly()[0] = wezel1; + wezel1.luki.add(nowyLuk); + nowyLuk.getWezly()[1] = wezel2; + wezel2.luki.add(nowyLuk); + instancja.luki.add(nowyLuk); + nowyLuk.id = instancja.luki.size() - 1; + return nowyLuk; + } - public static WezelDrogowy dodajWezel(String wspUTM) { - utworzSiecDrogowa(); - // TODO dodac weryfikacje poprawnosci wspolrzednych UTM - WezelDrogowy nowyWezel = new WezelDrogowy(); - nowyWezel.setXms(Teren.zamienWspUtmNaWspXms(wspUTM.substring(0, 6))); - nowyWezel.setYms(Teren.zamienWspUtmNaWspXms(wspUTM.substring(8, 14))); - int x = GridCoord.zamienWspXmsNaIdKwadratuX(nowyWezel.getXms()); - int y = GridCoord.zamienWspYmsNaIdKwadratuY(nowyWezel.getYms()); - nowyWezel.idKw = new GridCoord(x, y); - nowyWezel.luki = new ArrayList(); - instancja.wezly.add(nowyWezel); - nowyWezel.id = instancja.wezly.size() - 1; - return nowyWezel; - } + public static WezelDrogowy dodajWezel(String wspUTM) { + utworzSiecDrogowa(); + // TODO dodac weryfikacje poprawnosci wspolrzednych UTM + WezelDrogowy nowyWezel = new WezelDrogowy(); + nowyWezel.setXms(Teren.zamienWspSMSNaWspXms(wspUTM.substring(0, 6))); + nowyWezel.setYms(Teren.zamienWspSMSNaWspXms(wspUTM.substring(8, 14))); + int x = GridCoord.zamienWspXmsNaIdKwadratuX(nowyWezel.getXms()); + int y = GridCoord.zamienWspYmsNaIdKwadratuY(nowyWezel.getYms()); + nowyWezel.idKw = new GridCoord(x, y); + nowyWezel.luki = new ArrayList(); + instancja.wezly.add(nowyWezel); + nowyWezel.id = instancja.wezly.size() - 1; + return nowyWezel; + } - public static void usunLuk(LukDrogowy usuwanyLuk) { - utworzSiecDrogowa(); - if (usuwanyLuk.id < 0 || usuwanyLuk.id >= instancja.luki.size()) { - return; - } - int ostatniId = instancja.luki.size() - 1; - LukDrogowy lukOstatni = instancja.luki.get(ostatniId); - lukOstatni.id = usuwanyLuk.id; - instancja.luki.set(lukOstatni.id, lukOstatni); - instancja.luki.remove(ostatniId); - // aktualizacja wezlow luku - usuwanyLuk.getWezly()[0].luki.remove(usuwanyLuk); - usuwanyLuk.getWezly()[1].luki.remove(usuwanyLuk); - if (usuwanyLuk.getWezly()[0].luki.size() == 0) { - usunWezel(usuwanyLuk.getWezly()[0]); - } - if (usuwanyLuk.getWezly()[1].luki.size() == 0) { - usunWezel(usuwanyLuk.getWezly()[1]); - } - } + public static void usunLuk(LukDrogowy usuwanyLuk) { + utworzSiecDrogowa(); + if (usuwanyLuk.id < 0 || usuwanyLuk.id >= instancja.luki.size()) { + return; + } + int ostatniId = instancja.luki.size() - 1; + LukDrogowy lukOstatni = instancja.luki.get(ostatniId); + lukOstatni.id = usuwanyLuk.id; + instancja.luki.set(lukOstatni.id, lukOstatni); + instancja.luki.remove(ostatniId); + // aktualizacja wezlow luku + usuwanyLuk.getWezly()[0].luki.remove(usuwanyLuk); + usuwanyLuk.getWezly()[1].luki.remove(usuwanyLuk); + if (usuwanyLuk.getWezly()[0].luki.size() == 0) { + usunWezel(usuwanyLuk.getWezly()[0]); + } + if (usuwanyLuk.getWezly()[1].luki.size() == 0) { + usunWezel(usuwanyLuk.getWezly()[1]); + } + } - public static void usunWezel(WezelDrogowy usuwanyWezel) { - utworzSiecDrogowa(); - if (usuwanyWezel.id < 0 || usuwanyWezel.id >= instancja.wezly.size()) { - return; - } - int ostatniId = instancja.wezly.size() - 1; - WezelDrogowy wezelOstatni = instancja.wezly.get(ostatniId); - wezelOstatni.id = usuwanyWezel.id; - instancja.wezly.set(wezelOstatni.id, wezelOstatni); - instancja.wezly.remove(ostatniId); - } + public static void usunWezel(WezelDrogowy usuwanyWezel) { + utworzSiecDrogowa(); + if (usuwanyWezel.id < 0 || usuwanyWezel.id >= instancja.wezly.size()) { + return; + } + int ostatniId = instancja.wezly.size() - 1; + WezelDrogowy wezelOstatni = instancja.wezly.get(ostatniId); + wezelOstatni.id = usuwanyWezel.id; + instancja.wezly.set(wezelOstatni.id, wezelOstatni); + instancja.wezly.remove(ostatniId); + } - public static void wpiszDrogiWKwadraty() { - utworzSiecDrogowa(); - GridCoord[] kwadratyOdcinka; - for (int i = 0; i < instancja.luki.size(); i++) { - LukDrogowy luk = instancja.luki.get(i); - GridCoord kw1 = luk.getWezly()[0].idKw; - GridCoord kw2 = luk.getWezly()[1].idKw; - kwadratyOdcinka = GeomUtils.kwadratyOdcinka(kw1, kw2); - wpiszOdcinekDrogiWKwadraty(kwadratyOdcinka); - } - Teren.zapisBuforaMapyDoPliku(); - } + public static void wpiszDrogiWKwadraty() { + utworzSiecDrogowa(); + GridCoord[] kwadratyOdcinka; + for (int i = 0; i < instancja.luki.size(); i++) { + LukDrogowy luk = instancja.luki.get(i); + GridCoord kw1 = luk.getWezly()[0].idKw; + GridCoord kw2 = luk.getWezly()[1].idKw; + kwadratyOdcinka = GeomUtils.kwadratyOdcinka(kw1, kw2); + wpiszOdcinekDrogiWKwadraty(kwadratyOdcinka); + } + Teren.zapisBuforaMapyDoPliku(); + } - static void wpiszOdcinekDrogiWKwadraty(GridCoord[] kwadratyOdcinka) { - if (null == kwadratyOdcinka) { - return; - } - for (int i = 0; i < kwadratyOdcinka.length - 1; i++) { - GridCoord idkw1 = kwadratyOdcinka[i]; - GridCoord idkw2 = kwadratyOdcinka[i + 1]; + static void wpiszOdcinekDrogiWKwadraty(GridCoord[] kwadratyOdcinka) { + if (null == kwadratyOdcinka) { + return; + } + for (int i = 0; i < kwadratyOdcinka.length - 1; i++) { + GridCoord idkw1 = kwadratyOdcinka[i]; + GridCoord idkw2 = kwadratyOdcinka[i + 1]; EGeoDirection kier = GeomUtils.kierunekDlaSasiada(idkw1, idkw2); - Kwadrat kw = Teren.getKwadrat(idkw1.x, idkw1.y); - if (null != kw) { - kw.setJestDroga(kier, true); - } - kw = Teren.getKwadrat(idkw2.x, idkw2.y); - if (null != kw) { - // wyznaczam kierunek przeciwny - kier = kier.oppositeDirect(); - kw.setJestDroga(kier, true); - } - } - } + Square kw = Teren.getKwadrat(idkw1.x, idkw1.y); + if (null != kw) { + kw.jestDroga[kier.id] = true; + } + kw = Teren.getKwadrat(idkw2.x, idkw2.y); + if (null != kw) { + // wyznaczam kierunek przeciwny + kier = kier.oppositeDirect(); + kw.jestDroga[kier.id] = true; + } + } + } - public void aktualizujPliki(boolean wymuszony) throws IOException { - if (wymuszony) { - if (this.liczbaZmian == 0) - // nie bylo modyfikacji od ostatniej zapisu - return; - this.liczbaZmian = -1; - } - this.liczbaZmian++; - this.liczbaZmian %= LICZBA_ZMIAN; - if (0 == this.liczbaZmian) { - try { - // zapisanie wezlow - BufferedWriter bw = new BufferedWriter(new FileWriter(path + "\\nodes.txt")); - String linia = Integer.toString(this.wezly.size()); - bw.write(linia, 0, linia.length()); - bw.newLine(); - String s; - for (int i = 0; i < this.wezly.size(); i++) { - WezelDrogowy wezel = this.wezly.get(i); - s = String.format("%07d", wezel.id); - linia = s; - linia += " "; - s = String.format("%010d", wezel.getXms()); - linia += s; - linia += " "; - s = String.format("%010d", wezel.getYms()); - linia += s; - linia += " "; - int most = 0; - if (wezel.jestMostem) { - most = 1; - } - s = String.format("%01d", most); - linia += s; - bw.write(linia, 0, linia.length()); - bw.newLine(); - } - bw.close(); - logger.info("Zapisano plik wezlow sieci drogowej: " + path + "\\nodes.txt"); - } catch (IOException e) { - logger.warn("Blad zapisu pliku wezlow sieci drogowej: " + path + "\\nodes.txt"); - } - try { - // zapisanie lukow - BufferedWriter bw = new BufferedWriter(new FileWriter(path + "\\arcs.txt")); - String linia = Integer.toString(this.luki.size()); - bw.write(linia, 0, linia.length()); - bw.newLine(); - String s; - for (int i = 0; i < this.luki.size(); i++) { - LukDrogowy luk = this.luki.get(i); - s = String.format("%07d", luk.getWezly()[0].id); - linia = s; - linia += " "; - s = String.format("%07d", luk.getWezly()[1].id); - linia += s; - linia += " "; - s = String.format("%05d", luk.dlugosc); - linia += s; - linia += " "; - s = String.format("%02d", luk.szerokosc); - linia += s; - linia += " "; - int most = 0; - if (luk.jestMostem) { - most = 1; - } - s = String.format("%01d", most); - linia += s; - bw.write(linia, 0, linia.length()); - bw.newLine(); - } - bw.close(); - logger.info("Zapisano plik lukow sieci drogowej: " + path + "\\arcs.txt"); - } catch (IOException e) { - logger.warn("Blad zapisu pliku lukow sieci drogowej: " + path + "\\arcs.txt"); - } - } - } + public void aktualizujPliki(boolean wymuszony) throws IOException { + if (wymuszony) { + if (this.liczbaZmian == 0) + // nie bylo modyfikacji od ostatniej zapisu + return; + this.liczbaZmian = -1; + } + this.liczbaZmian++; + this.liczbaZmian %= LICZBA_ZMIAN; + if (0 == this.liczbaZmian) { + try { + // zapisanie wezlow + BufferedWriter bw = new BufferedWriter(new FileWriter(path + "\\nodes.txt")); + String linia = Integer.toString(this.wezly.size()); + bw.write(linia, 0, linia.length()); + bw.newLine(); + String s; + for (int i = 0; i < this.wezly.size(); i++) { + WezelDrogowy wezel = this.wezly.get(i); + s = String.format("%07d", wezel.id); + linia = s; + linia += " "; + s = String.format("%010d", wezel.getXms()); + linia += s; + linia += " "; + s = String.format("%010d", wezel.getYms()); + linia += s; + linia += " "; + int most = 0; + if (wezel.jestMostem) { + most = 1; + } + s = String.format("%01d", most); + linia += s; + bw.write(linia, 0, linia.length()); + bw.newLine(); + } + bw.close(); + logger.info("Zapisano plik wezlow sieci drogowej: " + path + "\\nodes.txt"); + } catch (IOException e) { + logger.warn("Blad zapisu pliku wezlow sieci drogowej: " + path + "\\nodes.txt"); + } + try { + // zapisanie lukow + BufferedWriter bw = new BufferedWriter(new FileWriter(path + "\\arcs.txt")); + String linia = Integer.toString(this.luki.size()); + bw.write(linia, 0, linia.length()); + bw.newLine(); + String s; + for (int i = 0; i < this.luki.size(); i++) { + LukDrogowy luk = this.luki.get(i); + s = String.format("%07d", luk.getWezly()[0].id); + linia = s; + linia += " "; + s = String.format("%07d", luk.getWezly()[1].id); + linia += s; + linia += " "; + s = String.format("%05d", luk.dlugosc); + linia += s; + linia += " "; + s = String.format("%02d", luk.szerokosc); + linia += s; + linia += " "; + int most = 0; + if (luk.jestMostem) { + most = 1; + } + s = String.format("%01d", most); + linia += s; + bw.write(linia, 0, linia.length()); + bw.newLine(); + } + bw.close(); + logger.info("Zapisano plik lukow sieci drogowej: " + path + "\\arcs.txt"); + } catch (IOException e) { + logger.warn("Blad zapisu pliku lukow sieci drogowej: " + path + "\\arcs.txt"); + } + } + } - // funkcja zwraca kolekcje lukow wewnatrz prostokata - // zawartego miedzy lewym dolnym i prawym gornym punktem - public static ArrayList dajLukiWObszarze(String wspUtmLD, String wspUtmPG) { - utworzSiecDrogowa(); - int xms = Teren.zamienWspUtmNaWspXms(wspUtmLD); - int yms = Teren.zamienWspUtmNaWspYms(wspUtmLD); - int xa_ld = GridCoord.zamienWspXmsNaIdKwadratuX(xms); - xa_ld /= MapConsts.SS_PER_SHEET; - int ya_ld = GridCoord.zamienWspYmsNaIdKwadratuY(yms); - ya_ld /= MapConsts.SS_PER_SHEET; + // funkcja zwraca kolekcje lukow wewnatrz prostokata + // zawartego miedzy lewym dolnym i prawym gornym punktem + public static ArrayList dajLukiWObszarze(String wspUtmLD, String wspUtmPG) { + utworzSiecDrogowa(); + int xms = Teren.zamienWspSMSNaWspXms(wspUtmLD); + int yms = Teren.zamienWspSMSNaWspYms(wspUtmLD); + int xa_ld = GridCoord.zamienWspXmsNaIdKwadratuX(xms); + xa_ld /= MapConsts.SS_PER_SHEET; + int ya_ld = GridCoord.zamienWspYmsNaIdKwadratuY(yms); + ya_ld /= MapConsts.SS_PER_SHEET; - xms = Teren.zamienWspUtmNaWspXms(wspUtmPG); - yms = Teren.zamienWspUtmNaWspYms(wspUtmPG); - int xa_pg = GridCoord.zamienWspXmsNaIdKwadratuX(xms); - xa_pg /= MapConsts.SS_PER_SHEET; - int ya_pg = GridCoord.zamienWspYmsNaIdKwadratuY(yms); - ya_pg /= MapConsts.SS_PER_SHEET; + xms = Teren.zamienWspSMSNaWspXms(wspUtmPG); + yms = Teren.zamienWspSMSNaWspYms(wspUtmPG); + int xa_pg = GridCoord.zamienWspXmsNaIdKwadratuX(xms); + xa_pg /= MapConsts.SS_PER_SHEET; + int ya_pg = GridCoord.zamienWspYmsNaIdKwadratuY(yms); + ya_pg /= MapConsts.SS_PER_SHEET; - //if (xa_ld > xa_pg || ya_ld > ya_pg) { - // return null; - //} - if (xa_ld > xa_pg){ - int tmp = xa_ld; - xa_ld = xa_pg; - xa_pg = tmp; - } - if (ya_ld > ya_pg){ - int tmp = ya_ld; - ya_ld = ya_pg; - ya_pg = tmp; - } - ArrayList luki = new ArrayList(); - // wspolrzedne arkusza mapy - for (int xa = xa_ld; xa <= xa_pg; xa++) { - for (int ya = ya_ld; ya <= ya_pg; ya++) { - if (instancja.arkusze[xa][ya].luki != null) { - luki.addAll(instancja.arkusze[xa][ya].luki); - } - } - } - return luki; - } + //if (xa_ld > xa_pg || ya_ld > ya_pg) { + // return null; + //} + if (xa_ld > xa_pg) { + int tmp = xa_ld; + xa_ld = xa_pg; + xa_pg = tmp; + } + if (ya_ld > ya_pg) { + int tmp = ya_ld; + ya_ld = ya_pg; + ya_pg = tmp; + } + ArrayList luki = new ArrayList(); + // wspolrzedne arkusza mapy + for (int xa = xa_ld; xa <= xa_pg; xa++) { + for (int ya = ya_ld; ya <= ya_pg; ya++) { + if (instancja.arkusze[xa][ya].luki != null) { + luki.addAll(instancja.arkusze[xa][ya].luki); + } + } + } + return luki; + } - public static void main(String[] args) { + public static void main(String[] args) { // GridCoord idKw = GridCoord.zamienWspUtmNaIdKwadratu("520101N0160202E"); // String utm = GridCoord.zamienIdKwadratuNaWspUtm(idKw); // int xms = GridCoord.zamienIdKwadratuXNaWspXms(idKw.x); @@ -357,8 +358,8 @@ public class SiecDrogowa { // float lat = GridCoord.zamienIdKwadratuYNaSzerokoscGeo(idKw.y); // idKw.x = GridCoord.zamienDlugoscGeoNaIdKwadratuX(lon); // idKw.y = GridCoord.zamienSzerokoscGeoNaIdKwadratuY(lat); - utworzSiecDrogowa(); - SiecDrogowa.wpiszDrogiWKwadraty(); - } + utworzSiecDrogowa(); + SiecDrogowa.wpiszDrogiWKwadraty(); + } } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/SmallSquare.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/SmallSquare.java deleted file mode 100644 index ae90151..0000000 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/SmallSquare.java +++ /dev/null @@ -1,83 +0,0 @@ -package pl.wat.ms4ds.terenfunkcje; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -public class SmallSquare { - - - /** - * The height above the level of the sea. - */ - short elevation; - /** - * 0 - BARE_GROUND - * 1 - GRASS - * 2 - SWAMP - * 3 - WATER - * 4 - SCRUB, BUSHES - * 5 - BUILDINGS - * 6 - FOREST - */ - byte terrainType; - /** - * Rodzaj drogi na danym kierunku. - * 0 - no road, 1 - small roads, 2 - minor roads, 3 - major roads - */ -// byte[] roads; - byte smallRoads; - byte minorRoads; - byte majorRoads; - - /** - * Rodzaj przeszkody wodnej na danym kierunku. - * 0 - no watercourse, 1 - drain, ditch, 2 - canal, stream, 3 - river - */ -// byte[] waterWays; - byte drains; - byte streams; - byte rivers; - - - public void reset() { - elevation = 0; - terrainType = 0; - smallRoads = 0; - minorRoads = 0; - majorRoads = 0; - drains = 0; - streams = 0; - rivers = 0; - } - - public void save(ObjectOutputStream out) throws IOException { - out.writeShort(elevation); - out.writeByte(terrainType); - out.writeByte(smallRoads); - out.writeByte(minorRoads); - out.writeByte(majorRoads); - out.writeByte(drains); - out.writeByte(streams); - out.writeByte(rivers); - } - - public void load(ObjectInputStream in) throws IOException { - elevation = in.readShort(); - terrainType = in.readByte(); - smallRoads = in.readByte(); - minorRoads = in.readByte(); - majorRoads = in.readByte(); - drains = in.readByte(); - streams = in.readByte(); - rivers = in.readByte(); - } - - public SmallSquare(short elevation, byte terrainType) { - this.elevation = elevation; - this.terrainType = terrainType; - } - - public SmallSquare() { - } -} diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/Square.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/Square.java new file mode 100644 index 0000000..39322ac --- /dev/null +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/Square.java @@ -0,0 +1,282 @@ +package pl.wat.ms4ds.terenfunkcje; + + +import pl.wat.ms4ds.common.EGeoDirection; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +public class Square { + + /** + * The height above the level of the sea. Unit of measure decimeter [m]. + */ + float elevation; + + /** + * Terrain type.

Possible values: + * 0 - BARE_GROUND + * 1 - GRASS + * 2 - SWAMP + * 3 - WATER + * 4 - SCRUB, BUSHES + * 5 - BUILDINGS + * 6 - FOREST + */ + 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; + + /** + * 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; + + //////////////////////////////////////// + /// 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 class RawData { + /** + * The height above the level of the sea. Unit of measure decimeter [dm]. + */ + short elevation; + /** + * Terrain type.

Possible values: + * 0 - BARE_GROUND + * 1 - GRASS + * 2 - SWAMP + * 3 - WATER + * 4 - SCRUB, BUSHES + * 5 - BUILDINGS + * 6 - FOREST + */ + byte terrainType; + + /** + * Small road in a given direction. Each bit corresponds to a given direction. + */ + byte smallRoads; + + /** + * Minor road in a given direction. Each bit corresponds to a given direction. + */ + byte minorRoads; + + /** + * Major road in a given direction. Each bit corresponds to a given direction. + */ + byte majorRoads; + + /** + * The existence of a drain in a given direction. Each bit corresponds to a given direction. + */ + byte drains; + + /** + * The existence of a stream in a given direction. Each bit corresponds to a given direction. + */ + byte streams; + + /** + * The existence of a river in a given direction. Each bit corresponds to a given direction. + */ + byte rivers; + + public void reset() { + elevation = 0; + terrainType = 0; + smallRoads = 0; + minorRoads = 0; + majorRoads = 0; + drains = 0; + streams = 0; + rivers = 0; + } + + public void save(ObjectOutputStream out) throws IOException { + out.writeShort(elevation); + out.writeByte(terrainType); + out.writeByte(smallRoads); + out.writeByte(minorRoads); + out.writeByte(majorRoads); + out.writeByte(drains); + out.writeByte(streams); + out.writeByte(rivers); + } + + public void load(ObjectInputStream in) throws IOException { + elevation = in.readShort(); + terrainType = in.readByte(); + smallRoads = in.readByte(); + minorRoads = in.readByte(); + majorRoads = in.readByte(); + drains = in.readByte(); + streams = in.readByte(); + rivers = in.readByte(); + } + + public RawData(short elevation, byte terrainType) { + this.elevation = elevation; + this.terrainType = terrainType; + } + + public RawData() { + } + + public RawData(Square kw) { + terrainType = (byte) kw.terrainType; + // Konwersja na decymetry. + elevation = (short) (kw.elevation * 10); + 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; + } + bit <<= 1; + } + bit = 1; + for (int i = 0; i < kw.roads.length; i++) { + 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 Square() { + this(-2, -2); + } + + public Square(int x, int y) { + this.x = x; + 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; + 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; + } + } + + final int x; + final int y; + public double sumaWysokosci; + public int count = 1; + public double ell; + public double nll; + public double eur; + public double nur; + + + @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; + } + + + 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("%5.1f", 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(); + } + +} diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/Teren.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/Teren.java index 342272b..f378ce6 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/Teren.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/Teren.java @@ -3,14 +3,16 @@ package pl.wat.ms4ds.terenfunkcje; import java.io.*; import java.util.Set; import java.util.concurrent.locks.ReentrantLock; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pl.wat.ms4ds.common.EGeoDirection; import pl.wat.ms4ds.common.ERodzajPodwozia; import pl.wat.ms4ds.common.ERodzajTerenuPokrycie; +import pl.wat.ms4ds.terenfunkcje.konwersja.CoordUtils; import pl.wat.ms4ds.terenfunkcje.nmt.NMTDataProvider; -import static pl.wat.ms4ds.terenfunkcje.Kwadrat.EMPTY_SQUARE; +import static pl.wat.ms4ds.terenfunkcje.Square.EMPTY; public class Teren { @@ -22,19 +24,12 @@ public class Teren { private static BigSquare bigSquares[][] = new BigSquare[BIG_X_MAX][BIG_Y_MAX]; // tablica obiektów synchronizujących dostęp do dużych kwadratów przy odczycie z pliku - private static Object bsSynch[][] = new Object[BIG_X_MAX][BIG_Y_MAX]; + private static Object bsSynch = new Object(); private static final float[][] STOPIEN_PRZEJEZDNOSCI; private static final String LITERALS = "ABCDEF"; - /** - * Nazwa pliku z konfiguracja mechanizmu odpowiedzialnego za transfer. Plik - * musi znajdowac sie w katalogu glownym aplikacji, ewentualnie musi tu byc - * podana sciezka bezwzgledna do niego. - */ - private static final String PLIK_Z_USTAWIENIAMI = "teren.properties"; - private static boolean przejezdnoscZawsze; static double minStopienPrzejezd; static double minStopienPrzejezdNaPrzelaj; @@ -80,8 +75,14 @@ public class Teren { System.gc(); } - // funkcja zwraca reprezentacje danej wspolrzednej UTM w milisekundach - public static int zamienWspUtmNaWspXms(String wspolrzedneUtm) { + /** + * 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); @@ -95,8 +96,14 @@ public class Teren { return ms; } - // funkcja zwraca reprezentacje danej wspolrzednej UTM w milisekundach - public static int zamienWspUtmNaWspYms(String wspolrzedneUtm) { + /** + * 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); @@ -110,7 +117,14 @@ public class Teren { return ms; } - public static String zamienWspXmsYmsNaWspUtm(long xms, long yms) { + /** + * 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; @@ -145,7 +159,7 @@ public class Teren { // funkcja wyznacza wspolrzedne UTM ze wspolrzednych dziesietnych // Zalozenie: wspolrzedne w zakresie dlugosc wschodnia do 100 stopni, szerokosc polnocna - public static String zamienWspGeoDziesietnieNaWspUtm(float lon, float lat) { + public static String zamienWspGeoDziesietnieNaWspSMS(float lon, float lat) { int x_st = (int) lon; int y_st = (int) lat; @@ -224,7 +238,7 @@ public class Teren { try { return new RightBigSquare(fName); } 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; } } @@ -236,55 +250,46 @@ public class Teren { bs.load(fName); return bs; } 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; } } private static ReentrantLock synchr; - public static Kwadrat getKwadrat(int idX, int idY) { - if (idX < 0 || idY < 0) { - return EMPTY_SQUARE; - } - // wspolrzędna x dużego kwadratu - int bsX = idX / MapConsts.SS_PER_BS_X; - // wspolrzędna y dużego kwadratu - int bsY = idY / MapConsts.SS_PER_BS_Y; - if (bsX < 0 || bsX >= BIG_X_MAX || bsY < 0 || bsY >= BIG_Y_MAX) { - return EMPTY_SQUARE; - } - // wspolrzędna x małego kwadratu w ramach dużego kwadratu - int ssX = idX % MapConsts.SS_PER_BS_X; - // wspolrzędna y małego kwadratu w ramach dużego kwadratu - int ssY = idY % MapConsts.SS_PER_BS_Y; - synchronized (bsSynch[bsX][bsY]) { - if (bigSquares[bsX][bsY] == null) { - makeRoom(bsX, bsY); - bigSquares[bsX][bsY] = loadAreaNew(bsX, bsY); - } - } - return bigSquares[bsX][bsY].getKwadrat(ssX, ssY); + public static Square getKwadratPUWG(double northing, double easting) { + GeoCoord geoCoord = new GeoCoord(); + CoordUtils.convertPUWG1992ToWGS84(northing, easting, geoCoord); + return getKwadrat(geoCoord.lat, geoCoord.lon); } - public static Kwadrat getKwadrat2(int idX, int idY) { + public static Square getKwadrat(double lat, double lon) { + int idX = GridCoord.zamienDlugoscGeoNaIdKwadratuX(lon); + int idY = GridCoord.zamienSzerokoscGeoNaIdKwadratuY(lat); + return getKwadrat(idX, idY); + } + + public static Square getKwadrat(int idX, int idY) { if (idX < 0 || idY < 0) { - return EMPTY_SQUARE; + return EMPTY; } // wspolrzędna x dużego kwadratu int bsX = idX / MapConsts.SS_PER_BS_X; // wspolrzędna y dużego kwadratu int bsY = idY / MapConsts.SS_PER_BS_Y; if (bsX < 0 || bsX >= BIG_X_MAX || bsY < 0 || bsY >= BIG_Y_MAX) { - return EMPTY_SQUARE; + return EMPTY; } // wspolrzędna x małego kwadratu w ramach dużego kwadratu int ssX = idX % MapConsts.SS_PER_BS_X; // wspolrzędna y małego kwadratu w ramach dużego kwadratu int ssY = idY % MapConsts.SS_PER_BS_Y; - if (bigSquares[bsX][bsY] == null) { - makeRoom(bsX, bsY); - bigSquares[bsX][bsY] = loadAreaNew(bsX, bsY); + 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); } @@ -321,53 +326,6 @@ public class Teren { } } - public static Kwadrat getKwadrat(String wspUtm) { - int idX = GridCoord.zamienWspUtmNaIdkwadratuX(wspUtm); - int idY = GridCoord.zamienWspUtmNaIdkwadratuY(wspUtm); - return getKwadrat(idX, idY); - } - - public static double getStopienPrzejezdnosci(int x, int y, ERodzajPodwozia podwozie) { - Kwadrat kwd = Teren.getKwadrat(x, y); - if (kwd == EMPTY_SQUARE) { - return 0.0f; - } - if (kwd.getStopienZabudowy() > 0.0f) { - return Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id]; - } - if (kwd.getStopienZawodnienia() > 0.9f) { - return 0.0f; - } - double pow_czysta_start = 1 - kwd.getStopienZalesienia() - - kwd.getStopienZabagnienia() - kwd.getStopienZawodnienia() - - kwd.getStopienZabudowy(); - double sp = pow_czysta_start - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id]; - sp += kwd.getStopienZalesienia() - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id]; - sp += kwd.getStopienZabagnienia() - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id]; - sp += kwd.getStopienZawodnienia() - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id]; - sp *= (1.0f - kwd.getStopienPofaldowania()); - return sp; - } - - public static double getStopienPrzejezdnosci(GridCoord id, ERodzajPodwozia podwozie) { - return Teren.getStopienPrzejezdnosci(id.x, id.y, podwozie); - } - - /** - * @param idKwStart kwadrat startowy - * @param idKwStop kwadrat docelowy - * @param podwozie rodzaj podwozia - * @return stopien przejezdnosci pomieszy dwoma kwadratami - */ - public static double getStopienPrzejezdnosci(GridCoord idKwStart, GridCoord idKwStop, EGeoDirection zKierunku, - ERodzajPodwozia podwozie) { - return getStopienPrzejezdnosci(idKwStart.x, idKwStart.y, idKwStop.x, idKwStop.y, zKierunku, podwozie); - } - /** * Tablica danych o braku rowów w kwadracie dla funkcji przejezdnosci, gdy nie uwzględniamy rowów. */ @@ -417,314 +375,6 @@ public class Teren { return (st < minStopienPrzejezdNaPrzelajNachylenie) ? minStopienPrzejezdNaPrzelajNachylenie : st; } - /** - * Funkcja wyznacza stopień przejezdności między dwoma sąsiednimi kwadratami - * uwzględniając warunki terenowe oraz możliwości sprzętu w zakresie pokonywania terenu - * bez możliwości pokonywania rzek i rowów. - * - * @param xStart współrzędna GridCoord.X kwadratu startowego - * @param yStart współrzędna GridCoord.Y kwadratu startowego - * @param xStop współrzędna GridCoord.X kwadratu docelowego - * @param yStop współrzędna GridCoord.Y kwadratu docelowego - * @param zKierunku parametr informujący, z którego kierunku znaleziono się w kwadracie startowym - * @param podwozie rodzaj podwozia - * @return stopien przejezdnosci pomiędzy dwoma sąsiednimi kwadratami - */ - public static double getStopienPrzejezdnosci(int xStart, int yStart, int xStop, int yStop, EGeoDirection zKierunku, - ERodzajPodwozia podwozie) { - if (podwozie == ERodzajPodwozia.NIEOKRESLONE) { - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - if (xStart == xStop && yStart == yStop) { - return getStopienPrzejezdnosci(xStart, yStart, podwozie); - } - Kwadrat kwStart = Teren.getKwadrat(xStart, yStart); - Kwadrat kwStop = Teren.getKwadrat(xStop, yStop); - if (kwStart == EMPTY_SQUARE || kwStop == EMPTY_SQUARE) { - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - EGeoDirection nowyKierunek = GeomUtils.kierunekDlaSasiada(xStart, yStart, xStop, yStop); - if (EGeoDirection.UNDEFINED == nowyKierunek) { - LOGGER.warn("Błędna wartość kierunku przy wyznaczaniu stopnia przejezdności."); - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - int roznicaWysokosci = kwStop.wysokoscSrednia - kwStart.wysokoscSrednia; - double tangKataNachyl = roznicaWysokosci / GeomUtils.odlegloscKwadratowSasiednich(nowyKierunek); - boolean jestPrzeszkoda = Teren.jestPrzeszkodaNaKierunkuRuchu(xStart, yStart, zKierunku, nowyKierunek); - if (jestPrzeszkoda) { - if (kwStart.jestDroga[zKierunku.oppositeDirectId] && kwStart.jestDroga[nowyKierunek.id]) { - // sprawdzam, czy istnieje droga z kierunku wejsciowego (kierunek przeciwny do zKierunku) - // do wyjściowego (nowyKierunek), zatem istnieje most - return stopienPrzejezdNaDrodzeNachylenie(tangKataNachyl); - } - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - // jezeli jest droga na kierunku to przejezdnosc 1 (zakładam, że dane są kompletne i istnienie drogi - // na tym odcinku implikuje istnienie drogi na komplementarnym odcinku kwadratu docelowego) tj. - // kwStop.jestDroga[nowyKierunek.oppositeDirectId] == true - if (kwStart.jestDroga[nowyKierunek.id]) { - return stopienPrzejezdNaDrodzeNachylenie(tangKataNachyl); - } - double stopPrzejezdNachylenie = stopienPrzejezdNaPrzelajNachylenie(tangKataNachyl); - if (stopPrzejezdNachylenie <= 0.0) { - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - float stop_pow_czysta_kw_start = 1.0f - kwStart.stopienZalesienia - - kwStart.stopienZabagnienia - kwStart.stopienZawodnienia - kwStart.stopienZabudowy; - float stop_pow_czysta_kw_stop = 1.0f - kwStop.stopienZalesienia - - kwStop.stopienZabagnienia - kwStop.stopienZawodnienia - kwStop.stopienZabudowy; - double stopienPrzejezdKwadratStart = stop_pow_czysta_kw_start - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id]; - if (stop_pow_czysta_kw_start < 0.5f) { - stopienPrzejezdKwadratStart += kwStart.stopienZalesienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id]; - stopienPrzejezdKwadratStart += kwStart.stopienZabudowy - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id]; - stopienPrzejezdKwadratStart += kwStart.stopienZawodnienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id]; - stopienPrzejezdKwadratStart += kwStart.stopienZabagnienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id]; - } - double stopienPrzejezdKwadratStop = stop_pow_czysta_kw_stop - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id]; - if (stop_pow_czysta_kw_stop < 0.5f) { - stopienPrzejezdKwadratStop += kwStop.stopienZalesienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id]; - stopienPrzejezdKwadratStop += kwStop.stopienZabudowy - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id]; - stopienPrzejezdKwadratStop += kwStop.stopienZawodnienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id]; - stopienPrzejezdKwadratStop += kwStop.stopienZabagnienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id]; - } - if (stopienPrzejezdKwadratStart < 0.05 || stopienPrzejezdKwadratStop < 0.05) { - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - double wynik = (stopienPrzejezdKwadratStart + stopienPrzejezdKwadratStop) * 0.5f; - wynik *= stopPrzejezdNachylenie; - return (przejezdnoscZawsze) ? Math.max(minStopienPrzejezd, wynik) : wynik; - } - - /** - * Funkcja wyznacza stopień przejezdności między dwoma sąsiednimi kwadratami - * uwzględniając warunki terenowe oraz możliwości sprzętu w zakresie pokonywania terenu, w tym rzek i rowów. - * - * @param xStart współrzędna GridCoord.X kwadratu startowego - * @param yStart współrzędna GridCoord.Y kwadratu startowego - * @param xStop współrzędna GridCoord.X kwadratu docelowego - * @param yStop współrzędna GridCoord.Y kwadratu docelowego - * @param zKierunku parametr informujący, z którego kierunku znaleziono się w kwadracie startowym - * @param podwozie rodzaj podwozia - * @param szerokoscPokonywRowow szerokość pokonywanych rowów [m] - * @param glebokoscBrodzenia maksymalna głębokość brodzenia [m] - * @param predkoscPlywania maksymalna predkość pływania [m] (value == 0, to brak możliwości pływania) - * @return stopień przejezdności pomiędzy dwoma sąsiednimi kwadratami (wartości z przedziału [0.0, 1.0]) - */ - public static double getStopienPrzejezdnosciNew(int xStart, int yStart, int xStop, int yStop, EGeoDirection zKierunku, - ERodzajPodwozia podwozie, - double szerokoscPokonywRowow, - double glebokoscBrodzenia, - double predkoscPlywania) { - if (podwozie == ERodzajPodwozia.NIEOKRESLONE) { - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - if (xStart == xStop && yStart == yStop) { - return getStopienPrzejezdnosci(xStart, yStart, podwozie); - } - Kwadrat kwStart = Teren.getKwadrat(xStart, yStart); - Kwadrat kwStop = Teren.getKwadrat(xStop, yStop); - if (kwStart == EMPTY_SQUARE || kwStop == EMPTY_SQUARE) { - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - EGeoDirection nowyKierunek = GeomUtils.kierunekDlaSasiada(xStart, yStart, xStop, yStop); - if (EGeoDirection.UNDEFINED == nowyKierunek) { - LOGGER.warn("Błędna wartość kierunku przy wyznaczaniu stopnia przejezdności."); - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - int roznicaWysokosci = kwStop.wysokoscSrednia - kwStart.wysokoscSrednia; - double odleglosc = GeomUtils.odlegloscKwadratowSasiednich(nowyKierunek); - double tangKataNachyl = roznicaWysokosci / odleglosc; - double stopienPrzejezdKwadratStart = 1.0; - double stopienPrzejezdKwadratStop = 1.0; - if (podwozie != ERodzajPodwozia.PODUSZKA_POW) { - if (kwStart.stopienZawodnienia > 0.0f) { - if (predkoscPlywania > 0.0) { - stopienPrzejezdKwadratStart = 0.1; - } else { - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - } - if (kwStop.stopienZawodnienia > 0.0f) { - if (predkoscPlywania > 0.0) { - stopienPrzejezdKwadratStop = 0.1; - } else { - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - } - if (stopienPrzejezdKwadratStart + stopienPrzejezdKwadratStop >= 2.0) { - // uwzględnienie przeszkodów wodnych tylko gdy badane kwadraty bez pokrycia wodami powierzchniowymi - boolean jestPrzeszkoda = Teren.jestPrzeszkodaNaKierunkuRuchu(xStart, yStart, zKierunku, nowyKierunek); - if (jestPrzeszkoda) { - if (kwStart.jestDroga[zKierunku.oppositeDirectId] && kwStart.jestDroga[nowyKierunek.id]) { - // sprawdzam, czy istnieje droga z kierunku wejsciowego (kierunek przeciwny do "zKierunku") - // do wyjściowego "nowyKierunek", zatem istnieje most - return stopienPrzejezdNaDrodzeNachylenie(tangKataNachyl); - } else { - // jeśli jest przeszkoda wodna i nie ma mostu, to sprawdzam możliwości przeprawowe sprzętu - //TODO wyznaczyć przejezdność na podstawie możliwości przeprawowych sprzętu - if (predkoscPlywania > 0.0) { - stopienPrzejezdKwadratStart = 0.1; - } else { - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - } - } - } - } - // jezeli jest droga na kierunku to przejezdnosc 1 (zakładam, że dane są kompletne i istnienie drogi - // na tym odcinku implikuje istnienie drogi na komplementarnym odcinku kwadratu docelowego) tj. - // kwStop.jestDroga[nowyKierunek.oppositeDirectId] == true - if (kwStart.jestDroga[nowyKierunek.id]) { - return stopienPrzejezdNaDrodzeNachylenie(tangKataNachyl); - } - double stopPrzejezdNachylenie = stopienPrzejezdNaPrzelajNachylenie(tangKataNachyl); - if (stopPrzejezdNachylenie <= 0.0) { - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - if (stopienPrzejezdKwadratStart >= 1.0) { - float stop_pow_czysta_kw_start = 1.0f - kwStart.stopienZalesienia - - kwStart.stopienZabagnienia - kwStart.stopienZawodnienia - kwStart.stopienZabudowy; - stopienPrzejezdKwadratStart = stop_pow_czysta_kw_start - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id]; - if (stop_pow_czysta_kw_start < 0.5f) { - stopienPrzejezdKwadratStart += kwStart.stopienZalesienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id]; - stopienPrzejezdKwadratStart += kwStart.stopienZabudowy - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id]; - stopienPrzejezdKwadratStart += kwStart.stopienZawodnienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id]; - stopienPrzejezdKwadratStart += kwStart.stopienZabagnienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id]; - } - } - if (stopienPrzejezdKwadratStop >= 1.0) { - float stop_pow_czysta_kw_stop = 1.0f - kwStop.stopienZalesienia - - kwStop.stopienZabagnienia - kwStop.stopienZawodnienia - kwStop.stopienZabudowy; - stopienPrzejezdKwadratStop = stop_pow_czysta_kw_stop - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id]; - if (stop_pow_czysta_kw_stop < 0.5f) { - stopienPrzejezdKwadratStop += kwStop.stopienZalesienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZALESIONY.id]; - stopienPrzejezdKwadratStop += kwStop.stopienZabudowy - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZABUDOWANY.id]; - stopienPrzejezdKwadratStop += kwStop.stopienZawodnienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZAWODNIONY.id]; - stopienPrzejezdKwadratStop += kwStop.stopienZabagnienia - * Teren.STOPIEN_PRZEJEZDNOSCI[podwozie.id][ERodzajTerenuPokrycie.TEREN_ZABAGNIONY.id]; - } - } - if (stopienPrzejezdKwadratStart < 0.05 || stopienPrzejezdKwadratStop < 0.05) { - return (przejezdnoscZawsze) ? minStopienPrzejezd : 0.0f; - } - double wynik = (stopienPrzejezdKwadratStart + stopienPrzejezdKwadratStop) * 0.5f; - wynik *= stopPrzejezdNachylenie; - return (przejezdnoscZawsze) ? Math.max(minStopienPrzejezd, wynik) : wynik; - } - - /** - * Funkcja sprawdza, czy w danym kwadracie na danym, złożonym kierunku ruchu - * zadanym przez staryKier-nowyKierunek znajduje się przeszkoda. - * - * @param xStart współrzędna X kwadratu startowego przemieszczenia - * @param yStart współrzędna Y kwadratu startowego przemieszczenia - * @param staryKier stary kierunek ruchu - * @param nowyKierunek nowy kierunek ruchu - * @return true, jeśli jest przeszkoda w danym kwadracie na danym kierunku ruchu zadanym przez staryKier-nowyKierunek - */ - public static boolean jestPrzeszkodaNaKierunkuRuchu(int xStart, int yStart, EGeoDirection staryKier, EGeoDirection nowyKierunek) { - // Najpierw sprawdzenie, czy przechodząc po przekątnej nie przecinam przeszkody wodnej lub rowu prostopadłej do ruchu - // przechodzącej przez kwadraty sąsiednie bokami np. dla NORTHEAST -> NORTH i EAST - Kwadrat kwSasiedni; - boolean jestPrzeszkoda = false; - switch (nowyKierunek) { - case NORTHEAST: - kwSasiedni = getKwadrat(xStart, yStart + 1); - jestPrzeszkoda = kwSasiedni.jestPrzeszkodaWodna[EGeoDirection.SOUTHEAST.id]; - break; - case SOUTHEAST: - kwSasiedni = getKwadrat(xStart, yStart - 1); - jestPrzeszkoda = kwSasiedni.jestPrzeszkodaWodna[EGeoDirection.NORTHEAST.id]; - break; - case SOUTHWEST: - kwSasiedni = getKwadrat(xStart, yStart - 1); - jestPrzeszkoda = kwSasiedni.jestPrzeszkodaWodna[EGeoDirection.NORTHWEST.id]; - break; - case NORTHWEST: - kwSasiedni = getKwadrat(xStart, yStart + 1); - jestPrzeszkoda = kwSasiedni.jestPrzeszkodaWodna[EGeoDirection.SOUTHWEST.id]; - break; - default: - } - if (jestPrzeszkoda) { - return true; - } - Kwadrat kwStart = getKwadrat(xStart, yStart); - boolean[] przeszkodaWodna = kwStart.jestPrzeszkodaWodna; - boolean[] row = ROWY_DLA_PRZEJEZDNOSCI; - if (nowyKierunek == EGeoDirection.UNDEFINED) { - // przeszkoda - return true; - } - // zmieniam zwrot poprzedniego wektora ruchu, aby oba wektory wychodziły z tego samego punktu - staryKier = staryKier.oppositeDirect(); - if (staryKier == nowyKierunek) { - // brak przeszkody na drodze powrotnej - return false; - } - if (przeszkodaWodna[nowyKierunek.id] || row[nowyKierunek.id]) { - // przeszkoda na kierunku ruchu - return true; - } - if (staryKier == EGeoDirection.UNDEFINED) { - // brak przeszkody - return false; - } - EGeoDirection kierSasiedni = staryKier; - // sprawdzam kierunki sąsiędnie idąc zgodnie z ruchem wskazówek zegara - do { - kierSasiedni = kierSasiedni.rightNextDirect(); - if (przeszkodaWodna[kierSasiedni.id] || row[kierSasiedni.id]) { - // wychodzę z petli, aby sprawdzić kierunki sąsiędnie idąc przeciwnie do ruchu wskazówek zegara - break; - } - } while (kierSasiedni != nowyKierunek); - if (kierSasiedni == nowyKierunek) { - // brak przeszkody na kierunku ruchu - return false; - } - // sprawdzam kierunki sąsiędnie idąc przeciwnie do ruchu wskazówek zegara - kierSasiedni = staryKier; - do { - kierSasiedni = kierSasiedni.leftNextDirect(); - if (przeszkodaWodna[kierSasiedni.id] || row[kierSasiedni.id]) { - // przeszkoda na kierunku ruchu - return true; - } - } while (kierSasiedni != nowyKierunek); - // brak przeszkody - return false; - } - - /** - * Funkcja sprawdza, czy kwadrat przejezdny - * - * @param gridCoord testowany kwadrat - * @return true, jeśli jest przejezdny - */ - public static boolean czyKwadratPrzyjezdny(GridCoord gridCoord) { - return getStopienPrzejezdnosci(gridCoord, ERodzajPodwozia.GASIENICE) > 0.01; - } - private Teren() { } @@ -835,11 +485,6 @@ public class Teren { Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_zawodniony")); STOPIEN_PRZEJEZDNOSCI[ERodzajPodwozia.PLOZY.id][ERodzajTerenuPokrycie.TEREN_CZYSTY.id] = Float.parseFloat(MapConsts.ustawienia.getProperty("stopien_przejezdnosci.podwozie_plozy.teren_czysty")); - for (int i = 0; i < BIG_X_MAX; i++) { - for (int j = 0; j < BIG_Y_MAX; j++) { - bsSynch[i][j] = new Object(); - } - } } public static void main(String[] args) throws Exception { @@ -854,111 +499,18 @@ public class Teren { // Teren.normalizujDanePokrycia(); String dir = "C:/users/jrulka/Workspace/_data/new/"; -// Set fileNames = NMTDataProvider.listFiles("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(MapConsts.KWADRATY_DIR); + Teren.wygenerujNoweDane(fileNames, dir, 100); // Teren.wygenerujCzysteDane(100, false, false, false, false, true, false, false, false, false); - Teren.wygenerujNoweDane(dir, 20); // Teren.wygenerujCzysteDane(dir, 25, false, false, false, false, true, false, false, false, false); // Teren.wyzerujDane(); // Teren.zapisBuforaMapyDoPliku(); - // test zapisu i odczytu danych w formacie byte (dane są w kodzie uzupelnieniowym do dwóch tzn. -128..127) -// StringBuilder sb = new StringBuilder(100); -// sb.append(MapConsts.KWADRATY_DIR); -// sb.append("aaa.bin"); -// ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(sb.toString())); -// int hex = (int) (1.0f * 255.0f); -//// hex = (hex > 255) ? 255 : hex; -//// out.writeByte(hex); -// int hex1 = (int) (0.0f * 255.0f); -//// out.writeByte(hex1); -// int hex2 = (int) (0.99 * 255.0f); -// out.writeByte(0); -// out.writeByte(1); -// out.writeByte(20); -// out.writeByte(100); -// out.writeByte(5); -// out.writeByte(127); -// out.writeByte(128); -// out.close(); -// -// ObjectInputStream in = new ObjectInputStream(new FileInputStream(sb.toString())); -// hex = in.readByte(); -// hex1 = in.readByte(); -// hex2 = in.readByte(); -// hex2 = in.readByte(); -// hex2 = in.readByte(); -// hex2 = in.readByte(); -// byte b = in.readByte(); -// in.close(); - - -// WYZEROWANIE DROG W TERENIE -// for (int x = 14; x < 14 + 11; x++) { -// for (int dx = 0; dx < 4; dx++) { -// char cx = LITERALS.charAt(dx); -// for (int y = 139; y < 139 + 7; y++) { -// for (int dy = 0; dy < 6; dy++) { -// char cy = LITERALS.charAt(dy); -// String fn = String.format("%1$s%2$03d%3$c%4$03d%5$c", PATH, x, cx, y, cy); -// try { -// RightBigSquare bs = new RightBigSquare(fn); -// for (int i = 0; i < bs.kwadraty.length; i++) { -// for (int j = 0; j < bs.kwadraty[i].length; j++) { -// Kwadrat kw = bs.kwadraty[i][j]; -//// kw.jestDroga = new boolean[8]; -// kw.stopienZalesienia = 0; -// } -// } -// bs.liczbaZmian = 1; -// bs.updateFile(true); -// } catch (IOException e) { -//// e.printStackTrace(); -// } -// } -// } -// } -// } - -// try { -// RightBigSquare bs = new RightBigSquare("au2data/new_teren/Polska/kwadraty/50m/014A142D", true); -// -// bs.liczbaZmian = 1; -//// bs.updateFile(true, true); -// bs.writeFileBinary(true, 50); -// } catch (IOException e) { -//// e.printStackTrace(); -// } - - -// WYZEROWANIE WYBRANYCH DANYCH KWADRATOW I ZAPIS W PLIKU WYBRANYM FORMACIE I NAZWIE -// for (int x = 14; x < 14 + 11; x++) { -// for (int dx = 0; dx < 4; dx++) { -// char cx = LITERALS.charAt(dx); -// for (int y = 49; y < 49 + 7; y++) { -//// for (int y = 139; y < 139 + 7; y++) { -// for (int dy = 0; dy < 6; dy++) { -// char cy = LITERALS.charAt(dy); -// // NOWY FORMAT NAZWY PLIKU -//// String fn = String.format("%1$s%2$03d%3$s%4$02d%5$c", "E", x, cx + "_N", y, cy); -// // STARY FORMAT NAZWY PLIKU -// String fn = String.format("%1$03d%2$c%3$03d%4$c", x, cx, y + 90, cy); -// try { -// RightBigSquare.binary = false; -// RightBigSquare bs = new RightBigSquare(fn); -// // wyzerowanie tylko drog -// bs.resetSquares(false, false, false, false, true, false, false); -// bs.liczbaZmian = 1; -// // NOWY FORMAT NAZWY PLIKU -//// fn = String.format("%1$s%2$03d%3$s%4$02d%5$c", "E", x, cx + "_N", y, cy); -// RightBigSquare.binary = false; -// bs.updateFile(true, fn); -// } catch (IOException e) { -//// e.printStackTrace(); -// } -// } -// } -// } -// } } @@ -991,8 +543,8 @@ public class Teren { int maxY = MapConsts.SS_PER_BS_Y * MapConsts.BS_PER_DEG_Y * MapConsts.DY_REF; for (int x = 0; x < maxX; x++) { for (int y = 0; y < maxY; y++) { - Kwadrat kw = getKwadrat(x, y); - if (kw == EMPTY_SQUARE) { + Square kw = getKwadrat(x, y); + if (kw == EMPTY) { continue; } if (kw.stopienZawodnienia == 0 && kw.wysokoscSrednia == 0) { @@ -1007,8 +559,8 @@ public class Teren { } int xx = x + i; int yy = y + j; - Kwadrat kwSasiad = getKwadrat(xx, yy); - if (kwSasiad == EMPTY_SQUARE) { + Square kwSasiad = getKwadrat(xx, yy); + if (kwSasiad == EMPTY) { // pomijam kwadraty poza mapą continue; } @@ -1048,8 +600,8 @@ public class Teren { int maxY = MapConsts.SS_PER_BS_Y * MapConsts.BS_PER_DEG_Y * MapConsts.DY_REF; for (int x = 0; x < maxX; x++) { for (int y = 0; y < maxY; y++) { - Kwadrat kw = getKwadrat(x, y); - if (kw == EMPTY_SQUARE) { + Square kw = getKwadrat(x, y); + if (kw == EMPTY) { continue; } float suma = kw.stopienZalesienia + kw.stopienZawodnienia + kw.stopienZabudowy + kw.stopienZabagnienia; @@ -1081,23 +633,13 @@ public class Teren { * @param dir katalog z danymi terenowymi np. "d:/Workspace2/kwadraty/czyste-wysokosc/" * @param dlmk docelowy rozmiar generowanych kwadratów terenu */ - public static void wygenerujNoweDane(String dir, int dlmk) { + 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 - for (int x = 0; x < bigSquares.length; x++) { - for (int y = 0; y < bigSquares[x].length; y++) { - try { - BigSquare bs = loadArea(x, y); - if (bs instanceof RightBigSquare ) { - RightBigSquare rbs = (RightBigSquare) bs; - // wyzerowanie wszystkiego poza wysokością i różnicą wzniesień -// rbs.resetSquares(true, true, true, true, true, true, true, true, true); - rbs.saveNewFileWithNewScale(dir, dlmk); - } - } catch (IOException e) { - e.printStackTrace(); - } - } + for (String fileName : fileNames) { + RightBigSquare rbs = new RightBigSquare(fileName); + rbs.saveNewFileWithNewFormatZero(dir, dlmk); } + } } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/TerrainUtils.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/TerrainUtils.java index 3f73c6b..76cd537 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/TerrainUtils.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/TerrainUtils.java @@ -10,18 +10,30 @@ public class TerrainUtils { // ======================================================================== - public static float widocznoscOptyczna(float wysokoscObserwatora, float wysokoscCelu, - int x1, int y1, int x2, int y2) { + /** + * Wyznacza widoczność optyczną w linii prostej między zadanymi kwadratami. Widoczność jest cechą symetryczną + * względem badanych kwadratów. + *

Wersja metody z wykorzystaniem + * + * @param ho + * @param ht + * @param x1 + * @param y1 + * @param x2 + * @param y2 + * @return + */ + public static float widocznoscOptyczna(float ho, float ht, int x1, int y1, int x2, int y2) { if ((x1 == x2) && (y1 == y2)) { return 1.0f; } - Kwadrat kwDo = Teren.getKwadrat(x1, y1); - Kwadrat kwOd = Teren.getKwadrat(x2, y2); - if (kwDo == Kwadrat.EMPTY_SQUARE || kwOd == Kwadrat.EMPTY_SQUARE) { + Square kwDo = Teren.getKwadrat(x1, y1); + Square kwOd = Teren.getKwadrat(x2, y2); + if (kwDo == Square.EMPTY || kwOd == Square.EMPTY) { return 0.0f; } // roznica wysokosci miedzy skrajnymi kwadratami - float roznicaWysokosci = kwDo.wysokoscSrednia + wysokoscCelu - kwOd.wysokoscSrednia - wysokoscObserwatora; + float roznicaWysokosci = kwDo.wysokoscSrednia + ht - kwOd.wysokoscSrednia - ho; float wysBezwzgObserwatora; if (roznicaWysokosci < 0) { // sprawdzanie kwOd -> kwDo @@ -32,9 +44,9 @@ public class TerrainUtils { y1 = y2; y2 = swap; roznicaWysokosci = -roznicaWysokosci; - wysBezwzgObserwatora = kwDo.wysokoscSrednia + wysokoscCelu; + wysBezwzgObserwatora = kwDo.wysokoscSrednia + ht; } else { - wysBezwzgObserwatora = kwOd.wysokoscSrednia + wysokoscObserwatora; + wysBezwzgObserwatora = kwOd.wysokoscSrednia + ho; } GridCoord[] kwadratyNaOdcinku = Bresenham.generateSegment(x1, y1, x2, y2); float dlugoscOdcinka = GridCoord.odleglosc(x1, y1, x2, y2); @@ -45,7 +57,7 @@ public class TerrainUtils { // badanie wewnetrznych kwadratow nalezacych do odcinka, // czy nie sa powyzej linii widocznosci dla kwadratow skrajnych float wysokoscPrzeszkody = 0.0f; - Kwadrat kwAkt = Teren.getKwadrat(kwadratyNaOdcinku[i].x, kwadratyNaOdcinku[i].y); + Square kwAkt = Teren.getKwadrat(kwadratyNaOdcinku[i].x, kwadratyNaOdcinku[i].y); if (kwAkt.stopienZalesienia > 0.5f) { wysokoscPrzeszkody = 10.0f; } @@ -54,79 +66,34 @@ public class TerrainUtils { } // wyznaczenie roznicy wysokosci kwadratu badanego i docelowego // uwzgledniajac wysokosc obserwatora oraz wysokosc przeszkody - float roznWysAkt = kwAkt.wysokoscSrednia + wysokoscPrzeszkody - wysBezwzgObserwatora; - if (dh_max >= roznWysAkt) { + float dh = kwAkt.wysokoscSrednia + wysokoscPrzeszkody - wysBezwzgObserwatora; + if (dh_max >= dh) { continue; } float odleg = GridCoord.odleglosc(kwadratyNaOdcinku[i].x, kwadratyNaOdcinku[i].y, x1, y1); // float tangAlfa = roznWysAkt / odleg; // if (tangAlfa0 < tangAlfa) { - if (tangAlfa0 * odleg < roznWysAkt) { + if (tangAlfa0 * odleg < dh) { // wysokosc aktualnie badanego kwadratu jest powyzej/ponizej // linii poprowadzonej z kwadratu startowego do docelowego (z uwzglednieniem wysokosci obserwatora i celu) // odpowiednio dla katow dodatnich/ujemnych return 0.0f; } - dh_max = roznWysAkt; + dh_max = dh; } return 1.0f; } public static float widocznoscOptyczna(int x, int y) { - Kwadrat kw = Teren.getKwadrat(x, y); + Square kw = Teren.getKwadrat(x, y); if (kw.stopienZabudowy > 0.25f || kw.stopienZalesienia > 0.25f) { return 0.3f; } return 1.0f; } - public static float widocznoscOptyczna2(float wysokoscObserwatora, float wysokoscCelu, - int x1, int y1, int x2, int y2) { - if ((x1 == x2) && (y1 == y2)) { - return 1.0f; - } - Kwadrat kwDo = Teren.getKwadrat(x1, y1); - Kwadrat kwOd = Teren.getKwadrat(x2, y2); - if (kwDo == Kwadrat.EMPTY_SQUARE || kwOd == Kwadrat.EMPTY_SQUARE) { - return 0.0f; - } - // roznica wysokosci miedzy skrajnymi kwadratami - float roznicaWysokosci = kwDo.wysokoscSrednia + wysokoscCelu - kwOd.wysokoscSrednia - wysokoscObserwatora; - GridCoord[] kwadratyNaOdcinku = GeomUtils.kwadratyOdcinka(x1, y1, x2, y2); - float dlugoscOdcinka = GridCoord.odleglosc(x1, y1, x2, y2); - float tangAlfa0 = roznicaWysokosci / dlugoscOdcinka; - for (int i = 1; i < kwadratyNaOdcinku.length - 1; i++) { - // badanie wewnetrznych kwadratow nalezacych do odcinka, - // czy nie sa powyzej linii widocznosci dla kwadratow skrajnych - float wysokoscPrzeszkody = 0.0f; - Kwadrat kwAkt = Teren.getKwadrat(kwadratyNaOdcinku[i].x, kwadratyNaOdcinku[i].y); - if (kwAkt.stopienZalesienia > 0.5f) { - wysokoscPrzeszkody = 10.0f; - } - if (kwAkt.stopienZabudowy > 0.5f) { - wysokoscPrzeszkody = 10.0f; - } - // wyznaczenie roznicy wysokosci kwadratu badanego i docelowego - // uwzgledniajac wysokosc obserwatora oraz wysokosc przeszkody - float roznWysAkt = kwAkt.wysokoscSrednia + wysokoscPrzeszkody - kwOd.wysokoscSrednia - wysokoscObserwatora; - float odleg = GridCoord.odleglosc(kwadratyNaOdcinku[i].x, kwadratyNaOdcinku[i].y, x1, y1); - float tangAlfa = roznWysAkt / odleg; - if (tangAlfa0 < tangAlfa) { - // wysokosc aktualnie badanego kwadratu jest powyzej/ponizej - // linii poprowadzonej z kwadratu startowego do docelowego (z uwzglednieniem wysokosci obserwatora i celu) - // odpowiednio dla katow dodatnich/ujemnych - - return 0.0f; - } - } - if (kwDo.stopienZabudowy > 0.25f || kwDo.stopienZalesienia > 0.25f) { - return 0.3f; - } - return 1.0f; - } - public static float sredStopienWidoczOptycznej(float wysokoscObserwatora, float wysokoscCelu, GridCoord kwadratOd, int dl1, GridCoord kwadratDo, int dl2) { float stop = 0.0f; @@ -140,27 +107,4 @@ public class TerrainUtils { return stop; } - public static float sredStopienWidoczOptycznej2(float wysokoscObserwatora, float wysokoscCelu, - GridCoord kwadratOd, int dl1, GridCoord kwadratDo, int dl2) { - float stop = 0.0f; - for (int x1 = kwadratOd.x; x1 < kwadratOd.x + dl1; x1++) - for (int y1 = kwadratOd.y; y1 < kwadratOd.y + dl1; y1++) - for (int x2 = kwadratDo.x; x2 < kwadratDo.x + dl2; x2++) - for (int y2 = kwadratDo.y; y2 < kwadratDo.y + dl2; y2++) - stop += widocznoscOptyczna2(wysokoscObserwatora, wysokoscCelu, x1, y1, x2, y2); - - stop /= (dl1 * dl1 * dl2 * dl2); - return stop; - } - - public static float stopienPrzejezdnosciAktualOdcinkaDrogi(ArrayList droga, int pozycja, - EGeoDirection zkierunku, ERodzajPodwozia podwozie) { - if ((droga == null) || (droga.size() == 0) || (pozycja < 0) || (pozycja >= droga.size() - 1)) { - return 0.0f; - } - GridCoord idKw1 = droga.get(pozycja); - GridCoord idKw2 = droga.get(pozycja + 1); - return (float) Teren.getStopienPrzejezdnosci(idKw1.x, idKw1.y, idKw2.x, idKw2.y, zkierunku, podwozie); - } - } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/CoordTest.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/CoordTest.java new file mode 100644 index 0000000..e3dbe82 --- /dev/null +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/CoordTest.java @@ -0,0 +1,76 @@ +package pl.wat.ms4ds.terenfunkcje.konwersja; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import pl.wat.ms4ds.terenfunkcje.GeoCoord; + +public class CoordTest { + static Logger logger = LoggerFactory.getLogger(CoordTest.class); + + static void main() { + + + + logger.debug(" "); + + PUWGCoord puwgCoord = new PUWGCoord(); + GeoCoord geoCoord = new GeoCoord(); + geoCoord.lon = 19; + geoCoord.lat = 50; + CoordUtils.convertWGS84ToPUWG1992(geoCoord.lat, geoCoord.lon, puwgCoord); + logger.debug("Lat={}, Lon={} => PUWG (e,n)=({}, {})", geoCoord.lat, geoCoord.lon, puwgCoord.easting, puwgCoord.northing); + double e = puwgCoord.easting; + double n = puwgCoord.northing; + geoCoord.lon = 20; + geoCoord.lat = 51; + CoordUtils.convertWGS84ToPUWG1992(geoCoord.lat, geoCoord.lon, puwgCoord); + + double dx = puwgCoord.easting - e; + double dy = puwgCoord.northing - n; + + + logger.debug("Lat={}, Lon={} => PUWG (e,n)=({}, {})", geoCoord.lat, geoCoord.lon, puwgCoord.easting, puwgCoord.northing); + CoordUtils.convertPUWG1992ToWGS84(puwgCoord.northing, puwgCoord.easting, geoCoord); + logger.debug("PUWG (e,n)=({}, {}) => Lat={}, Lon={}", puwgCoord.easting, puwgCoord.northing, geoCoord.lat, geoCoord.lon); + +// coord.proj = 1; +// CoordUtils.convertWGS84ToPUWG(coord, geoCoord.lat, geoCoord.lon); +// logger.debug("Lat={}, Lon={}, PUWG (proj={}, e={}, n={})", geoCoord.lat, geoCoord.lon, coord.proj, coord.easting, coord.northing); +// CoordUtils.convertPuwg1992ToWgs84(coord, geoCoord); +// logger.debug("Lat={}, Lon={}, PUWG (proj={}, e={}, n={})", geoCoord.lat, geoCoord.lon, coord.proj, coord.easting, coord.northing); +// +// coord.proj = 2; +// CoordUtils.convertWGS84ToPUWG(coord, geoCoord.lat, geoCoord.lon); +// logger.debug("Lat={}, Lon={}, PUWG (proj={}, e={}, n={})", geoCoord.lat, geoCoord.lon, coord.proj, coord.easting, coord.northing); +// CoordUtils.convertPuwg2000ToWgs84(coord, geoCoord); +// logger.debug("Lat={}, Lon={}, PUWG (proj={}, e={}, n={})", geoCoord.lat, geoCoord.lon, coord.proj, coord.easting, coord.northing); +// 195828.000 673108.000 + +// puwgCoord.easting = 253974; +// puwgCoord.northing = 476879; + puwgCoord.easting = 500000; + puwgCoord.northing = 500000; + logger.debug("----------------------------------"); + CoordUtils.convertPUWG1992ToWGS84(puwgCoord.northing, puwgCoord.easting, geoCoord); + logger.debug("PUWG (e,n)=({}, {}) => Lat={}, Lon={}", puwgCoord.easting, puwgCoord.northing, geoCoord.lat, geoCoord.lon); + CoordUtils.convertWGS84ToPUWG1992(geoCoord.lat, geoCoord.lon, puwgCoord); + logger.debug("Lat={}, Lon={} => PUWG (e,n)=({}, {})", geoCoord.lat, geoCoord.lon, puwgCoord.easting, puwgCoord.northing); + + + puwgCoord.easting = 100000; + puwgCoord.northing = 470642; + CoordUtils.convertPUWG1992ToWGS84(puwgCoord.northing, puwgCoord.easting, geoCoord); + logger.debug("PUWG (e,n)=({}, {}) => Lat={}, Lon={}", puwgCoord.easting, puwgCoord.northing, geoCoord.lat, geoCoord.lon); + CoordUtils.convertWGS84ToPUWG1992(geoCoord.lat, geoCoord.lon, puwgCoord); + logger.debug("Lat={}, Lon={} => PUWG (e,n)=({}, {})", geoCoord.lat, geoCoord.lon, puwgCoord.easting, puwgCoord.northing); + + puwgCoord.easting = 821310; + puwgCoord.northing = 369750; + CoordUtils.convertPUWG1992ToWGS84(puwgCoord.northing, puwgCoord.easting, geoCoord); + logger.debug("PUWG (e,n)=({}, {}) => Lat={}, Lon={}", puwgCoord.easting, puwgCoord.northing, geoCoord.lat, geoCoord.lon); + CoordUtils.convertWGS84ToPUWG1992(geoCoord.lat, geoCoord.lon, puwgCoord); + logger.debug("Lat={}, Lon={} => PUWG (e,n)=({}, {})", geoCoord.lat, geoCoord.lon, puwgCoord.easting, puwgCoord.northing); + + + } +} diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/CoordUtils.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/CoordUtils.java index 5075726..ed5f52f 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/CoordUtils.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/CoordUtils.java @@ -2,10 +2,11 @@ package pl.wat.ms4ds.terenfunkcje.konwersja; import pl.wat.ms4ds.terenfunkcje.GeoCoord; import pl.wat.ms4ds.terenfunkcje.GridCoord; -import pl.wat.ms4ds.terenfunkcje.Kwadrat; +import pl.wat.ms4ds.terenfunkcje.Square; import pl.wat.ms4ds.terenfunkcje.Teren; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; @@ -25,7 +26,8 @@ public class CoordUtils { public static void main(String[] args) throws Exception { - HashMap daneWysokHashMap = new HashMap(); + + HashMap daneWysokHashMap = new HashMap(); if (args.length > 0) { dataDir = args[0]; } @@ -33,9 +35,9 @@ public class CoordUtils { String nmt_fn = args[i]; daneWysokHashMap.clear(); readData(nmt_fn, daneWysokHashMap); - for (DaneWysok daneWysok : daneWysokHashMap.values()) { - Kwadrat kw = Teren.getKwadrat(daneWysok.idKw.x, daneWysok.idKw.y); - kw.setWysokoscSrednia((int) (daneWysok.suma / daneWysok.licz + 0.5)); + for (NMTData daneWysok : daneWysokHashMap.values()) { +// Square kw = Teren.getKwadrat(daneWysok.idKw.x, daneWysok.idKw.y); +// kw.setWysokoscSrednia((int) (daneWysok.suma / daneWysok.licz + 0.5)); } logger.debug("Poczatek zapisu danych dla regionu " + nmt_fn + " >> " + i + "/" + (args.length - 1)); Teren.zapisBuforaMapyDoPliku(); @@ -62,7 +64,7 @@ public class CoordUtils { } - private static void readData(String fileName, HashMap daneWysokHashMap) throws IOException { + private static void readData(String fileName, HashMap daneWysokHashMap) throws IOException { try { StringBuilder sb = new StringBuilder(100); sb.append(dataDir); @@ -103,11 +105,11 @@ public class CoordUtils { } catch (NumberFormatException e) { logger.warn("Bledne dane w pliku: " + fileName); } - convertPuwgToLatLon(puwgCoord, latLon); + convertPUWG1992ToWGS84(puwgCoord.northing, puwgCoord.easting, latLon); GridCoord idKw = new GridCoord(latLon.lon, latLon.lat); - DaneWysok daneWysok = daneWysokHashMap.get(idKw); + NMTData daneWysok = daneWysokHashMap.get(idKw); if (daneWysok == null) { - daneWysok = new DaneWysok(idKw, wysokosc, 1); + daneWysok = new NMTData(idKw, wysokosc, 1); daneWysokHashMap.put(idKw, daneWysok); } else { daneWysok.suma += wysokosc; @@ -127,327 +129,83 @@ public class CoordUtils { } } - private static final double fe = 500000.0; - - //Deklaracja tablicy stref rownoleżnikowych - private static final char[] cArray = {'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', - 'S', 'T', 'U', 'V', 'W', 'X'}; -// private static final String LITERALS = "CDEFGHJKLMNPQRSTUVWX"; - -//------------------------------------------------------------------------------ -//////////////////////////////////////////////////////////////////////////////// -//Funkcje pomocnicze - - /// ///////////////////////////////////////////////////////////////////////////// -//------------------------------------------------------------------------------ - static double calculateESquared(double a, double b) { - a *= a; - b *= b; - return (a - b) / a; -// return ((a * a) - (b * b)) / (a * a); - } - - static double calculateE2Squared(double a, double b) { - a *= a; - b *= b; - return (a - b) / b; -// return ((a * a) - (b * b)) / (b * b); - } - - static double denom(double es, double sphi) { - double sinSphi = Math.sin(sphi); - return Math.sqrt(1.0 - es * (sinSphi * sinSphi)); - } - - static double sphsr(double a, double es, double sphi) { - double dn = denom(es, sphi); - return a * (1.0 - es) / (dn * dn * dn); - } - - static double sphsn(double a, double es, double sphi) { - double sinSphi = Math.sin(sphi); - return a / Math.sqrt(1.0 - es * (sinSphi * sinSphi)); - } - - static double sphtmd(double ap, double bp, double cp, double dp, double ep, double sphi) { - return (ap * sphi) - (bp * Math.sin(2.0 * sphi)) + (cp * Math.sin(4.0 * sphi)) - - (dp * Math.sin(6.0 * sphi)) + (ep * Math.sin(8.0 * sphi)); - } - - //======================================================================= -// Funkcja służy do konwersji współrzednych elipsoidalnych B, L (lat/lon) WGS84 na płaskie X-northing, Y-easting odwzorowania kartograficznego UTM -//======================================================================= -// Argumenty wejściowe i wyjściowe: -// -------------------------------- -// int& utmXZone: nr strefy UTM wg. podziału południkowego (zwracane numery od 1 do 60, każda strefa ma sześć stopni) -// char& utmYZone: nr strefy wg. podziału równoleżnikowego (zwracane wartości: CDEFGHJKLMNPQRSTUVWX) -// double& easting: współrzędna Y UTM, w metrach po konwersji [metry] -// double& northing: współrzędna X UTM, w metrach po konwersji [metry] -// double lat, double lon: współrzędne lat/lon do konwersji [stopnie] -//======================================================================= - /** + * Funkcja służy do konwersji współrzednych elipsoidalnych WGS84 (lat/lon) na płaskie X-northing, Y-easting + * odwzorowania kartograficznego 1992. * - * @param lat współrzędna lat (szerokość geograficzna) do konwersji [stopnie] (układ WGS84) - * @param lon współrzędna lon (długość geograficzna) do konwersji [stopnie] (układ WGS84) - * @param utmCoord współrzędne UTM + * @param puwgCoord współrzędne PUWG1992 (easting, northing) [metry] + * @param lat szerokość geograficzna WSG-84 [stopnie dziesiętnie] + * @param lon długość geograficzna WSG-84 [stopnie dziesiętnie] */ - public static void convertLatLonToUtm(double lat, double lon, UTMCoord utmCoord) { - // Współczynnik zniekształcenia skali w południku osiowym - double tmd; - double nfn; - if (lon <= 0.0) { - utmCoord.xZone = 30 + (int) (lon / 6.0); - } else { - utmCoord.xZone = 31 + (int) (lon / 6.0); - } - if (lat < 84.0 && lat >= 72.0) { - // Specjalne zatrzymanie: strefa X ma 12 stopni od północy do południa, nie 8 - utmCoord.yZone = cArray[19]; - } else { - utmCoord.yZone = cArray[(int) ((lat + 80.0) / 8.0)]; - } - if (lat >= 84.0 || lat < -80.0) { - // Błędna wartość szerokości geograficznej (zwracany znak gwiazdki) - utmCoord.yZone = '*'; - } - double latRad = lat * DEG_2_RAD; - double lonRad = lon * DEG_2_RAD; - double olam = (utmCoord.xZone * 6 - 183) * DEG_2_RAD; - double dlam = lonRad - olam; - double s = Math.sin(latRad); - double c = Math.cos(latRad); - double t = s / c; - double eta = e2Squared * (c * c); - double sn = sphsn(a, eSquared, latRad); - tmd = sphtmd(ap, bp, cp, dp, ep, latRad); - double t1, t2, t3, t4, t5, t6, t7, t8, t9; - t1 = tmd * ok; - t2 = sn * s * c * ok / 2.0; - t3 = sn * s * (c * c * c) * ok * (5.0 - (t * t) + 9.0 * eta + 4.0 * (eta * eta)) / 24.0; - t4 = sn * s * (c * c * c * c * c) * ok * (61.0 - 58.0 * (t * t) + (t * t * t * t) + 270.0 * eta - 330.0 * (t * t) * eta + 445.0 * (eta * eta) + 324.0 * (eta * eta * eta) - 680.0 * (t * t) * (eta * eta) + 88.0 * (eta * eta * eta * eta) - 600.0 * (t * t) * (eta * eta * eta) - 192.0 * (t * t) * (eta * eta * eta * eta)) / 720.0; - t5 = sn * s * (c * c * c * c * c * c * c) * ok * (1385.0 - 3111.0 * (t * t) + 543.0 * (t * t * t * t) - (t * t * t * t * t * t)) / 40320.0; - if (latRad < 0.0) nfn = 10000000.0; - else nfn = 0; - utmCoord.northing = nfn + t1 + (dlam * dlam) * t2 + (dlam * dlam * dlam * dlam) * t3 + (dlam * dlam * dlam * dlam * dlam * dlam) * t4 + (dlam * dlam * dlam * dlam * dlam * dlam * dlam * dlam) * t5; - t6 = sn * c * ok; - t7 = sn * (c * c * c) * ok * (1.0 - (t * t) + eta) / 6.0; - t8 = sn * (c * c * c * c * c) * ok * (5.0 - 18.0 * (t * t) + (t * t * t * t) + 14.0 * eta - 58.0 * (t * t) * eta + 13.0 * (eta * eta) + 4.0 * (eta * eta * eta) - 64.0 * (t * t) * (eta * eta) - 24.0 * (t * t) * (eta * eta * eta)) / 120.0; - t9 = sn * (c * c * c * c * c * c * c) * ok * (61.0 - 479.0 * (t * t) + 179.0 * (t * t * t * t) - (t * t * t * t * t * t)) / 5040.0; - utmCoord.easting = fe + dlam * t6 + (dlam * dlam * dlam) * t7 + (dlam * dlam * dlam * dlam * dlam) * t8 + (dlam * dlam * dlam * dlam * dlam * dlam * dlam) * t9; - if (utmCoord.northing >= 9999999.0) utmCoord.northing = 9999999.0; - } - - //======================================================================= -// Funkcja służy do konwersji współrzednych elipsoidalnych WGS84 B, L (lat/lon) na płaskie X-northing, Y-easting odwzorowania kartograficznego 1992 i 2000 -//======================================================================= -// -------------------------------- -// int& utmXZone: nr strefy UTM wg. podziału południkowego (zwracane numery od 1 do 60, każda strefa ma sześć stopni) -// char& utmYZone: nr strefy wg. podziału równoleżnikowego (zwracane wartości: CDEFGHJKLMNPQRSTUVWX) -// double& easting: współrzędna Y UTM, w metrach po konwersji [metry] -// double& northing: współrzędna X UTM, w metrach po konwersji [metry] -// double lat, double lon: współrzędne lat/lon do konwersji [stopnie] -// int proj: odwzorowanie kartograficzne (proj = 1 odpowiada odwzorowaniu 1992, natomiast każda inna odwzorowaniu 2000) -//======================================================================= - public static void convertLatLonToPUWG(PUWGCoord puwgCoord, double lat, double lon) { - // Współczynnik zniekształcenia skli mapy w południku osiowym dla odwzorowania kartograficznego 2000 - //Współczynnik zniekształcenia skli mapy w południku osiowym dla odwzorowania kartograficznego 1992 - double ok_new = (puwgCoord.proj != 1) ? 0.999923 : 0.9993; - double olam = 0.0; - double tmd; - double nfn; - double strf = 0.0; + public static void convertWGS84ToPUWG1992(double lat, double lon, PUWGCoord puwgCoord) { if (lon < 13.5 || lon > 25.5) { - //Błędna wartość długości geograficznej (zwracana wartość 99999999999999) + //Błędna wartość długości geograficznej (zwracana wartość 999999999999999) puwgCoord.easting = 999999999999999.0; puwgCoord.northing = 999999999999999.0; return; - } else { - if (puwgCoord.proj == 1) { - olam = 19.0 * DEG_2_RAD; - strf = 0.0; - nfn = -5300000.0; - } else { - nfn = 0; - if (lon >= 13.5 && lon < 16.5) { - olam = 15.0 * DEG_2_RAD; - strf = 5000000.0; - } - - if (lon >= 16.5 && lon < 19.5) { - olam = 18.0 * DEG_2_RAD; - strf = 6000000.0; - } - - if (lon >= 19.5 && lon < 22.5) { - olam = 21.0 * DEG_2_RAD; - strf = 7000000.0; - } - - if (lon >= 22.5 && lon < 25.5) { - olam = 24.0 * DEG_2_RAD; - strf = 8000000.0; - } - } } double latRad = lat * DEG_2_RAD; - double lonRad = lon * DEG_2_RAD; - double dlam = lonRad - olam; + double dlam = (lon - 19.0) * DEG_2_RAD; + double dlam_pow_2 = dlam * dlam; + double dlam_pow_3 = dlam_pow_2 * dlam; + double dlam_pow_4 = dlam_pow_3 * dlam; double s = Math.sin(latRad); double c = Math.cos(latRad); + double c_pow_2 = c * c; + double c_pow_3 = c_pow_2 * c; + double c_pow_4 = c_pow_3 * c; double t = s / c; - double eta = e2Squared * (c * c); - double sn = sphsn(a, eSquared, latRad); - tmd = sphtmd(ap, bp, cp, dp, ep, latRad); - double t1, t2, t3, t4, t5, t6, t7, t8, t9; - t1 = tmd * ok_new; - t2 = sn * s * c * ok_new / 2.0; - t3 = sn * s * (c * c * c) * ok_new * (5.0 - (t * t) + 9.0 * eta + 4.0 * (eta * eta)) / 24.0; - t4 = sn * s * (c * c * c * c * c) * ok_new * (61.0 - 58.0 * (t * t) + (t * t * t * t) + 270.0 * eta - 330.0 * (t * t) * eta + 445.0 * (eta * eta) + 324.0 * (eta * eta * eta) - 680.0 * (t * t) * (eta * eta) + 88.0 * (eta * eta * eta * eta) - 600.0 * (t * t) * (eta * eta * eta) - 192.0 * (t * t) * (eta * eta * eta * eta)) / 720.0; - t5 = sn * s * (c * c * c * c * c * c * c) * ok_new * (1385.0 - 3111.0 * (t * t) + 543.0 * (t * t * t * t) - (t * t * t * t * t * t)) / 40320.0; - puwgCoord.northing = nfn + t1 + (dlam * dlam) * t2 + (dlam * dlam * dlam * dlam) * t3 + (dlam * dlam * dlam * dlam * dlam * dlam) * t4 + (dlam * dlam * dlam * dlam * dlam * dlam * dlam * dlam) * t5; - t6 = sn * c * ok_new; - t7 = sn * (c * c * c) * ok_new * (1.0 - (t * t) + eta) / 6.0; - t8 = sn * (c * c * c * c * c) * ok_new * (5.0 - 18.0 * (t * t) + (t * t * t * t) + 14.0 * eta - 58.0 * (t * t) * eta + 13.0 * (eta * eta) + 4.0 * (eta * eta * eta) - 64.0 * (t * t) * (eta * eta) - 24.0 * (t * t) * (eta * eta * eta)) / 120.0; - t9 = sn * (c * c * c * c * c * c * c) * ok_new * (61.0 - 479.0 * (t * t) + 179.0 * (t * t * t * t) - (t * t * t * t * t * t)) / 5040.0; - puwgCoord.easting = fe + strf + dlam * t6 + (dlam * dlam * dlam) * t7 + (dlam * dlam * dlam * dlam * dlam) * t8 + (dlam * dlam * dlam * dlam * dlam * dlam * dlam) * t9;// + 0.5; + double t_pow_2 = t * t; + double t_pow_3 = t_pow_2 * t; + double t_pow_4 = t_pow_3 * t; + double t_pow_5 = t_pow_4 * t; + double eta = E2_SQUARED * c_pow_2; + double eta_pow_2 = eta * eta; + double eta_pow_3 = eta_pow_2 * eta; + double eta_pow_4 = eta_pow_3 * eta; + double sn = sphsn(latRad); + double tmd = sphtmd(latRad); + double t1, t2, t3, t4, t5; + t1 = tmd * OK; + double sns = sn * s; + t2 = sns * c * OK / 2.0; + t3 = sns * c_pow_3 * OK * (5.0 - t_pow_2 + 9.0 * eta + 4.0 * eta_pow_2) / 24.0; + t4 = sns * c_pow_4 * c * OK * (61.0 - 58.0 * t_pow_2 + t_pow_4 + + 270.0 * eta - 330.0 * t_pow_2 * eta + 445.0 * eta_pow_2 + + 324.0 * eta_pow_3 - 680.0 * t_pow_2 * eta_pow_2 + + 88.0 * eta_pow_4 - 600.0 * t_pow_2 * eta_pow_3 - 192.0 * t_pow_2 * eta_pow_4) / 720.0; + t5 = sns * c_pow_4 * c_pow_3 * OK * (1385.0 - 3111.0 * t_pow_2 + + 543.0 * t_pow_4 - t_pow_5 * t) / 40320.0; + puwgCoord.northing = -5300000.0 + t1 + dlam_pow_2 * t2 + dlam_pow_4 * t3 + + dlam_pow_4 * dlam_pow_2 * t4 + dlam_pow_4 * dlam_pow_4 * t5; + t1 = sn * c * OK; + t2 = sn * c_pow_3 * OK * (1.0 - t_pow_2 + eta) / 6.0; + t3 = sn * c_pow_4 * c * OK * (5.0 - 18.0 * t_pow_2 + t_pow_4 + 14.0 * eta + - 58.0 * t_pow_2 * eta + 13.0 * eta_pow_2 + 4.0 * eta_pow_3 + - 64.0 * t_pow_2 * eta_pow_2 - 24.0 * t_pow_2 * eta_pow_3) / 120.0; + t4 = sn * c_pow_4 * c_pow_3 * OK * (61.0 - 479.0 * t_pow_2 + 179.0 * t_pow_4 - t_pow_5 * t) / 5040.0; + puwgCoord.easting = 500000.0 + dlam * t1 + dlam_pow_3 * t2 + + dlam_pow_4 * dlam * t3 + dlam_pow_4 * dlam_pow_3 * t4;// + 0.5; } - - //======================================================================= -// Funkcja do konwersji współrzędnych płaskich X/Y UTM na elipsoidalne lat/lon (dla dowolnej elipsoidy) -//======================================================================= -// Wymagania: -// ------------------------------------- -// utmXZone musi być wartością w garanicach od 1 do 60 -// utmYZone musi być jedną z liter: CDEFGHJKLMNPQRSTUVWX -// Argumenty wejściowe i wyjściowe: -// ------------------------------------ -// double a: długość dużej półosi, w metrach (np. dla elipsoidy WGS 84, 6378137.0) -// double f: spłaszczenie elipsoidalne (np. dla elipsoidy WGS 84, 1 / 298.257223563) -// int utmXZone: nr strefy UTM wg. podziału południkowego (zwracane numery od 1 do 60, każda strefa ma sześć stopni) -// char utmYZone: nr strefy wg. podziału równoleżnikowego (zwracane wartości: CDEFGHJKLMNPQRSTUVWX) -// double easting, double northing: współrzędna X, Y UTM do konwersji [metry] -// double& lat, double& lon: współrzędne elipsoidalne lat/lon po konwersji [stopnie] -//======================================================================= - public static void convertUtmToLatLon(UTMCoord utmCoord, GeoCoord geoCoord) { - double nfn; - utmCoord.yZone = Character.toUpperCase(utmCoord.yZone); - if (utmCoord.yZone <= 'M' && utmCoord.yZone >= 'C') { - nfn = 10000000.0; - } else { - nfn = 0; - } - double tmd = (utmCoord.northing - nfn) / ok; - double sr = sphsr(a, eSquared, 0.0); - double ftphi = tmd / sr; - double t10, t11, t12, t13, t14, t15, t16, t17; - for (int i = 0; i < 5; i++) { - t10 = sphtmd(ap, bp, cp, dp, ep, ftphi); - sr = sphsr(a, eSquared, ftphi); - ftphi = ftphi + (tmd - t10) / sr; - } - sr = sphsr(a, eSquared, ftphi); - double sn = sphsn(a, eSquared, ftphi); - double s = Math.sin(ftphi); - double c = Math.cos(ftphi); - double t = s / c; - double eta = e2Squared * (c * c); - double de = utmCoord.easting - fe; - t10 = t / (2.0 * sr * sn * (ok * ok)); - t11 = t * (5.0 + 3.0 * (t * t) + eta - 4.0 * (eta * eta) - 9.0 * (t * t) * eta) / (24.0 * sr * (sn * sn * sn) * (ok * ok * ok * ok)); - t12 = t * (61.0 + 90.0 * (t * t) + 46.0 * eta + 45.0 * (t * t * t * t) - 252.0 * (t * t) * eta - 3.0 * (eta * eta) + 100.0 * (eta * eta * eta) - 66.0 * (t * t) * (eta * eta) - 90.0 * (t * t * t * t) * eta + 88.0 * (eta * eta * eta * eta) + 225.0 * (t * t * t * t) * (eta * eta) + 84.0 * (t * t) * (eta * eta * eta) - 192.0 * (t * t) * (eta * eta * eta * eta)) / (720.0 * sr * (sn * sn * sn * sn * sn) * (ok * ok * ok * ok * ok * ok)); - t13 = t * (1385.0 + 3633 * (t * t) + 4095.0 * (t * t * t * t) + 1575.0 * (t * t * t * t * t * t)) / (40320 * sr * (sn * sn * sn * sn * sn * sn * sn) * (ok * ok * ok * ok * ok * ok * ok * ok)); - geoCoord.lat = ftphi - (de * de) * t10 + (de * de * de * de) * t11 - (de * de * de * de * de * de) * t12 + (de * de * de * de * de * de * de * de) * t13; - t14 = 1.0 / (sn * c * ok); - t15 = (1.0 + 2.0 * (t * t) + eta) / (6.0 * (sn * sn * sn) * c * (ok * ok * ok)); - t16 = 1.0 * (5.0 + 6.0 * eta + 28.0 * (t * t) - 3.0 * (eta * eta) + 8.0 * (t * t) * eta + 24.0 * (t * t * t * t) - 4.0 * (eta * eta * eta) + 4.0 * (t * t) * (eta * eta) + 24.0 * (t * t) * (eta * eta * eta)) / (120.0 * (sn * sn * sn * sn * sn) * c * (ok * ok * ok * ok * ok)); - t17 = 1.0 * (61.0 + 662.0 * (t * t) + 1320.0 * (t * t * t * t) + 720.0 * (t * t * t * t * t * t)) / (5040.0 * (sn * sn * sn * sn * sn * sn * sn) * c * (ok * ok * ok * ok * ok * ok * ok)); - double dlam = de * t14 - (de * de * de) * t15 + (de * de * de * de * de) * t16 - (de * de * de * de * de * de * de) * t17; - double olam = (utmCoord.xZone * 6 - 183.0) * DEG_2_RAD; - geoCoord.lon = olam + dlam; - geoCoord.lon *= RAD_2_DEG; - geoCoord.lat *= RAD_2_DEG; - } - - - // Współczynnik zniekształcenia skali mapy w południku osiowym dla odwzorowania kartograficznego UTM - private static final double ok = 0.9996; - private static final double DEG_2_RAD = Math.PI / 180.0; - private static final double RAD_2_DEG = 180.0 / Math.PI; /** - * double a: dlługość dużej półsi, w metrach dla elipsoidy WGS-84, 6378137.0 - */ - private static final double a = 6378137.0; - - private static final double recf = 298.257223563; - /** - * double f: spłaszczenie elipsoidalne dla elipsoidy WGS-84, 1 / 298.257223563 - */ - private static final double f = 1.0 / recf; - // private static final double b = a * (recf - 1) / recf; - private static final double b = a * (1.0 - f); - private static final double eSquared = calculateESquared(a, b); - private static final double e2Squared = calculateE2Squared(a, b); - private static final double tn = (a - b) / (a + b); - private static final double ap = a * (1.0 - tn + 5.0 * ((tn * tn) - (tn * tn * tn)) / 4.0 + 81.0 * ((tn * tn * tn * tn) - (tn * tn * tn * tn * tn)) / 64.0); - private static final double bp = 3.0 * a * (tn - (tn * tn) + 7.0 * ((tn * tn * tn) - (tn * tn * tn * tn)) / 8.0 + 55.0 * (tn * tn * tn * tn * tn) / 64.0) / 2.0; - private static final double cp = 15.0 * a * ((tn * tn) - (tn * tn * tn) + 3.0 * ((tn * tn * tn * tn) - (tn * tn * tn * tn * tn)) / 4.0) / 16.0; - private static final double dp = 35.0 * a * ((tn * tn * tn) - (tn * tn * tn * tn) + 11.0 * (tn * tn * tn * tn * tn) / 16.0) / 48.0; - private static final double ep = 315.0 * a * ((tn * tn * tn * tn) - (tn * tn * tn * tn * tn)) / 512.0; - - /** - * Funkcja do konwersji współrzędnych płaskich X/Y odwzorowania kartograficznego 1992 i 2000 na elipsoidalne lat/lon elipsoide WGS84. + * Funkcja do konwersji współrzędnych płaskich X/Y odwzorowania kartograficznego 1992 na elipsoidalne lat/lon elipsoide WGS84. *

* PUWGCoord.proj: odwzorowanie kartograficzne (proj = 1 odpowiada odwzorowaniu 1992, natomiast każda inna odwzorowaniu 2000) * - * @param puwgCoord współrzędne odwzorowania kartograficznego PUWG-1992 lub PUWG-2000 do konwersji [metry] + * @param northing współrzędne na osi OY odwzorowania kartograficznego PUWG-1992 do konwersji [metry] + * @param easting współrzędne na osi OX odwzorowania kartograficznego PUWG-1992 do konwersji [metry] * @param geoCoord współrzędne geograficzne odwzorowania WGS-84 po konwersji [stopnie] */ - public static void convertPuwgToLatLon(PUWGCoord puwgCoord, GeoCoord geoCoord) { - double ok = (puwgCoord.proj != 1) ? 0.999923 : 0.9993; - double nfn; - double tmd; - double ftphi; - double eta; - double dlam; - double olam = 0.0; - double strf = 0.0; - - if (puwgCoord.proj == 1) { - olam = 19.0 * DEG_2_RAD; - strf = 0.0; - nfn = -5300000.0; - } else { - nfn = 0; - if (puwgCoord.easting < 6000000.0 && puwgCoord.easting > 5000000.0) { - strf = 5000000.0; - olam = 15.0 * DEG_2_RAD; - } - if (puwgCoord.easting < 7000000.0 && puwgCoord.easting > 6000000.0) { - strf = 6000000.0; - olam = 18.0 * DEG_2_RAD; - } - if (puwgCoord.easting < 8000000.0 && puwgCoord.easting > 7000000.0) { - strf = 7000000.0; - olam = 21.0 * DEG_2_RAD; - } - if (puwgCoord.easting < 9000000.0 && puwgCoord.easting > 8000000.0) { - strf = 8000000.0; - olam = 24.0 * DEG_2_RAD; - } - } - tmd = (puwgCoord.northing - nfn) / ok; - double sr = sphsr(a, eSquared, 0.0); - ftphi = tmd / sr; - double t10, t11, t12, t13, t14, t15, t16, t17; + public static void convertPUWG1992ToWGS84(double northing, double easting, GeoCoord geoCoord) { + double tmd = (northing + 5300000.0) / OK; + double sr = sphsr(0.0); + double ftphi = tmd / sr; for (int i = 0; i < 5; i++) { - t10 = sphtmd(ap, bp, cp, dp, ep, ftphi); - sr = sphsr(a, eSquared, ftphi); - ftphi = ftphi + (tmd - t10) / sr; + ftphi += (tmd - sphtmd(ftphi)) / sphsr(ftphi); } - sr = sphsr(a, eSquared, ftphi); - double sn = sphsn(a, eSquared, ftphi); + sr = sphsr(ftphi); + double sn = sphsn(ftphi); double sn_pow_2 = sn * sn; double sn_pow_3 = sn_pow_2 * sn; double sn_pow_4 = sn_pow_3 * sn; @@ -459,27 +217,106 @@ public class CoordUtils { double t_pow_2 = t * t; double t_pow_4 = t_pow_2 * t_pow_2; double t_pow_6 = t_pow_4 * t_pow_2; - eta = e2Squared * (c * c); + double eta = E2_SQUARED * (c * c); double eta_pow_2 = eta * eta; double eta_pow_3 = eta_pow_2 * eta; double eta_pow_4 = eta_pow_2 * eta_pow_2; - double de = puwgCoord.easting - fe - strf; + double de = easting - 500000.0; double de_pow_2 = de * de; double de_pow_3 = de_pow_2 * de; double de_pow_4 = de_pow_3 * de; - t10 = t / (2.0 * sr * sn * (ok * ok)); - t11 = t * (5.0 + 3.0 * t_pow_2 + eta - 4.0 * eta_pow_2 - 9.0 * t_pow_2 * eta) / (24.0 * sr * sn_pow_3 * (ok * ok * ok * ok)); - t12 = t * (61.0 + 90.0 * t_pow_2 + 46.0 * eta + 45.0 * t_pow_4 - 252.0 * t_pow_2 * eta - 3.0 * eta_pow_2 + 100.0 * eta_pow_3 - 66.0 * t_pow_2 * eta_pow_2 - 90.0 * t_pow_4 * eta + 88.0 * eta_pow_4 + 225.0 * t_pow_4 * eta_pow_2 + 84.0 * t_pow_2 * eta_pow_3 - 192.0 * t_pow_2 * eta_pow_4) / (720.0 * sr * sn_pow_5 * (ok * ok * ok * ok * ok * ok)); - t13 = t * (1385.0 + 3633 * t_pow_2 + 4095.0 * t_pow_4 + 1575.0 * t_pow_6) / (40320 * sr * sn_pow_7 * (ok * ok * ok * ok * ok * ok * ok * ok)); - geoCoord.lat = ftphi - de_pow_2 * t10 + de_pow_4 * t11 - de_pow_3 * de_pow_3 * t12 + de_pow_4 * de_pow_3 * t13; - t14 = 1.0 / (sn * c * ok); - t15 = (1.0 + 2.0 * t_pow_2 + eta) / (6.0 * sn_pow_3 * c * (ok * ok * ok)); - t16 = 1.0 * (5.0 + 6.0 * eta + 28.0 * t_pow_2 - 3.0 * eta_pow_2 + 8.0 * t_pow_2 * eta + 24.0 * t_pow_4 - 4.0 * eta_pow_3 + 4.0 * t_pow_2 * eta_pow_2 + 24.0 * t_pow_2 * eta_pow_3) / (120.0 * sn_pow_5 * c * (ok * ok * ok * ok * ok)); - t17 = 1.0 * (61.0 + 662.0 * t_pow_2 + 1320.0 * t_pow_4 + 720.0 * t_pow_6) / (5040.0 * sn_pow_7 * c * (ok * ok * ok * ok * ok * ok * ok)); - dlam = de * t14 - de_pow_3 * t15 + de_pow_3 * de_pow_2 * t16 - de_pow_3 * de_pow_4 * t17; - geoCoord.lon = olam + dlam; - geoCoord.lon *= RAD_2_DEG; + double t0, t1, t2, t3; + t0 = t / (2.0 * sr * sn * OK_POW_2); + t1 = t * (5.0 + 3.0 * t_pow_2 + eta - 4.0 * eta_pow_2 - 9.0 * t_pow_2 * eta) / (24.0 * sr * sn_pow_3 * OK_POW_4); + t2 = t * (61.0 + 90.0 * t_pow_2 + 46.0 * eta + 45.0 * t_pow_4 - 252.0 * t_pow_2 * eta - 3.0 * eta_pow_2 + + 100.0 * eta_pow_3 - 66.0 * t_pow_2 * eta_pow_2 - 90.0 * t_pow_4 * eta + 88.0 * eta_pow_4 + + 225.0 * t_pow_4 * eta_pow_2 + 84.0 * t_pow_2 * eta_pow_3 - 192.0 * t_pow_2 * eta_pow_4) / (720.0 * sr * sn_pow_5 * OK_POW_6); + t3 = t * (1385.0 + 3633 * t_pow_2 + 4095.0 * t_pow_4 + 1575.0 * t_pow_6) / (40320 * sr * sn_pow_7 * (OK_POW_8)); + geoCoord.lat = ftphi - de_pow_2 * t0 + de_pow_4 * t1 - de_pow_3 * de_pow_3 * t2 + de_pow_4 * de_pow_3 * t3; + t0 = 1.0 / (sn * c * OK); + t1 = (1.0 + 2.0 * t_pow_2 + eta) / (6.0 * sn_pow_3 * c * (OK_POW_3)); + t2 = (5.0 + 6.0 * eta + 28.0 * t_pow_2 - 3.0 * eta_pow_2 + 8.0 * t_pow_2 * eta + + 24.0 * t_pow_4 - 4.0 * eta_pow_3 + 4.0 * t_pow_2 * eta_pow_2 + + 24.0 * t_pow_2 * eta_pow_3) / (120.0 * sn_pow_5 * c * (OK_POW_5)); + t3 = (61.0 + 662.0 * t_pow_2 + 1320.0 * t_pow_4 + 720.0 * t_pow_6) / (5040.0 * sn_pow_7 * c * OK_POW_7); + double dlam = de * t0 - de_pow_3 * t1 + de_pow_3 * de_pow_2 * t2 - de_pow_3 * de_pow_4 * t3; + // 19.0 * DEG_2_RAD == 0.33161255787892263; +// geoCoord.lon = 0.33161255787892263 + dlam; +// geoCoord.lon *= RAD_2_DEG; + geoCoord.lon = dlam * RAD_2_DEG; + geoCoord.lon += 19.0; geoCoord.lat *= RAD_2_DEG; } + //////////////////////////////////////////////////////////////////////////////// + // Funkcje pomocnicze i stałe + //////////////////////////////////////////////////////////////////////////////// + + static double calculateESquared(double a, double b) { + a *= a; + b *= b; + return (a - b) / a; + } + + static double calculateE2Squared(double a, double b) { + a *= a; + b *= b; + return (a - b) / b; + } + + static double denom(double sphi) { + double sinSphi = Math.sin(sphi); + return Math.sqrt(1.0 - E_SQUARED * (sinSphi * sinSphi)); + } + + static double sphsr(double sphi) { + double dn = denom(sphi); + return A * (1.0 - E_SQUARED) / (dn * dn * dn); + } + + static double sphsn(double sphi) { + double sinSphi = Math.sin(sphi); + return A / Math.sqrt(1.0 - E_SQUARED * (sinSphi * sinSphi)); + } + + static double sphtmd(double sphi) { + return (AP * sphi) - (BP * Math.sin(2.0 * sphi)) + (CP * Math.sin(4.0 * sphi)) + - (DP * Math.sin(6.0 * sphi)) + (EP * Math.sin(8.0 * sphi)); + } + + private static final double DEG_2_RAD = Math.PI / 180.0; + private static final double RAD_2_DEG = 180.0 / Math.PI; + + /** + * Dlługość dużej półsi, w metrach dla elipsoidy WGS-84. + */ + private static final double A = 6378137.0; + + /** + * double f: spłaszczenie elipsoidalne dla elipsoidy WGS-84, 1 / 298.257223563 + */ +// private static final double F = 1.0 / 298.257223563; + private static final double B = A * (1.0 - 1.0 / 298.257223563); + private static final double E_SQUARED = calculateESquared(A, B); + private static final double E2_SQUARED = calculateE2Squared(A, B); + private static final double TN = (A - B) / (A + B); + private static final double AP = A * (1.0 - TN + 5.0 * (TN * TN - TN * TN * TN) / 4.0 + 81.0 * TN * TN * TN * TN - TN * TN * TN * TN * TN / 64.0); + private static final double BP = 3.0 * A * (TN - TN * TN + 7.0 * (TN * TN * TN - TN * TN * TN * TN) / 8.0 + 55.0 * TN * TN * TN * TN * TN / 64.0) / 2.0; + private static final double CP = 15.0 * A * (TN * TN - TN * TN * TN + 3.0 * (TN * TN * TN * TN - TN * TN * TN * TN * TN) / 4.0) / 16.0; + private static final double DP = 35.0 * A * (TN * TN * TN - TN * TN * TN * TN + 11.0 * TN * TN * TN * TN * TN / 16.0) / 48.0; + private static final double EP = 315.0 * A * (TN * TN * TN * TN - TN * TN * TN * TN * TN) / 512.0; + + /** + * Współczynnik zniekształcenia skali mapy w południku osiowym dla odwzorowania kartograficznego PUWG-1992. + */ + private static final double OK = 0.9993; + private static final double OK_POW_2 = OK * OK; + private static final double OK_POW_3 = OK_POW_2 * OK; + private static final double OK_POW_4 = OK_POW_3 * OK; + private static final double OK_POW_5 = OK_POW_4 * OK; + private static final double OK_POW_6 = OK_POW_5 * OK; + private static final double OK_POW_7 = OK_POW_6 * OK; + private static final double OK_POW_8 = OK_POW_7 * OK; + + } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/DaneWysok.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/NMTData.java similarity index 73% rename from src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/DaneWysok.java rename to src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/NMTData.java index 006e5ab..879a512 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/DaneWysok.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/NMTData.java @@ -5,7 +5,7 @@ import pl.wat.ms4ds.terenfunkcje.GridCoord; /** * */ -public class DaneWysok { +public class NMTData { GridCoord idKw; @@ -13,7 +13,7 @@ public class DaneWysok { int licz; - public DaneWysok(GridCoord idKw, double suma, int licz) { + public NMTData(GridCoord idKw, double suma, int licz) { this.idKw = idKw; this.suma = suma; this.licz = licz; diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Node.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Node.java index 6b8cdaa..90c531c 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Node.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Node.java @@ -1,6 +1,6 @@ package pl.wat.ms4ds.terenfunkcje.konwersja; -import pl.wat.ms4ds.terenfunkcje.Kwadrat; +import pl.wat.ms4ds.terenfunkcje.Square; import pl.wat.ms4ds.terenfunkcje.MapConsts; import pl.wat.ms4ds.terenfunkcje.Teren; @@ -69,11 +69,11 @@ public class Node { public void writeAreaFeatureIntoSquare(EAreaFeature type) { if (buildingsCount >= BUILDINGS_COUNT) { - Kwadrat kw = Teren.getKwadrat(idX, idY); - kw.setStopienZabudowy(1.0f); + Square kw = Teren.getKwadrat(idX, idY); + kw.stopienZabudowy = 1.0f; } else if (buildingsCount > 0) { - Kwadrat kw = Teren.getKwadrat(idX, idY); - kw.setStopienZabudowy(0.5f); + Square kw = Teren.getKwadrat(idX, idY); + kw.stopienZabudowy = 0.5f; } } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/PUWGCoord.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/PUWGCoord.java index 34e2e5d..0194591 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/PUWGCoord.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/PUWGCoord.java @@ -1,7 +1,7 @@ package pl.wat.ms4ds.terenfunkcje.konwersja; /** - * Współrzędne punktu odwzorowania kartograficznego PUWG 1992 lub 2000. + * Współrzędne punktu odwzorowania kartograficznego PUWG 1992. *

* Wartośći współrzędnych [metry]. * @@ -15,21 +15,14 @@ public class PUWGCoord { * Współrzędna Y (oś rzędnych) odwzorowania kartograficznego [metry]. */ public double northing; - /** - * proj = 1 odpowiada odwzorowaniu 1992, natomiast każda inna odwzorowaniu 2000 - */ - public int proj; public PUWGCoord() { this.easting = 0; this.northing = 0; - // PUWG 1992 - this.proj = 1; } - public PUWGCoord(double easting, double northing, int proj) { + public PUWGCoord(double easting, double northing) { this.easting = easting; this.northing = northing; - this.proj = proj; } } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Way.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Way.java index 94bfefb..b5c1856 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Way.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/konwersja/Way.java @@ -247,8 +247,8 @@ public class Way { for (int i = 0; i < nodes.size(); i++) { punktyLamanej[i] = new GridCoord(nodes.get(i).idX, nodes.get(i).idY); } - Kwadrat kw0; - Kwadrat kw1; + Square kw0; + Square kw1; GridCoord id0; GridCoord id1; EGeoDirection kier; @@ -263,16 +263,16 @@ public class Way { kier = GeomUtils.kierunekDlaSasiada(id0, id1); switch (type) { case ROAD: - kw0.setJestDroga(kier, true); - kw1.setJestDroga(kier.oppositeDirect(), true); + kw0.jestDroga[kier.id]= true; + kw0.jestDroga[kier.oppositeDirect().id]= true; break; case WATER_WAY: - kw0.setJestPrzeszkodaWodna(kier, true); - kw1.setJestPrzeszkodaWodna(kier.oppositeDirect(), true); + kw0.jestPrzeszkodaWodna[kier.id]= true; + kw0.jestPrzeszkodaWodna[kier.oppositeDirect().id]= true; break; case DITCH: - kw0.setJestRow(kier, true); - kw1.setJestRow(kier.oppositeDirect(), true); + kw0.jestRow[kier.id]= true; + kw0.jestRow[kier.oppositeDirect().id]= true; break; default: } @@ -341,10 +341,10 @@ public class Way { int maxX = polygon[0].x; int maxY = polygon[0].y; for (int i = 1; i < polygon.length; i++) { - minX = (polygon[i].x < minX) ? polygon[i].x : minX; - minY = (polygon[i].y < minY) ? polygon[i].y : minY; - maxX = (polygon[i].x > maxX) ? polygon[i].x : maxX; - maxY = (polygon[i].y > maxY) ? polygon[i].y : maxY; + minX = Math.min(polygon[i].x, minX); + minY = Math.min(polygon[i].y, minY); + maxX = Math.max(polygon[i].x, maxX); + maxY = Math.max(polygon[i].y, maxY); } GridCoord idTest = new GridCoord(); boolean inside; @@ -352,24 +352,24 @@ public class Way { for (int i = minX; i <= maxX; i++) { idTest.x = i; idTest.y = j; - Kwadrat kw = Teren.getKwadrat(idTest.x, idTest.y); - if (kw == Kwadrat.EMPTY_SQUARE) { + Square kw = Teren.getKwadrat(idTest.x, idTest.y); + if (kw == Square.EMPTY) { continue; } inside = GeomUtils.insidePolygon(polygon, idTest); if (inside) { switch (type) { case FOREST: - kw.setStopienZalesienia(val); + kw.stopienZalesienia = val; break; case WATER: - kw.setStopienZawodnienia(val); + kw.stopienZawodnienia = val; break; case SWAMP: - kw.setStopienZabagnienia(val); + kw.stopienZabagnienia = val; break; case BUILDINGS: - kw.setStopienZabudowy(val); + kw.stopienZabudowy = val; break; default: } @@ -387,24 +387,24 @@ public class Way { for (int j = minY; j <= maxY; j++) { idTest.x = i; idTest.y = j; - Kwadrat kw = Teren.getKwadrat(idTest.x, idTest.y); - if (kw == Kwadrat.EMPTY_SQUARE) { + Square kw = Teren.getKwadrat(idTest.x, idTest.y); + if (kw == Square.EMPTY) { continue; } inside = GeomUtils.insidePolygon(polygon, idTest); if (inside) { switch (type) { case FOREST: - kw.setStopienZalesienia(val); + kw.stopienZalesienia = val; break; case WATER: - kw.setStopienZawodnienia(val); + kw.stopienZawodnienia = val; break; case SWAMP: - kw.setStopienZabagnienia(val); + kw.stopienZabagnienia = val; break; case BUILDINGS: - kw.setStopienZabudowy(val); + kw.stopienZabudowy = val; break; default: } @@ -417,22 +417,22 @@ public class Way { if (nodes.size() == 0) { return; } - Kwadrat kw; + Square kw; float val = (clearFeature) ? 0.0f : 1.0f; if (nodes.size() == 1) { kw = Teren.getKwadrat(nodes.get(0).idX, nodes.get(0).idY); switch (type) { case FOREST: - kw.setStopienZalesienia(val); + kw.stopienZalesienia = val; break; case WATER: - kw.setStopienZawodnienia(val); + kw.stopienZawodnienia = val; break; case SWAMP: - kw.setStopienZabagnienia(val); + kw.stopienZabagnienia = val; break; case BUILDINGS: - kw.setStopienZabudowy(val); + kw.stopienZabudowy = val; break; default: } @@ -445,16 +445,16 @@ public class Way { kw = Teren.getKwadrat(kwadraty[i].x, kwadraty[i].y); switch (type) { case FOREST: - kw.setStopienZalesienia(val); + kw.stopienZalesienia = val; break; case WATER: - kw.setStopienZawodnienia(val); + kw.stopienZawodnienia = val; break; case SWAMP: - kw.setStopienZabagnienia(val); + kw.stopienZabagnienia = val; break; case BUILDINGS: - kw.setStopienZabudowy(val); + kw.stopienZabudowy = val; break; default: } @@ -472,22 +472,22 @@ public class Way { if (nodes.size() == 0) { return; } - Kwadrat kw; + Square kw; float val = (clearFeature) ? 0.0f : 1.0f; if (nodes.size() == 1) { kw = Teren.getKwadrat(nodes.get(0).idX, nodes.get(0).idY); switch (type) { case FOREST: - kw.setStopienZalesienia(val); + kw.stopienZalesienia = val; break; case WATER: - kw.setStopienZawodnienia(val); + kw.stopienZawodnienia = val; break; case SWAMP: - kw.setStopienZabagnienia(val); + kw.stopienZabagnienia = val; break; case BUILDINGS: - kw.setStopienZabudowy(val); + kw.stopienZabudowy = val; break; default: } @@ -500,16 +500,16 @@ public class Way { kw = Teren.getKwadrat(kwadraty[i].x, kwadraty[i].y); switch (type) { case FOREST: - kw.setStopienZalesienia(val); + kw.stopienZalesienia = val; break; case WATER: - kw.setStopienZawodnienia(val); + kw.stopienZawodnienia = val; break; case SWAMP: - kw.setStopienZabagnienia(val); + kw.stopienZabagnienia = val; break; case BUILDINGS: - kw.setStopienZabudowy(val); + kw.stopienZabudowy = val; break; default: } @@ -523,10 +523,10 @@ public class Way { int maxY = nodes.get(0).idY; for (int i = 0; i < nodes.size(); i++) { wielokat[i] = new GridCoord(nodes.get(i).idX, nodes.get(i).idY); - minX = (wielokat[i].x < minX) ? wielokat[i].x : minX; - minY = (wielokat[i].y < minY) ? wielokat[i].y : minY; - maxX = (wielokat[i].x > maxX) ? wielokat[i].x : maxX; - maxY = (wielokat[i].y > maxY) ? wielokat[i].y : maxY; + minX = Math.min(wielokat[i].x, minX); + minY = Math.min(wielokat[i].y, minY); + maxX = Math.max(wielokat[i].x, maxX); + maxY = Math.max(wielokat[i].y, maxY); } int ileKwTest = (maxX - minX) * (maxY - minY); if (ileKwTest > 100000) { @@ -555,7 +555,7 @@ public class Way { // char c = ' '; // liczKw++; kw = Teren.getKwadrat(idTest.x, idTest.y); - if (kw == Kwadrat.EMPTY_SQUARE) { + if (kw == Square.EMPTY) { continue; } nalezyDoWielokata = GeomUtils.insidePolygon(wielokat, idTest); @@ -563,16 +563,16 @@ public class Way { // c = 'O'; switch (type) { case FOREST: - kw.setStopienZalesienia(val); + kw.stopienZalesienia = val; break; case WATER: - kw.setStopienZawodnienia(val); + kw.stopienZawodnienia = val; break; case SWAMP: - kw.setStopienZabagnienia(val); + kw.stopienZabagnienia = val; break; case BUILDINGS: - kw.setStopienZabudowy(val); + kw.stopienZabudowy = val; break; default: } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTDataProvider.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTDataProvider.java index 48653a7..a39fc53 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTDataProvider.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTDataProvider.java @@ -2,6 +2,7 @@ package pl.wat.ms4ds.terenfunkcje.nmt; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamReader; @@ -20,6 +21,7 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; public class NMTDataProvider { @@ -38,12 +40,13 @@ public class NMTDataProvider { // // String dir = "C:/Workspace/nmt/gugik_1m/"; // String links_fn = "C:/Workspace/nmt/gugik_links.txt"; - String dir = args[0]; - String links_fn = args[1]; +// String dir = args[0]; +// String links_fn = args[1]; // int start = Integer.parseInt(args[2]); // int end = Integer.parseInt(args[3]); - Set files = listFiles("C:/Workspace/nmt/gugik_1m/"); +// Set files = listFiles("C:/Workspace/nmt/gugik_1m/"); + // downloadFileSet(links_fn, start, end, dir); diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTReader.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTReader.java index 44831e5..78577de 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTReader.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/nmt/NMTReader.java @@ -1,58 +1,301 @@ package pl.wat.ms4ds.terenfunkcje.nmt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import pl.wat.ms4ds.terenfunkcje.*; +import pl.wat.ms4ds.terenfunkcje.konwersja.CoordUtils; +import pl.wat.ms4ds.terenfunkcje.konwersja.PUWGCoord; + import java.io.*; +import java.nio.file.FileSystemException; +import java.util.HashMap; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; public class NMTReader { + private static final Logger logger = LoggerFactory.getLogger(NMTReader.class); + static void main(String[] args) { // File dir = new File(System.getProperty("user.home") + "/nmt/gugik_SkorowidzNMT2018.gml"); - InputStream is = null; + int i = 0; + String inDir = "C:/Workspace/nmt/gugik_1m/asc/"; + String outDir = "C:/Workspace/nmt/unzipped/"; + String testFn = "D:\\Work\\73771_1025306_NMT-M348Dc41.xyz\\"; +// String testFn = "C:\\Workspace\\nmt\\M-33-7-A-c-3-2.asc"; try { - File file = new File("C:/Workspace/nmt/N-34-139-A-b-2-4.asc"); - is = new FileInputStream(file); - readFromInputStream(is); - //... - } catch (FileNotFoundException e) { - throw new RuntimeException(e); +// readFromFileASC(testFn); + readFromFileXYZ(testFn); } catch (IOException e) { throw new RuntimeException(e); - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException e) { - e.printStackTrace(); + } +// renameFiles(inDir, inDir); + + Set files = NMTDataProvider.listFiles(inDir); + for (String file : files) { + try { + String unzipfn = unzipFile(inDir + file, outDir); + if (unzipfn.endsWith(".asc")) { + readFromFileASC(outDir + unzipfn); + } else if (unzipfn.endsWith(".xyz")) { + readFromFileXYZ(outDir + unzipfn); } + } catch (IOException e) { + } } + + } + + 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); + + } + } catch (Exception e) { + throw new RuntimeException(e); + } } - private static void readFromInputStream(InputStream inputStream) throws IOException { + private static void readFromFileASC(String fn) 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 line = br.readLine(); String[] split = line.split(" "); int ncols = Integer.parseInt(split[1]); - line= br.readLine(); + line = br.readLine(); split = line.split(" "); int nrows = Integer.parseInt(split[1]); - line= br.readLine(); + line = br.readLine(); split = line.split(" "); double xll = Double.parseDouble(split[1]); - line= br.readLine(); + line = br.readLine(); split = line.split(" "); double yll = Double.parseDouble(split[1]); - line= br.readLine(); + line = br.readLine(); split = line.split(" "); double cellsize = Double.parseDouble(split[1]); - line= br.readLine(); + line = br.readLine(); split = line.split(" "); double nodata = Double.parseDouble(split[1]); - while ((line = br.readLine()) != null) { + double[][] data = new double[nrows][ncols]; + for (int i = nrows - 1; i >= 0; i--) { + line = br.readLine(); split = line.split(" "); - + for (int j = 0; j < ncols; j++) { + data[i][j] = Double.parseDouble(split[j]); + } } + GeoCoord geo_ll = new GeoCoord(); + CoordUtils.convertPUWG1992ToWGS84(yll, xll, geo_ll); + GeoCoord geo_ur = new GeoCoord(); + CoordUtils.convertPUWG1992ToWGS84(yll + nrows + cellsize, xll + ncols * cellsize, geo_ur); + int d_x = (int) ((geo_ur.lon - geo_ll.lon) / MapConsts.DELTA_X) + 3; + int d_y = (int) ((geo_ur.lat - geo_ll.lat) / MapConsts.DELTA_Y) + 3; + Square[][] kwadraty = new Square[d_x][d_y]; + final int x = GridCoord.zamienDlugoscGeoNaIdKwadratuX(geo_ll.lon); + final int y = GridCoord.zamienSzerokoscGeoNaIdKwadratuY(geo_ll.lat); + kwadraty[0][0] = new Square(); + +// Kwadrat kw = Teren.getKwadrat(x, y); + // Wyznacz współrzędne geo środka kwadratu. + GeoCoord geoCoord = new GeoCoord(); + geoCoord.lon = GridCoord.zamienIdKwadratuXNaDlugoscGeo(x); + geoCoord.lat = GridCoord.zamienIdKwadratuYNaSzerokoscGeo(y); + PUWGCoord puwgCoord = new PUWGCoord(); + // Wyznacz współrzędne PUWG lewego dolnego rogu kwadratu. + CoordUtils.convertWGS84ToPUWG1992(geoCoord.lat - MapConsts.DELTA_Y / 2, geoCoord.lon - MapConsts.DELTA_X / 2, puwgCoord); + kwadraty[0][0].ell = (int) puwgCoord.easting; + kwadraty[0][0].nll = (int) puwgCoord.northing; + // Wyznacz współrzędne PUWG prawego górnego rogu kwadratu. + CoordUtils.convertWGS84ToPUWG1992(geoCoord.lat + MapConsts.DELTA_Y / 2, geoCoord.lon + MapConsts.DELTA_X / 2, puwgCoord); + kwadraty[0][0].eur = (int) puwgCoord.easting; + kwadraty[0][0].nur = (int) puwgCoord.northing; + double dyy = 0; + double h; + int idX = 0; + int idY = 0; +// HashMap kws = new HashMap(); + for (int i = 0; i < nrows; i++) { + double yy = yll + dyy; + dyy += cellsize; + // Reset współrzędnej X na gridzie (siatce). + idX = 0; + if (yy >= kwadraty[idX][idY].nur) { + // Przekracza zakres współrzędnych pionowych, zatem kolejny/sąsiedni kwadrat po osi OY. + idY++; + if (kwadraty[idX][idY] == null) { + kwadraty[idX][idY] = new Square(); + } +// kw = Teren.getKwadrat(idX, idY); + if (kwadraty[idX][idY].nur == 0) { + // Świeży kwadrat. + // Wyznacz współrzędne geo środka kwadratu. + geoCoord.lon = GridCoord.zamienIdKwadratuXNaDlugoscGeo(idX + x); + geoCoord.lat = GridCoord.zamienIdKwadratuYNaSzerokoscGeo(idY + y); + // Wyznacz współrzędne PUWG prawego górnego rogu kwadratu. + CoordUtils.convertWGS84ToPUWG1992(geoCoord.lat + MapConsts.DELTA_Y / 2, geoCoord.lon + MapConsts.DELTA_X / 2, puwgCoord); + kwadraty[idX][idY].eur = (int) puwgCoord.easting; + kwadraty[idX][idY].nur = (int) puwgCoord.northing; + } + } + double dxx = 0; + for (int j = 0; j < ncols; j++) { + double xx = xll + dxx; + dxx += cellsize; + if (xx >= kwadraty[idX][idY].eur) { + // Przekracza zakres współrzędnych poziomych, zatem kolejny/sąsiedni kwadrat po osi OX. + idX++; + if (kwadraty[idX][idY] == null) { + kwadraty[idX][idY] = new Square(); + } +// kw = Teren.getKwadrat(idX, idY); + if (kwadraty[idX][idY].eur == 0) { + // Świeży kwadrat. + // Wyznacz współrzędne geo środka kwadratu. + geoCoord.lon = GridCoord.zamienIdKwadratuXNaDlugoscGeo(idX + x); + geoCoord.lat = GridCoord.zamienIdKwadratuYNaSzerokoscGeo(idY + y); + // Wyznacz współrzędne PUWG prawego górnego rogu kwadratu. + CoordUtils.convertWGS84ToPUWG1992(geoCoord.lat + MapConsts.DELTA_Y / 2, geoCoord.lon + MapConsts.DELTA_X / 2, puwgCoord); + kwadraty[idX][idY].eur = (int) puwgCoord.easting; + kwadraty[idX][idY].nur = (int) puwgCoord.northing; + } + } else if (xx < kwadraty[idX][idY].ell) { + idX--; + } + +// kws.put(kw, kw); + h = data[i][j]; + if (kwadraty[idX][idY] != Square.EMPTY && h > nodata) { + kwadraty[idX][idY].sumaWysokosci += h; + kwadraty[idX][idY].count++; + } + } + } + for (int i = 0; i < d_x; i++) { + for (int j = 0; j < d_y; j++) { + Square kw = kwadraty[i][j]; + if (kw != null) { + kw.wysokoscSrednia = (int) (kw.sumaWysokosci / kw.count); + Square kwOryg = Teren.getKwadrat(i + x, j + y); + // Aktualizacja tylko w przypadku braku danych o wysokości. + if (kwOryg != Square.EMPTY && kwOryg.wysokoscSrednia <= -1000) { +// kwOryg.wysokoscSrednia = kw.wysokoscSrednia; + kwOryg.sumaWysokosci = kw.sumaWysokosci; + kwOryg.count = kw.count; + } + } + } + } + logger.debug("Time= {}[ms]", System.currentTimeMillis() - start); } } + + private static void readFromFileXYZ(String fn) throws IOException { + File file = new File(fn); + InputStream inputStream = new FileInputStream(file); + Square kw = Square.EMPTY; + PUWGCoord puwgCoord = new PUWGCoord(); + GeoCoord geo = new GeoCoord(); + HashMap map = new HashMap<>(); + try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { + String line; + while ((line = br.readLine()) != null) { + String[] split = line.split(" "); + double x = Double.parseDouble(split[0]); + double y = Double.parseDouble(split[1]); + double h = Double.parseDouble(split[2]); + if (kw.ell > x || kw.eur < x || kw.nll > y || kw.nur < y) { + // Punkt poza granicą bieżącego kwadratu. + CoordUtils.convertPUWG1992ToWGS84(y, x, geo); + kw = Teren.getKwadrat(geo.lat, geo.lon); + if (kw == Square.EMPTY) { + continue; + } + if (kw.stopienZalesienia > 0 || kw.stopienZawodnienia > 0 || kw.stopienZabudowy > 0) { + System.out.println(kw); + } + map.put(kw, kw); + if (kw.nur == 0) { + // Kwadrat jeszcze nie był odczytany (czysty). + int idX = GridCoord.zamienDlugoscGeoNaIdKwadratuX(geo.lon); + int idY = GridCoord.zamienSzerokoscGeoNaIdKwadratuY(geo.lat); + // Współrzędne geo środka kwadratu. + geo.lon = GridCoord.zamienIdKwadratuXNaDlugoscGeo(idX); + geo.lat = GridCoord.zamienIdKwadratuYNaSzerokoscGeo(idY); + // Wyznacz współrzędne PUWG lewego dolnego rogu kwadratu. + CoordUtils.convertWGS84ToPUWG1992(geo.lat - MapConsts.DELTA_Y / 2, geo.lon - MapConsts.DELTA_X / 2, puwgCoord); + kw.ell = (int) puwgCoord.easting; + kw.nll = (int) puwgCoord.northing; + // Wyznacz współrzędne PUWG prawego górnego rogu kwadratu. + CoordUtils.convertWGS84ToPUWG1992(geo.lat + MapConsts.DELTA_Y / 2, geo.lon + MapConsts.DELTA_X / 2, puwgCoord); + kw.eur = (int) puwgCoord.easting; + kw.nur = (int) puwgCoord.northing; + } + } +// if (kw != Kwadrat.EMPTY_SQUARE && kw.wysokoscSrednia <= -1000) { + if (kw != Square.EMPTY) { + kw.sumaWysokosci += h; + kw.count++; +// kw.wysokoscSrednia = kw.wysokoscSrednia; + } + } + + + } + + } + + public static String unzipFile(String zipFileName, String destDir) throws IOException { + byte[] buffer = new byte[1024]; + String unzipFileName = ""; + try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName))) { + ZipEntry zipEntry = zis.getNextEntry(); + while (zipEntry != null) { + unzipFileName = zipEntry.getName(); + File newFile = new File(destDir + unzipFileName); +// File newFile = new File(destDir + File.separator + unzipFileName); + int len; + // write file content + FileOutputStream fos = new FileOutputStream(newFile); + while ((len = zis.read(buffer)) > 0) { + fos.write(buffer, 0, len); + } + fos.close(); + zipEntry = zis.getNextEntry(); + } + zis.closeEntry(); + } + return unzipFileName; + } } diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/osm/shapefile/Main.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/osm/shapefile/Main.java index 29823ac..bfebc31 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/osm/shapefile/Main.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/osm/shapefile/Main.java @@ -6,8 +6,7 @@ public class Main { static void main(String[] args) { try { // GET DIRECTORY - String curDir = (args[0] != null) ? args[0] : System.getProperty("user.dir"); - curDir = ""; + String curDir = (args.length > 0) ? args[0] : ""; String folder = "C:/Workspace/osm/dolnoslaskie-251217-free.shp/"; // LOAD SHAPE FILE (.shp, .shx, .dbf) diff --git a/src/main/java/pl/wat/ms4ds/terenfunkcje/osm/shapefile/OsmShapeFileReader.java b/src/main/java/pl/wat/ms4ds/terenfunkcje/osm/shapefile/OsmShapeFileReader.java index f6ba74b..bb7f7a0 100644 --- a/src/main/java/pl/wat/ms4ds/terenfunkcje/osm/shapefile/OsmShapeFileReader.java +++ b/src/main/java/pl/wat/ms4ds/terenfunkcje/osm/shapefile/OsmShapeFileReader.java @@ -84,34 +84,34 @@ public class OsmShapeFileReader { ShpShape shape = null; DbfRecord info = null; switch (shpHeader.shapeType) { -// case Point, PointZ, PointM: -// shape = new ShpPoint(shpHeader.shapeType); -// shape.read(bisShp); -// info = new DbfRecord(); -// info.read(bisDbf, dbfHeader); -// shape.setInfo(info); -// return shape; -// case PolyLine, PolyLineZ, PolyLineM: -// shape = new ShpPolyLine(shpHeader.shapeType); -// shape.read(bisShp); -// info = new DbfRecord(); -// info.read(bisDbf, dbfHeader); -// shape.setInfo(info); -// return shape; -// case Polygon, PolygonZ, PolygonM: -// shape = new ShpPolygon(shpHeader.shapeType); -// shape.read(bisShp); -// info = new DbfRecord(); -// info.read(bisDbf, dbfHeader); -// shape.setInfo(info); -// return shape; -// case MultiPoint, MultiPointZ, MultiPointM: -// shape = new ShpMultiPoint(shpHeader.shapeType); -// shape.read(bisShp); -// info = new DbfRecord(); -// info.read(bisDbf, dbfHeader); -// shape.setInfo(info); -// return shape; + case Point, PointZ, PointM: + shape = new ShpPoint(shpHeader.shapeType); + shape.read(bisShp); + info = new DbfRecord(); + info.read(bisDbf, dbfHeader); + shape.setInfo(info); + return shape; + case PolyLine, PolyLineZ, PolyLineM: + shape = new ShpPolyLine(shpHeader.shapeType); + shape.read(bisShp); + info = new DbfRecord(); + info.read(bisDbf, dbfHeader); + shape.setInfo(info); + return shape; + case Polygon, PolygonZ, PolygonM: + shape = new ShpPolygon(shpHeader.shapeType); + shape.read(bisShp); + info = new DbfRecord(); + info.read(bisDbf, dbfHeader); + shape.setInfo(info); + return shape; + case MultiPoint, MultiPointZ, MultiPointM: + shape = new ShpMultiPoint(shpHeader.shapeType); + shape.read(bisShp); + info = new DbfRecord(); + info.read(bisDbf, dbfHeader); + shape.setInfo(info); + return shape; default: return shape; }