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 { public ArrayList 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(); } public MobilePhone(BayesAll bayes) { MR = new ArrayList(); 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 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 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 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 filterTime(ArrayList MR, long time) { ArrayList temporalMR = new ArrayList(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; } }