package DataStructure; import helper.ListBTS; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.Date; import voronoi.voronoi; import Parse.sqlreader; public class Interpolator extends GSMMap { /** * */ private static final long serialVersionUID = 1388761837460629751L; public ArrayList[][] buffer; public Interpolator(sqlreader SQL, double accuracy) { super(SQL, accuracy); // initialize buffer buffer = new ArrayList[this.Xcoords.length][this.Ycoords.length]; for (int x = 0; x < Xcoords.length; x++) { for (int y = 0; y < Ycoords.length; y++) { buffer[x][y] = new ArrayList(); } } } public void toGoogleKml(String filename) throws IOException { new GoogleOut(this, filename).write(); } /** * Saves GSM map as Object on filesystem * * @param filename */ public void save(String filename) { try { FileOutputStream fos = new FileOutputStream(filename); ObjectOutputStream out = new ObjectOutputStream(fos); out.writeObject(this); out.close(); } catch (IOException e) { // TODO Auto-generated catch block // e.printStackTrace(); System.out.println("Cannot write Object to filesystem"); } System.out.println("GSMmap saved"); } /** * Interpolates every Point on the map,every arfcn */ public void interpolateVR() { // get starting time long start = new Date().getTime(); // average first! // average(); // removeOutlier(); SingleBTS[] content = content(); int success = 0; int failure = 0; int number = Xcoords.length * Ycoords.length * content.length; // traverse each bts for (int i = 0; i < content.length; i++) { // for (int i = 2; i < 3; i++) { // initialize voronoi with current arfcn voronoi primary = new voronoi(); primary.sortNode(this, content[i].ARFCN, 1); primary.generateVoronoi(0, Xcoords.length * 3.5, 0, Ycoords.length * 3.5); // now, traverse each point. Check if interpolation is needed! // loop is a little tricky because of threats! for (int x = 0; x < Xcoords.length; x++) { for (int y = 0; y < Ycoords.length; y++) { // this is a crucial point for parallelism. Change this if // statement // if (ListBTS.contains(map[x][y], content[i])) { // this coordinates already contains this bts // continue; // } // System.out.print("Interpoliere bei:" + x + "," + y // + ", arfcn " + content[i].ARFCN); // make it parallel? interpolateThread it1 = new interpolateThread(x, y, content[i], primary); Thread it1T = new Thread(it1); try { if (!ListBTS.contains(map[x][y], content[i])) { it1T.start(); // success++; } } catch (Exception e) { failure++; } y++; interpolateThread it2 = new interpolateThread(x, y, content[i], primary); Thread it2T = new Thread(it2); try { if (checkBounds(x, y) && !ListBTS.contains(map[x][y], content[i])) { it2T.start(); // success++; } } catch (Exception e) { failure++; } y++; interpolateThread it3 = new interpolateThread(x, y, content[i], primary); Thread it3T = new Thread(it3); try { if (checkBounds(x, y) && !ListBTS.contains(map[x][y], content[i])) { it3T.start(); // success++; } } catch (Exception e) { failure++; } y++; interpolateThread it4 = new interpolateThread(x, y, content[i], primary); Thread it4T = new Thread(it4); try { if (checkBounds(x, y) && !ListBTS.contains(map[x][y], content[i])) { it4T.start(); // success++; } } catch (Exception e) { failure++; } // y++; // interpolateThread it5 = new interpolateThread(x, y, // content[i], primary); // Thread it5T = new Thread(it5); // try { // if (checkBounds(x, y) // && !ListBTS.contains(map[x][y], content[i])) { // it5T.start(); // success++; // } // } catch (Exception e) { // failure++; // } // success += 5; success += 4; if (success % 200 == 0) { // calc ETA long difference = new Date().getTime() - start; int resttime = (int) (difference / success * (number - success)); resttime = (resttime / 1000) / 60; System.out.println("Total: " + number + " current: " + success + " rest: " + resttime + " min; current ARFCN: " + content[i].ARFCN + ", Index:" + i + "/" + content.length); } try { it1T.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { it2T.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { it3T.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { it4T.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // try { // it5T.join(); // } catch (InterruptedException e) { // TODO Auto-generated catch block // e.printStackTrace(); // } // interpolateAT(x, y, content[i], primary); // //singleThread // } catch (Exception e) { // System.out.println("Fehler bei:" + x + "," + y); // failure++; // } } } } mergebuffer(); System.out.println("Fertig!"); } private boolean checkBounds(int x, int y) { return (x < Xcoords.length && y < Ycoords.length); } /** * Takes map[x][y]. Inserts an interpolated BTS on this point if neccessary * * @param x * @param y * @param arfcn * @param primary * original Voronoi without the current Interpolationpoint */ private void interpolateAT(int x, int y, SingleBTS interpolateThis, voronoi primary) { if (!ListBTS.contains(map[x][y], interpolateThis)) { // do it! voronoi secondary = new voronoi(); secondary.sortNode((GSMMap) this, interpolateThis.ARFCN, 1, x, y); secondary.generateVoronoi(0, 4000, 0, 4000); // get area of polygon for current x,y // double area = secondary.areaOf(x, y); Path2D region = secondary.getPoly(x, y); double area = secondary.area(region); if (region == null) { return; } // get Neighbors of x,y ArrayList neighbors = secondary.getDirectNeighbors(x, y); // calculate intersection of voronoi region for each neighbor ArrayList weights = new ArrayList(neighbors.size()); for (int i = 0; i < neighbors.size(); i++) { int neighX = (int) neighbors.get(i).getX(); int neighY = (int) neighbors.get(i).getY(); // double area2 = primary.areaOf(currentx, currenty); Path2D underling = primary.getPoly(neighX, neighY); if (underling == null) { // one of the neighbors doesn't have a vornoi region. // this happens at the bounds of the gsm map:a infinit big // polygon continue; // TODO: das continue könnte zu problemen führen, weil dann // auch kein weights element an dieser Stelle eingefügt wird // und das Array somit an dieser Stelle auch null ist // TODO: warum ist temporary manchmal null?!!!!!!! } // intersection between both voronoi regions double intersectA = primary.intersectArea(region, underling); Weight new_element = new Weight(); new_element.weight = intersectA / area; new_element.bts = ListBTS.getARFCN(map[neighX][neighY], interpolateThis); weights.add(new_element); } // now, traverse weights, get sum of weights (to check if it equals // one) double newDL = 0; double mode = 0; double var = 0; double DlQualsub = 0; // double DlQualFull = 0; double UlQualsub = 0; // double UlQualFull = 0; double sum_of_weights = 0; for (int i = 0; i < weights.size(); i++) { if (weights.get(i) == null) continue; sum_of_weights += weights.get(i).weight; } // calculate with weights and normalize for (int i = 0; i < weights.size(); i++) { if (weights.get(i) == null) continue; // HACK: normalize weights weights.get(i).weight = weights.get(i).weight / sum_of_weights; // calulate newDL = newDL + weights.get(i).weight * weights.get(i).bts.getDLmW(); mode = mode + weights.get(i).weight * weights.get(i).bts.getStrictDLdBAverage(); var = var + weights.get(i).weight * weights.get(i).bts.getTrueVarianceDLdB(); DlQualsub = DlQualsub + weights.get(i).weight * weights.get(i).bts.getDLQsub(); // DlQualFull = DlQualFull + weights.get(i).weight // * weights.get(i).bts.getDLQfull(); UlQualsub = UlQualsub + weights.get(i).weight * weights.get(i).bts.getULQsub(); // UlQualFull = UlQualFull + weights.get(i).weight // * weights.get(i).bts.getULQfull(); // weights.get(i).bts. } // map[x][y] doesn't contain the just interpolated bts SingleBTS temp = new SingleBTS(interpolateThis.ARFCN, interpolateThis.name + "I"); temp.addDl(newDL); temp.dlQsub.add(DlQualsub); // temp.dlQfull.add(DlQualFull); temp.ulQsub.add(UlQualsub); // temp.ulQfull.add(UlQualFull); temp.interpolated.add(true); temp.setVarDLdB(var); temp.mode = mode; buffer[x][y].add(temp); } } private void mergebuffer() { for (int x = 0; x < Xcoords.length; x++) { for (int y = 0; y < Ycoords.length; y++) { if (map[x][y].isEmpty()) { map[x][y] = buffer[x][y]; } else { mergeSingleBTS(x, y); } } } } /** * If map[x][y] contains measurements, check if some BTS are missing and * merge with buffer * * @param x * @param y */ private void mergeSingleBTS(int x, int y) { for (SingleBTS current : buffer[x][y]) { if (!ListBTS.contains(map[x][y], current)) { map[x][y].add(current); } } } class interpolateThread implements Runnable { public int x; public int y; public SingleBTS what; public voronoi primary; @Override public void run() { if (x < Xcoords.length && y < Ycoords.length) { voronoi primary = new voronoi(); primary.sortNode(Interpolator.this, what.ARFCN, 1); interpolateAT(x, y, what, primary); } } public interpolateThread(int x, int y, SingleBTS what, voronoi primary) { this.x = x; this.y = y; this.what = what; // this.primary=primary; } } }