summaryrefslogblamecommitdiffstats
path: root/DataStructure/Interpolator.java
blob: 3869255da69f64a6308fa822aad5afa3f56931e5 (plain) (tree)













































































































































































































































































































































































                                                                                                                 
package DataStructure;

import helper.ListBTS;

import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
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<SingleBTS>[][] 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<SingleBTS>();
			}
		}

	}

	/**
	 * 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<Point2D> neighbors = secondary.getDirectNeighbors(x, y);

			// calculate intersection of voronoi region for each neighbor
			ArrayList<Weight> weights = new ArrayList<Weight>(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)
				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;
		}

	}

}