summaryrefslogtreecommitdiffstats
path: root/DataStructure/GoogleOut.java
diff options
context:
space:
mode:
Diffstat (limited to 'DataStructure/GoogleOut.java')
-rw-r--r--DataStructure/GoogleOut.java598
1 files changed, 598 insertions, 0 deletions
diff --git a/DataStructure/GoogleOut.java b/DataStructure/GoogleOut.java
new file mode 100644
index 0000000..0d96e33
--- /dev/null
+++ b/DataStructure/GoogleOut.java
@@ -0,0 +1,598 @@
+package DataStructure;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class GoogleOut {
+ private BufferedWriter br;
+ private LinkedList<MeasurementReport> MRlog;
+ // private LinkedList<GPScoordinate> GPSlog;
+ private double accuracy = 0.00004;
+ private GSMMap map;
+ private double[] Xcoords;
+ private double[] Ycoords;
+ private String fileName;
+
+ public GoogleOut(GSMMap map, String fileName) {
+ this.map = map;
+ this.fileName = fileName;
+ }
+
+ // Constructor
+ public void write() throws IOException {
+ // this.map = map;
+ Xcoords = map.Xcoords;
+ Ycoords = map.Ycoords;
+ br = new BufferedWriter(new FileWriter(new File(fileName)));
+ writeHeader();
+
+ // Downlink
+ // write Folder and Polygons for each BTS in the database
+ SingleBTS[] btsNames = map.btsnames; // change here to plot e-plus bts
+ for (SingleBTS singleBTSDL : btsNames) {
+ if (map.contains(singleBTSDL)) {
+ // if the GSMmap contains at least one of this BTS, do it
+ writeFolderDesc(singleBTSDL, false);
+ writePlacemarks(singleBTSDL, false);
+ br.write("</Folder> \n");
+ }
+
+ }
+
+ // Uplink (RZ-GSM)
+ for (SingleBTS singleBTSDL : btsNames) {
+ if (map.contains(singleBTSDL)) {
+ // if the GSMmap contains at least one of this BTS, do it
+ writeFolderDesc(singleBTSDL, true);
+ writePlacemarks(singleBTSDL, true);
+ br.write("</Folder> \n");
+ }
+
+ }
+
+ // Downlink (foreign BTSs). Actually one could just change BTSnames =
+ // map.content() in the beginning
+ SingleBTS[] foreign = map.contentForeignBTS();
+ if (foreign != null) {
+ for (SingleBTS foreignBTS : foreign) {
+ writeFolderDesc(foreignBTS, false);
+ writePlacemarks(foreignBTS, false);
+ br.write("</Folder> \n");
+ }
+ }
+
+ br.write("</Document>");
+ br.write("</kml>");
+ br.flush();
+ br.close();
+ }
+
+ /**
+ * Writes Header for the folder: Foldername, Up/Downlink, LookAt,...
+ *
+ * @param btsname
+ * @param uplink
+ * @throws IOException
+ */
+ private void writeFolderDesc(SingleBTS btsname, boolean uplink)
+ throws IOException {
+ SingleBTS foundBTS = map.getFirstBTSmatch(btsname);
+ String upDown;
+ if (uplink)
+ upDown = "Uplink: ";
+ else
+ upDown = "Downlink: ";
+
+ // br.write("<open>1</open>\n");
+ br.write(" <Folder>\n");
+ br.write("<name>MR " + upDown + "" + btsname.ARFCN + ": "
+ + btsname.name + "</name>\n");
+ br.write(" <visibility>1</visibility>\n");
+ br.write("<description>MR from " + foundBTS.time.toString()
+ + "</description>\n");
+ br.write(" <LookAt>\n");
+ br.write("<longitude>" + (map.maxX + map.minX) / 2 + "</longitude>\n");
+ br.write("<latitude>" + (map.maxY + map.minY) / 2 + "</latitude>\n");
+ br.write("<altitude>0</altitude>\n");
+ br.write("<heading>0.0</heading>\n");
+ br.write("<tilt>0</tilt>\n");
+ br.write("<range>276.0</range>\n");
+ br.write("</LookAt>\n");
+
+ }
+
+ private void writePlacemarks(SingleBTS btsName, boolean uplink)
+ throws IOException {
+ // was a BTS written to file?
+ // Polygon Description for every Measured BTS
+ for (double gpsX : Xcoords) {
+ for (double gpsY : Ycoords) {
+ // because within GSMmap, every cell of the array is
+ // initialized, no null pointer exception will occur. only a
+ // empty list will be "thrown" but it doesn't hurt
+ ArrayList<SingleBTS> currentBTSList = map
+ .getBTSList(gpsX, gpsY);
+
+ // traverse the ListBTS to find out if a BTS with the current
+ // name
+ // exists on this coordinate. Tell if a BTS was written to file
+
+ writePlacemarkDetails(currentBTSList, btsName, gpsX, gpsY,
+ uplink);
+
+ }
+
+ }
+
+ // Polygon Coordinates
+ }
+
+ private void writePlacemarkDetails(List<SingleBTS> btsList,
+ SingleBTS btsName, double coordX, double coordY, boolean uplink)
+ throws IOException {
+ // if the current field was empty, so is the btsList. But still it is
+ // initilized, so there is no nullpointer exception!
+ String name;
+ for (SingleBTS singleBTS : btsList) {
+ // maybe its null, then continue with next
+ if (singleBTS == null)
+ continue;
+
+ // get correct output String for UL or DL
+ if (uplink)
+ name = singleBTS.ULtoString();
+ else
+ name = singleBTS.DLtoString();
+ // you can only draw uplink if you've got a FullBTS!
+ if ((singleBTS.ARFCN == btsName.ARFCN && (!uplink || singleBTS.fullBTS))) {
+ if (uplink)
+ name = singleBTS.ULtoString();
+ else
+ name = singleBTS.DLtoString();
+ // draw it!
+ br.write("<Placemark> \n");
+ br.write("<visibility>1</visibility>\n");
+ br.write("<name>" + name + "</name>\n");
+
+ writeStyleIdentifier(singleBTS, uplink);
+
+ br.write("<Polygon>\n");
+ br.write("<tessellate>1</tessellate>\n");
+ br.write("<outerBoundaryIs>\n");
+ br.write("<LinearRing>\n");
+ br.write("<coordinates>\n");
+
+ writePolygonCoordinates(coordX, coordY, map.accuracy);
+
+ br.write("</coordinates>\n");
+ br.write("</LinearRing>\n");
+ br.write("</outerBoundaryIs>\n");
+ br.write("</Polygon>\n");
+ br.write("</Placemark>\n");
+
+ // if (singleBTS.name.equals("neuer Name")) {
+ // System.out.print("hier! " + coordX + "/" + coordY);
+ // System.out.println(" Xcoord results to array "
+ // + map.searchBestX(coordX));
+ // }
+
+ }
+
+ }
+ }
+
+ private void writeStyleIdentifier(SingleBTS bts, boolean uplink)
+ throws IOException {
+ int btsRXvalue;
+ if (uplink)
+ btsRXvalue = (int) bts.getUldB();
+ else
+ btsRXvalue = (int) bts.getDldB();
+
+ if (bts.isInterpolated()) {
+ // no FullBTS but interpolated: draw black line("#I")
+ br.write("<styleUrl>#I" + btsRXvalue + "</styleUrl>\n");
+ } else if (bts.fullBTS) {
+ // show the nice FullBTS line around
+ br.write("<styleUrl>#F" + btsRXvalue + "</styleUrl>\n");
+ } else {
+ // no line
+ br.write("<styleUrl>#" + btsRXvalue + "</styleUrl>\n");
+ }
+
+ }
+
+ private void writePolygonCoordinates(double coordX, double coordY,
+ double accuracy) throws IOException {
+ double accuracyX = accuracy / 2;
+ double accuracyY = accuracy;
+ // Point 1
+ br.write(coordX - accuracyX + "," + coordY + accuracyY + ",0,\n");
+ // Point 2
+ br.write(coordX + accuracyX + "," + coordY + accuracyY + ",0,\n");
+ // Point3
+ br.write(coordX + accuracyX + "," + (coordY - accuracyY) + ",0,\n");
+ // Point4
+ br.write((coordX - accuracyX) + "," + (coordY - accuracyY) + ",0,\n");
+ // End: Point 1
+ br.write((coordX - accuracyX) + "," + coordY + accuracyY + ",0\n");
+
+ }
+
+ public GoogleOut(LinkedList<GPScoordinate> GPSlog,
+ LinkedList<MeasurementReport> MRlog, String fileName)
+ throws IOException {
+ this.MRlog = MRlog;
+ // this.GPSlog = GPSlog;
+
+ br = new BufferedWriter(new FileWriter(new File(fileName)));
+ // write header
+ writeHeader();
+ // write viewpoint
+ br.write("<open>1</open>");
+ br.write(" <Folder>");
+ br.write("<name>Measurement Report " + map.IMSI + "</name>");
+ br.write(" <visibility>1</visibility>");
+ br.write("<description>MR from " + GPSlog.getFirst().time.toString()
+ + "</description>");
+ br.write(" <LookAt>");
+ br.write("<longitude>" + GPSlog.getFirst().coord2 + "</longitude>");
+ br.write("<latitude>" + GPSlog.getFirst().coord1 + "</latitude>");
+ br.write("<altitude>0</altitude>");
+ br.write("<heading>-34.82469740081282</heading>");
+ br.write("<tilt>0</tilt>");
+ br.write("<range>276.7870053764046</range>");
+ br.write("</LookAt>");
+
+ // write content
+ int i = 0;
+ int discarded = 0;
+ Iterator<GPScoordinate> GPSitr = GPSlog.iterator();
+ while (GPSitr.hasNext()) {
+ GPScoordinate GPS = GPSitr.next();
+ MeasurementReport MR = MRlog.get(i);
+
+ // do nothing if Time is not valid
+ if (Math.abs(MR.time.getTime() - GPS.time.getTime()) < 3000) {
+
+ br.write("<Placemark> \n");
+ br.write("<visibility>1</visibility>");
+ br.write("<name>" + MR.toString() + "</name>");
+ // br.write("<PolyStyle>");
+ // br.write("<color>bf00ff00</color>");
+ // br.write("</PolyStyle>");
+
+ // dl: Downlink - Network to phone
+ // up: Uplink - Phone to Network (has better perception for some
+ // reason)
+ br.write("<styleUrl>#" + MRlog.get(i).getFirstBTSdl()
+ + "</styleUrl>");
+
+ br.write("<Polygon>");
+ br.write("<tessellate>1</tessellate>");
+ br.write("<outerBoundaryIs>");
+ br.write("<LinearRing>");
+ br.write("<coordinates>");
+ // Point 1
+ System.out.println("this should not be started anymore");
+ br.write(GPS.coord2 - accuracy + "," + GPS.coord1 + accuracy
+ + ",0,");
+ // Point 2
+ br.write(GPS.coord2 + accuracy + "," + GPS.coord1 + accuracy
+ + ",0,");
+ // Point3
+ br.write(GPS.coord2 + accuracy + "," + (GPS.coord1 - accuracy)
+ + ",0,");
+ // Point4
+ br.write((GPS.coord2 - accuracy) + ","
+ + (GPS.coord1 - accuracy) + ",0,");
+ // End: Point 1
+ br.write((GPS.coord2 - accuracy) + "," + GPS.coord1 + accuracy
+ + ",0");
+
+ br.write("</coordinates>");
+ br.write("</LinearRing>");
+ br.write("</outerBoundaryIs>");
+ br.write("</Polygon>");
+ br.write("</Placemark>\n");
+ } else {
+ discarded++;
+
+ }
+
+ i++;
+ }
+ br.write("</Folder>");
+ br.write("</Document>");
+ br.write("</kml>");
+ br.flush();
+ br.close();
+ System.out.println("Discarded Coordinates: " + discarded);
+
+ }
+
+ @SuppressWarnings("unused")
+ private int getMin() {
+ Iterator<MeasurementReport> itr = MRlog.iterator();
+ MeasurementReport current;
+ int min = 0;
+ while (itr.hasNext()) {
+ current = itr.next();
+ if (current.getFirstBTSul() < min)
+ min = current.getFirstBTSul();
+ }
+ return min;
+
+ }
+
+ @SuppressWarnings("unused")
+ private int getMax() {
+ Iterator<MeasurementReport> itr = MRlog.iterator();
+ MeasurementReport current;
+ int max = -999;
+ while (itr.hasNext()) {
+ current = itr.next();
+ if (current.getFirstBTSul() > max)
+ max = current.getFirstBTSul();
+ }
+ return max;
+ }
+
+ @SuppressWarnings("unused")
+ private int getSteps() {
+ Iterator<MeasurementReport> itr = MRlog.iterator();
+ int i = 0;
+ while (itr.hasNext()) {
+ itr.next();
+ i++;
+ }
+ return i;
+ }
+
+ @SuppressWarnings("unused")
+ private String toHex(int i) {
+ String out = Integer.toHexString(Math.abs(i));
+ if (out.length() == 4)
+ return (out + "000");
+ if (out.length() == 5)
+ return (out + "00");
+ if (out.length() == 6)
+ return (out + "0");
+ if (out.length() == 7)
+ return (out);
+ return out;
+
+ }
+
+ // strength -30 to -120
+ // yellow at -75
+ private String getColor(int strength) {
+ int green = 0;
+ int red = 0;
+ // yellow at -75
+ if (strength > -75) {
+ green = 255;
+ red = 256 - Math.abs((256 / 45) * (-75 - strength));
+
+ } else {
+ // transient green from now on
+ red = 255;
+ green = Math.abs((256 / 45) * (-120 - strength));
+ }
+ // int green = 256 - Math.abs((256 / 90) * (-120 - strength));
+ // int red = Math.abs((256 / 90) * (-120 - strength));
+ // int result = red << 24 | green
+ if ((green > 255) || (red > 255))
+ System.out.println("Zu groß bei strength= " + strength + ",Rot: "
+ + red + "Grün: " + green);
+ if (green > 255)
+ green = 255;
+ if (red > 255)
+ red = 255;
+ // return ("7f00" + Integer.toHexString(red) +
+ // Integer.toHexString(green));
+ // return ("ff00" + Integer.toHexString(red) +
+ // Integer.toHexString(green));
+ // return ("ff00" + Integer.toHexString(red) +
+ // Integer.toHexString(green));
+ return ("ff00" + Integer.toHexString(green) + Integer.toHexString(red));
+
+ }
+
+ private void writeHeader() throws IOException {
+ br.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ br.write("<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n");
+ br.write(" <Document>\n");
+ br.write("<name>Measurement Report " + map.IMSI + "</name>\n");
+ br.write("<open>1</open>\n");
+
+ // style: color for signal strength from -30db to -120db
+ // color red = #FF0000 (16711680)
+ // color green = #00FF00 (65280)
+
+ // styles for normal BTS
+ for (int style = -30; style >= -120; style--) {
+
+ // int step = (16711680 - 65280) / getSteps();
+ // for (int i = getMin(); i <= getMax(); i++) {
+
+ br.write("<Style id=\"" + style + "\"> \n");
+ br.write("<PolyStyle> \n");
+ br.write("<color>" + getColor(style) + "</color> \n");
+ br.write("</PolyStyle> \n");
+ br.write("<LineStyle>\n");
+ // br.write("<color>" + getColor(style) + "</color>\n");
+ br.write("<color>" + 00000000 + "</color>\n");
+ br.write("</LineStyle>\n");
+ br.write("</Style> \n");
+ }
+
+ // styles for Full BTS: full white ffffff, no transparency:ff
+ for (int style = -30; style >= -120; style--) {
+ br.write("<Style id=\"F" + style + "\"> \n");
+ br.write("<PolyStyle> \n");
+ br.write("<color>" + getColor(style) + "</color> \n");
+ br.write("</PolyStyle> \n");
+ br.write("<LineStyle>\n");
+ // // br.write("<color>" + getColor(style) + "</color>\n");
+ br.write("<color>" + "ffffffff" + "</color>\n");
+ br.write("<width>2</width>\n");
+ br.write("</LineStyle>\n");
+ br.write("</Style> \n");
+ }
+
+ // styles for Interpolated BTS: full black 000000, no transparency:ff
+ for (int style = -30; style >= -120; style--) {
+ br.write("<Style id=\"I" + style + "\">\n");
+ br.write("<PolyStyle>\n");
+ br.write("<color>" + getColor(style) + "</color>\n");
+ br.write("</PolyStyle>\n");
+ br.write("<LineStyle>\n");
+ // br.write("<color>" + getColor(style) + "</color>\n");
+ br.write("<color>" + "ff000000" + "</color>\n");
+ br.write("<width>2</width>\n");
+ br.write("</LineStyle>\n");
+ br.write("</Style>\n");
+ }
+
+ }
+
+ /**
+ * Writes Probabilitymap to file.
+ *
+ * @param scoremap
+ * @param file
+ * @throws IOException
+ */
+ public void writeProbability(double[][] scoremap, String file)
+ throws IOException {
+ BufferedWriter br = new BufferedWriter(new FileWriter(new File(file)));
+ writeProbHeader(br);
+ for (int x = 0; x < map.Xcoords.length; x++) {
+ for (int y = 0; y < map.Ycoords.length; y++) {
+ if (scoremap[x][y] > 0) {
+ writeProbabilityLandmark(x, y, scoremap, br);
+ }
+ }
+ }
+ br.write("</Folder> \n");
+ br.write("</Document>");
+ br.write("</kml>");
+ br.flush();
+ br.close();
+ }
+
+ private void writeProbabilityLandmark(int x, int y, double[][] scoremap,
+ BufferedWriter br) throws IOException {
+ int score = (int) (scoremap[x][y] * 100);
+
+ br.write("<Placemark> \n");
+ br.write("<visibility>1</visibility>\n");
+ br.write("<name>" + score + "</name>\n");
+
+ br.write("<styleUrl>#" + score + "</styleUrl>\n");
+
+ br.write("<Polygon>\n");
+ br.write("<tessellate>1</tessellate>\n");
+ br.write("<outerBoundaryIs>\n");
+ br.write("<LinearRing>\n");
+ br.write("<coordinates>\n");
+
+ // draw the square
+ double accuracyX = map.accuracy;
+ double accuracyY = map.accuracy;
+ double coordX = map.Xcoords[x];
+ double coordY = map.Ycoords[y];
+ br.write(coordX - accuracyX + "," + coordY + accuracyY + ",0,\n");
+ // Point 2
+ br.write(coordX + accuracyX + "," + coordY + accuracyY + ",0,\n");
+ // Point3
+ br.write(coordX + accuracyX + "," + (coordY - accuracyY) + ",0,\n");
+ // Point4
+ br.write((coordX - accuracyX) + "," + (coordY - accuracyY) + ",0,\n");
+ // End: Point 1
+ br.write((coordX - accuracy) + "," + coordY + accuracy + ",0\n");
+
+ br.write("</coordinates>\n");
+ br.write("</LinearRing>\n");
+ br.write("</outerBoundaryIs>\n");
+ br.write("</Polygon>\n");
+ br.write("</Placemark>\n");
+
+ }
+
+ private void writeProbHeader(BufferedWriter br) throws IOException {
+ br.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ br.write("<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n");
+ br.write(" <Document>\n");
+ br.write("<name> Probability map </name> \n");
+ br.flush();
+ br.write("<open>1</open>\n");
+
+ // style: color for probability from 0% to 100%
+ // color red = #FF0000 (16711680)
+ // color green = #00FF00 (65280)
+
+ // styles for probability
+ for (int style = 0; style <= 100; style++) {
+
+ // int step = (16711680 - 65280) / getSteps();
+ // for (int i = getMin(); i <= getMax(); i++) {
+
+ br.write("<Style id=\"" + style + "\"> \n");
+ br.write("<PolyStyle> \n");
+ br.write("<color>" + getProbabilityColor(style) + "</color> \n");
+ br.write("</PolyStyle> \n");
+ br.write("<LineStyle>\n");
+ // br.write("<color>" + getColor(style) + "</color>\n");
+ br.write("<color>" + 00000000 + "</color>\n");
+ br.write("</LineStyle>\n");
+ br.write("</Style> \n");
+ }
+ br.write(" <Folder>\n");
+ br.write("<name>Probability</name>");
+ br.write(" <visibility>1</visibility>\n");
+ br.write("<description>Probability Map</description>\n");
+ br.write(" <LookAt>\n");
+ br.write("<longitude>" + (map.maxX + map.minX) / 2 + "</longitude>\n");
+ br.write("<latitude>" + (map.maxY + map.minY) / 2 + "</latitude>\n");
+ br.write("<altitude>0</altitude>\n");
+ br.write("<heading>0.0</heading>\n");
+ br.write("<tilt>0</tilt>\n");
+ br.write("<range>276.0</range>\n");
+ br.write("</LookAt>\n");
+
+ }
+
+ private String getProbabilityColor(int probability) {
+
+ int greenp = (int) (probability * 2.55);
+ return ("ff00" + Integer.toHexString(greenp) + "00");
+
+ /*
+ * // probability is from 0 - 100 int green = 0; int red = 0; // yellow
+ * at -75 if (probability > 70) { green = 255; red = 256 - Math.abs((256
+ * / 30) * (-70 - probability));
+ *
+ * } else { // transient green from now on red = 255; green =
+ * Math.abs((256 / 70) * (-30 - probability)); } // int green = 256 -
+ * Math.abs((256 / 90) * (-120 - strength)); // int red = Math.abs((256
+ * / 90) * (-120 - strength)); // int result = red << 24 | green if
+ * ((green > 255) || (red > 255))
+ * System.out.println("Zu groß bei strength= " + probability + ",Rot: "
+ * + red + "Grün: " + green); if (green > 255) green = 255; if (red >
+ * 255) red = 255; // return ("7f00" + Integer.toHexString(red) + //
+ * Integer.toHexString(green)); // return ("ff00" +
+ * Integer.toHexString(red) + // Integer.toHexString(green)); // return
+ * ("ff00" + Integer.toHexString(red) + // Integer.toHexString(green));
+ * return ("ff00" + Integer.toHexString(green) +
+ * Integer.toHexString(red));
+ */
+ }
+}