summaryrefslogblamecommitdiffstats
path: root/DataStructure/MobilePhone.java
blob: 2276bb635b2438bfe2c94174445bde97bca06cc7 (plain) (tree)
















































































































































































































































































































































                                                                                                        
package DataStructure;

import helper.ListBTS;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Date;

import org.jdesktop.swingx.JXMapViewer;
import org.jdesktop.swingx.mapviewer.GeoPosition;
import org.jdesktop.swingx.painter.Painter;

public class MobilePhone implements Painter<JXMapViewer> {
	public ArrayList<SingleBTS> MR;
	public long IMSI;
	public double[][] scoremap;
	public GSMMap gsmmap;
	public Color color;
	public boolean timeSensitiv = false;
	public double confidence;
	public BayesAll bayes;
	public GPScoordinate correctCoordinate;
	public String name = "";
	public Date time = new Date();

	// private int maxProbX;
	// private int maxProbY;

	public MobilePhone() {
		MR = new ArrayList<SingleBTS>();
	}

	public MobilePhone(BayesAll bayes) {
		MR = new ArrayList<SingleBTS>();
		this.bayes = bayes;

	}

	private void DrawDetails(Graphics2D g, double highestScore, int tileCount) {
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, 300, 25);
		g.setColor(Color.BLACK);
		g.drawString("Score tile: " + highestScore + "\n\r #Tiles: "
				+ tileCount, 5, 10);
		Date time;
		if (timeSensitiv) {
			time = this.time;
		} else {
			time = MR.get(0).time;
		}
		g.drawString(name + " " + time, 5, 20);

	}

	public void average() {

	}

	public String toString() {
		return IMSI + " " + MR;
	}

	/**
	 * Returns (and stores in scoremap) the possibility that this Mobile Phone
	 * falls within the tile. Dimensions and Coordinates of scoremap are that of
	 * map. Must be run before this Phone gets drawn!
	 * 
	 * @param map
	 * @return
	 */
	public double[][] locate(GSMMap map, boolean dropNaN) {
		scoremap = gsmBayes.computeScore(MR, map);
		this.gsmmap = map;

		return scoremap;
	}

	public double[][] locate(double confidence) {
		this.gsmmap = this.bayes.map;
		this.confidence = confidence;
		timeSensitiv = false;
		ArrayList<SingleBTS> averagedMR = ListBTS.generateAveragedList(MR);

		// remove outlier!
		// for (int i = 0; i < averagedMR.size(); i++) {
		// averagedMR.get(i).removeOutlier();
		// }
		scoremap = bayes.locate(averagedMR, confidence);
		if (correctCoordinate != null) {
			System.out.println(localizationAccuracy());
		}
		return scoremap;
	}

	/**
	 * Returns (and stores) the possibility that this Mobile Phone falls within
	 * the tile. Possibilities get summed up until they are greater or equal
	 * confidence. Dimensions and Coordinates of scoremap are that of map
	 * 
	 * @param map
	 * @return
	 */
	public double[][] locate(GSMMap map, double confidence, boolean dropNaN) {
		scoremap = gsmBayes.toConfidence(gsmBayes.computeScore(MR, map),
				confidence);
		gsmmap = map;
		this.confidence = confidence;
		return scoremap;
	}

	public double[][] locateTimeSensitiv(GSMMap map, double confidence,
			long time, boolean dropNaN) {
		gsmmap = map;
		this.confidence = confidence;
		ArrayList<SingleBTS> temporalMR = filterTime(MR, time);
		temporalMR = ListBTS.generateAveragedList(temporalMR);
		scoremap = gsmBayes.toConfidence(
				gsmBayes.computeScore(temporalMR, map), confidence);
		return scoremap;
	}

	public double[][] locateTimeSensitiv(double confidence, long time) {
		this.gsmmap = this.bayes.map;
		this.confidence = confidence;
		timeSensitiv = true;
		this.time = new Date(time);
		ArrayList<SingleBTS> temporalMR = filterTime(MR, time);
		temporalMR = ListBTS.generateAveragedList(temporalMR);
		scoremap = bayes.locate(temporalMR, confidence);

		// sum up scoremap!!!!
		double sum = 0;
		for (int x = 0; x < scoremap.length; x++) {
			for (int y = 0; y < scoremap[0].length; y++) {
				sum += scoremap[x][y];
			}
		}
		// System.out.println("Summe scoremap: " + sum);

		return scoremap;

	}

	/**
	 * Returns entries in MR that are +/- 1 second within time
	 * 
	 * @param MR
	 * @param time
	 * @return
	 */
	private ArrayList<SingleBTS> filterTime(ArrayList<SingleBTS> MR, long time) {
		ArrayList<SingleBTS> temporalMR = new ArrayList<SingleBTS>(20);
		for (SingleBTS current : MR) {
			if (Math.abs(current.time.getTime() - time) <= 1001) {
				temporalMR.add(current);
			}
		}
		return temporalMR;
	}

	@Override
	public void paint(Graphics2D g, JXMapViewer map, int w, int h) {
		// locate(gsmmap);

		g = (Graphics2D) g.create();

		// convert from viewport to world bitmap
		Rectangle rect = ((org.jdesktop.swingx.JXMapViewer) map)
				.getViewportBounds();
		g.translate(-rect.x, -rect.y);
		// maxProbX = 0;
		// maxProbY = 0;
		double currentscore = 0;
		int tileCounter = 0;
		Polygon maxTile = null;
		// now, draw
		for (int x = 0; x < scoremap.length; x++) {
			for (int y = 0; y < scoremap[0].length; y++) {

				if (scoremap[x][y] > 0) {
					tileCounter++;
					double coordX = gsmmap.Xcoords[x];
					double coordY = gsmmap.Ycoords[y];
					double accuracy = gsmmap.accuracy;
					Polygon tile = new Polygon();

					GeoPosition pos1 = new GeoPosition(coordY - accuracy / 2,
							coordX + accuracy / 2);
					GeoPosition pos2 = new GeoPosition(coordY + accuracy / 2,
							coordX + accuracy / 2);
					GeoPosition pos3 = new GeoPosition(coordY + accuracy / 2,
							coordX - accuracy / 2);
					GeoPosition pos4 = new GeoPosition(coordY - accuracy / 2,
							coordX - accuracy / 2);
					Point2D pt1 = map.getTileFactory().geoToPixel(pos1,
							map.getZoom());
					Point2D pt2 = map.getTileFactory().geoToPixel(pos2,
							map.getZoom());
					Point2D pt3 = map.getTileFactory().geoToPixel(pos3,
							map.getZoom());
					Point2D pt4 = map.getTileFactory().geoToPixel(pos4,
							map.getZoom());
					Color c = getColor(scoremap[x][y]);
					// g.setColor(new Color(255, 0, 0, 255));
					g.setColor(c);
					tile.addPoint((int) pt1.getX(), (int) pt1.getY());
					tile.addPoint((int) pt2.getX(), (int) pt2.getY());
					tile.addPoint((int) pt3.getX(), (int) pt3.getY());
					tile.addPoint((int) pt4.getX(), (int) pt4.getY());
					g.fill(tile);
					g.draw(tile);
					if (scoremap[x][y] >= currentscore) {
						// update x, y of biggest score
						currentscore = scoremap[x][y];
						// maxProbX = x;
						// maxProbY = y;
						maxTile = tile;
					}
				}
			}
		}

		// g.translate(-rect.x, -rect.y);
		try {
			g.setColor(Color.red);
			g.draw(maxTile);
		} catch (NullPointerException e) {

		}

		if (correctCoordinate != null) {
			// draw a circle where the correct position of this phone is
			double latitude = correctCoordinate.coord1;
			double longitude = correctCoordinate.coord2;
			GeoPosition correct = new GeoPosition(latitude, longitude);
			Point2D circle = map.getTileFactory().geoToPixel(correct,
					map.getZoom());
			g.setColor(Color.RED);
			g.drawOval((int) circle.getX() - 5, (int) circle.getY() - 5, 10, 10);
		}
		// translate back to Monitor coordinates
		g.translate(rect.x, rect.y);
		DrawDetails(g, currentscore, tileCounter);
		g.dispose();

	}

	/**
	 * After a localization was done, you can output details for this
	 * localization
	 * 
	 * @return
	 */
	public String localizationAccuracy() {
		try {
			// get maximum possible tile
			PossibilityObject[] possibilities = bayes.toPossibility(scoremap);
			PossibilityObject mostPossible = possibilities[possibilities.length - 1];
			// x,y for most possible coord
			int x = mostPossible.x;
			int y = mostPossible.y;
			GPScoordinate possibleCoord = new GPScoordinate(new Date(),
					gsmmap.Ycoords[y], 'N', gsmmap.Xcoords[x], 'E', true);

			// distance between correct localization and possibleCoord
			double distance = helper.Distance.calc(possibleCoord,
					correctCoordinate);
			// get distance of tile that is maximum away from correct location
			double radius = maxError();
			String result = "Distance to correct position: " + distance * 1000
					+ "m. Most away tile: " + radius * 1000
					+ "m  from correct position";
			return result;

		} catch (NullPointerException e) {
			// System.out.println("ERROR: cannot aquire most possible location");
			return "";
		}

	}

	private double maxError() {
		double maxDistance = 0;
		double correctN = correctCoordinate.coord1;
		double correctE = correctCoordinate.coord2;
		for (int x = 0; x < scoremap.length; x++) {
			for (int y = 0; y < scoremap[0].length; y++) {
				if (scoremap[x][y] > 0) {
					double currentDistance = helper.Distance.calc(correctN,
							correctE, gsmmap.Ycoords[y], gsmmap.Xcoords[x]);
					maxDistance = Math.max(maxDistance, currentDistance);
				}
			}
		}
		return maxDistance;
	}

	private Color getColor(double d) {
		// d between 0...confidence
		// Color between black and green???
		// int green = (int) (d * 255);
		// return new Color(0, green, 0, 100);

		// r+b means probability of 1/2!!!
		int color = (int) ((d / confidence) * 255);
		// lets say half of confidence is already full pink!
		color = color * 2;
		if (color > 255)
			color = 255;
		return new Color(color, 0, color, 255);
	}

	public long getMinTime() {
		long time = MR.get(0).time.getTime();
		for (int i = 1; i < MR.size(); i++) {
			if (MR.get(i).time.getTime() < time) {
				time = MR.get(i).time.getTime();
			}
		}
		return time;
	}

	public long getMaxTime() {
		long time = MR.get(0).time.getTime();
		for (int i = 1; i < MR.size(); i++) {
			if (MR.get(i).time.getTime() > time) {
				time = MR.get(i).time.getTime();
			}
		}
		return time;
	}

}