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

366 lines
14 KiB
Java

package pl.wat.ms4ds.terenfunkcje;
import java.io.BufferedReader;
import java.io.BufferedWriter;
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);
ArrayList<LukDrogowy> luki;
ArrayList<WezelDrogowy> wezly;
static SiecDrogowa instancja;
static String path;
Arkusz[][] arkusze;
public int liczbaZmian = 0;
static final int LICZBA_ZMIAN = 50;
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();
// logger.debug("Liczba lukow w arkuszach:");
// int ll = 0;
// for (int i = 0; i < Arkusz.lx; i++) {
// for (int j = 0; j < Arkusz.ly; j++) {
// logger.debug(String.format("(%1$2d, %2$2d) - %3$6d", i, j, this.arkusze[i][j].luki.size()));
// ll += this.arkusze[i][j].luki.size();
// }
// }
// 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<WezelDrogowy>(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<LukDrogowy>(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);
}
}
}
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 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<LukDrogowy>();
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 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();
}
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);
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");
}
}
}
// funkcja zwraca kolekcje lukow wewnatrz prostokata
// zawartego miedzy lewym dolnym i prawym gornym punktem
public static ArrayList<LukDrogowy> 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.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<LukDrogowy> luki = new ArrayList<LukDrogowy>();
// 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) {
// GridCoord idKw = GridCoord.zamienWspUtmNaIdKwadratu("520101N0160202E");
// String utm = GridCoord.zamienIdKwadratuNaWspUtm(idKw);
// int xms = GridCoord.zamienIdKwadratuXNaWspXms(idKw.x);
// int yms = GridCoord.zamienIdKwadratuYNaWspYms(idKw.y);
// utm = Teren.zamienWspXmsYmsNaWspUtm(xms, yms);
// float lon = GridCoord.zamienIdKwadratuXNaDlugoscGeo(idKw.x);
// float lat = GridCoord.zamienIdKwadratuYNaSzerokoscGeo(idKw.y);
// idKw.x = GridCoord.zamienDlugoscGeoNaIdKwadratuX(lon);
// idKw.y = GridCoord.zamienSzerokoscGeoNaIdKwadratuY(lat);
utworzSiecDrogowa();
SiecDrogowa.wpiszDrogiWKwadraty();
}
}