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 luki; ArrayList 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(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 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(); 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 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 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) { // 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(); } }