summaryrefslogtreecommitdiffstats
path: root/helper
diff options
context:
space:
mode:
Diffstat (limited to 'helper')
-rw-r--r--helper/Distance.java75
-rw-r--r--helper/Extrapolate.java508
-rw-r--r--helper/FunctionFit.java91
-rw-r--r--helper/LMfunc.java37
-rw-r--r--helper/ListBTS.java300
-rw-r--r--helper/ListGPS.java191
-rw-r--r--helper/Polygons.java34
7 files changed, 1236 insertions, 0 deletions
diff --git a/helper/Distance.java b/helper/Distance.java
new file mode 100644
index 0000000..680998b
--- /dev/null
+++ b/helper/Distance.java
@@ -0,0 +1,75 @@
+package helper;
+
+import DataStructure.GPScoordinate;
+
+/**
+ * @author richy
+ */
+public class Distance {
+
+ public static void main(String[] args) {
+ GPScoordinate coord1 = new GPScoordinate(null, 52.517, 'N', 13.4, 'E',
+ true);
+ GPScoordinate coord2 = new GPScoordinate(null, 35.7, 'N', 139.767, 'E',
+ true);
+ System.out.println(calc(coord1, coord2));
+
+ System.out.println(calc(52.517, 13.4, 35.7, 139.767));
+ }
+
+ /**
+ * Returns distance in kilometers. see
+ * http://de.wikipedia.org/wiki/Orthodrome
+ *
+ * @param coord1
+ * GPScoordinate Point 1
+ * @param coord2
+ * GPScoordinate Point 2
+ * @return distance in Kilometer
+ */
+ static public double calc(GPScoordinate coord1, GPScoordinate coord2) {
+ double a = DEGtoRAD(coord1.coord1);
+ double b = DEGtoRAD(coord1.coord2);
+ double c = DEGtoRAD(coord2.coord1);
+ double d = DEGtoRAD(coord2.coord2);
+
+ double angle = Math.acos(Math.sin(a) * Math.sin(c) + Math.cos(a)
+ * Math.cos(c) * Math.cos(d - b));
+ double distance = angle * 6370;
+ return distance;
+ }
+
+ /**
+ * Returns distance in kilometers
+ *
+ * @param coordN1
+ * DEC (decimal) value coordinate point 1 N/S (y-axis)
+ * @param coordE1
+ * DEC (decimal) value coordinate point 1 E/W (x-axis)
+ * @param coordN2
+ * DEC (decimal) value coordinate point 2 N/S (y-axis)
+ * @param coordE2
+ * DEC (decimal) value coordinate point 2 E/W (x-axis)
+ * @return
+ */
+
+ static public double calc(double coordN1, double coordE1, double coordN2,
+ double coordE2) {
+ GPScoordinate coord1 = new GPScoordinate(null, coordN1, 'N', coordE1,
+ 'E', true);
+ GPScoordinate coord2 = new GPScoordinate(null, coordN2, 'N', coordE2,
+ 'E', true);
+ return calc(coord1, coord2);
+ }
+
+ static private double DEGtoRAD(double deg) {
+ // see wiki http://de.wikipedia.org/wiki/Radiant_%28Einheit%29
+ return deg * 0.017453293d;
+ }
+
+ @SuppressWarnings("unused")
+ static private double RADtoDEG(double rad) {
+ // see wiki http://de.wikipedia.org/wiki/Radiant_%28Einheit%29
+ return rad * 57.29577951d;
+ }
+}
diff --git a/helper/Extrapolate.java b/helper/Extrapolate.java
new file mode 100644
index 0000000..40b238b
--- /dev/null
+++ b/helper/Extrapolate.java
@@ -0,0 +1,508 @@
+package helper;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import DataStructure.SingleBTS;
+
+public class Extrapolate {
+ private static final int SP = 4;
+
+ public static void main(String[] args) {
+ // String[] args2 = { "15.1", "167.16", "15.2", "167.27", "15.3",
+ // "167.39", "14", "165.85", "15.2", "167.5" };
+ String[] args2 = { "2", "5.4", "3", "6" };
+ args = args2;
+ System.out
+ .println("Approximationsfunktionen zur Inter- und Extrapolation\n"
+ + "Kommentare siehe:\n"
+ + "http://www.torsten-horn.de/techdocs/java-approximationsfunktionen.htm");
+
+ if (args == null || args.length < 2 || args.length % 2 != 0) {
+ System.out
+ .println("\nBitte eine Menge an x-/y-Wertepaaren angeben "
+ + "(Werte durch Leerzeichen getrennt).");
+ return;
+ }
+
+ double[] xyArr = convertStringArrToDoubleArr(args);
+ ArrayList<RegressionResult> result = new ArrayList<RegressionResult>();
+
+ // Verschiedene Regressionen:
+ result.add(calculateLinearRegression(xyArr));
+ result.add(calculatePowerRegression(xyArr));
+ result.add(calculatelog10arithmicRegression(xyArr));
+ result.add(calculateExponentialRegression(xyArr));
+ result.add(calculateOneMinusExponentialRegression(xyArr));
+
+ boolean atLeastOne = false;
+ for (Iterator<RegressionResult> itr = result.iterator(); itr.hasNext();) {
+ RegressionResult res = itr.next();
+ atLeastOne |= res != null;
+ if (res != null)
+ System.out.println("\n"
+ + linksbuendigerString(res.titel + ":", " ")
+ + linksbuendigerString(res.formel,
+ " ")
+ + " (Bestimmtheitsmass = " + res.rr + ")");
+ }
+
+ if (atLeastOne) {
+ System.out.print("\nx y ");
+ for (Iterator<RegressionResult> itr = result.iterator(); itr
+ .hasNext();) {
+ RegressionResult res = itr.next();
+ if (res != null)
+ System.out.print(linksbuendigerString(res.titel,
+ " "));
+ }
+ System.out.println();
+ for (int i = 0; i < args.length && i < 20; i += 2) {
+ System.out.print(linksbuendigerString("x=" + args[i] + ",",
+ " ")
+ + linksbuendigerString(" y=" + args[i + 1] + ":",
+ " "));
+ for (Iterator<RegressionResult> itr = result.iterator(); itr
+ .hasNext();) {
+ RegressionResult res = itr.next();
+ if (res != null)
+ System.out
+ .print(linksbuendigerString(
+ " "
+ + roundSignificant(
+ res.approxFunction
+ .execute(
+ res.a,
+ res.b,
+ xyArr[i]),
+ SP), " "));
+ }
+ System.out.println();
+ }
+ if (args.length > 20) {
+ System.out.println("...");
+ }
+ }
+ }
+
+ public static SingleBTS extrapolateLogDL(List<SingleBTS> list, double x,
+ SingleBTS extrapolateThis, int sendingStrength) {
+ if (list == null || list.isEmpty()) {
+ return null;
+ }
+ double[] array = BTStoArrayDL(list, extrapolateThis, sendingStrength);
+ // log10:
+ RegressionResult result = calculatelog10arithmicRegression(array);
+ // linear:
+ // RegressionResult result = calculateLinearRegression(array);
+ double DL = result.approxFunction.execute(result.a, result.b, x);
+
+ // add Signal Strenght back again
+ DL = DL + sendingStrength;
+ // if (DL < -115 || DL > -47 || Double.isNaN(DL))
+ // return null;
+ if (Double.isNaN(DL))
+ return null;
+ if (DL < -115)
+ DL = -115;
+ if (DL > -47)
+ DL = -47;
+ SingleBTS interpolated = new SingleBTS(extrapolateThis.ARFCN, 0, DL,
+ true, new Date(), extrapolateThis.name);
+ return interpolated;
+
+ }
+
+ /**
+ *
+ * @param list
+ * @param x
+ * @param extrapolateThis
+ * @param sendingStrength
+ * is SignalStrength from the cell phone: About 1 W and 2 dBi
+ * @return
+ */
+ public static SingleBTS extrapolateLogUL(List<SingleBTS> list, double x,
+ SingleBTS extrapolateThis, int sendingStrength) {
+ if (list == null || list.isEmpty()) {
+ return null;
+ }
+ double[] array = BTStoArrayUL(list, extrapolateThis, sendingStrength);
+ if (array == null) {
+ return null;
+ }
+ // log10:
+ RegressionResult result = calculatelog10arithmicRegression(array);
+ // linear:
+ // RegressionResult result = calculateLinearRegression(array);
+
+ if (result == null) {
+ return null;
+ }
+ double UL = result.approxFunction.execute(result.a, result.b, x);
+ // add the sendingStrength back on
+ UL = UL + sendingStrength;
+ if (Double.isNaN(UL))
+ return null;
+ if (UL < -115)
+ UL = -115;
+ if (UL > -47)
+ UL = -47;
+ SingleBTS interpolated = new SingleBTS(extrapolateThis.ARFCN, UL, 0,
+ true, new Date(), extrapolateThis.name);
+ interpolated.fullBTS = true;
+ // interpolated.interpolated = true;
+ return interpolated;
+
+ }
+
+ /**
+ *
+ * @param list
+ * @param extrapolateThis
+ * @param sendingStrength
+ * is the Signalstrength in dB that the BTS sends (Antenna Gain +
+ * Amplifier + Power)
+ * @return
+ */
+ private static double[] BTStoArrayDL(List<SingleBTS> list,
+ SingleBTS extrapolateThis, int sendingStrength) {
+ ArrayList<Double> array = new ArrayList<Double>();
+
+ // double[] array = new double[list.size() * 2];
+
+ for (int i = 0; i < list.size(); i++) {
+ SingleBTS currentElement = list.get(i);
+ if (currentElement != null
+ && currentElement.ARFCN == extrapolateThis.ARFCN) {
+ array.add(currentElement.distance);
+ array.add(currentElement.getDldB() - sendingStrength);
+ }
+ }
+
+ double[] doublearray = new double[array.size()];
+
+ for (int i = 0; i < doublearray.length; i++) {
+ doublearray[i] = array.get(i);
+ }
+ return doublearray;
+ }
+
+ private static double[] BTStoArrayUL(List<SingleBTS> list,
+ SingleBTS extrapolateThis, int sendingStrength) {
+ ArrayList<Double> array = new ArrayList<Double>();
+
+ for (int i = 0; i < list.size(); i++) {
+ SingleBTS currentElement = list.get(i);
+ if (currentElement != null
+ && currentElement.ARFCN == extrapolateThis.ARFCN) {
+ array.add(currentElement.distance);
+ array.add(currentElement.getUldB() - sendingStrength);
+ }
+ }
+
+ double[] doublearray = new double[array.size()];
+ for (int i = 0; i < doublearray.length; i++) {
+ doublearray[i] = array.get(i);
+ }
+ return doublearray;
+ }
+
+ // Lineare Regression
+ // y = a + b * x
+ static RegressionResult calculateLinearRegression(double[] xyArr) {
+ if (xyArr == null || xyArr.length < 2 || xyArr.length % 2 != 0)
+ return null;
+
+ int n = xyArr.length / 2;
+ double xs = 0;
+ double ys = 0;
+ double xqs = 0;
+ double yqs = 0;
+ double xys = 0;
+
+ for (int i = 0; i < xyArr.length; i += 2) {
+ xs += xyArr[i];
+ ys += xyArr[i + 1];
+ xqs += xyArr[i] * xyArr[i];
+ yqs += xyArr[i + 1] * xyArr[i + 1];
+ xys += xyArr[i] * xyArr[i + 1];
+ }
+
+ RegressionResult abr = new RegressionResult();
+ double xm = xs / n;
+ double ym = ys / n;
+ double xv = xqs / n - (xm * xm);
+ double yv = yqs / n - (ym * ym);
+ double kv = xys / n - (xm * ym);
+ abr.rr = Math.min((kv * kv) / (xv * yv), 1);
+ abr.b = kv / xv;
+ abr.a = ym - abr.b * xm;
+ abr.titel = "Lin";
+ abr.formel = "y = " + roundSignificant(abr.a, SP) + " + "
+ + roundSignificant(abr.b, SP) + " * x";
+ abr.approxFunction = new ApproxFunction() {
+ public double execute(double a, double b, double x) {
+ return a + b * x;
+ }
+ };
+
+ return abr;
+ }
+
+ // Potenzielle Regression
+ // y = a * x^b
+ // Regression ueber: ln(y) = ln(a) + b * ln(x)
+ static RegressionResult calculatePowerRegression(double[] xyArr) {
+ if (xyArr == null || xyArr.length < 2 || xyArr.length % 2 != 0)
+ return null;
+
+ double[] xyArrConv = new double[xyArr.length];
+
+ for (int i = 0; i < xyArr.length; i += 2) {
+ if (xyArr[i] <= 0 || xyArr[i + 1] <= 0)
+ return null;
+ xyArrConv[i] = Math.log10(xyArr[i]);
+ xyArrConv[i + 1] = Math.log10(xyArr[i + 1]);
+ }
+
+ RegressionResult abr = calculateLinearRegression(xyArrConv);
+ if (abr == null)
+ return null;
+ abr.a = Math.exp(abr.a);
+ abr.titel = "Pow";
+ abr.formel = "y = " + roundSignificant(abr.a, SP) + " * x ^ "
+ + roundSignificant(abr.b, SP);
+ abr.approxFunction = new ApproxFunction() {
+ public double execute(double a, double b, double x) {
+ return a * Math.pow(x, b);
+ }
+ };
+
+ return abr;
+ }
+
+ // log10arithmische Regression
+ // y = a + b * ln(x)
+ public static RegressionResult calculatelog10arithmicRegression(
+ double[] xyArr) {
+ if (xyArr == null || xyArr.length < 2 || xyArr.length % 2 != 0)
+ return null;
+
+ double[] xyArrConv = new double[xyArr.length];
+
+ for (int i = 0; i < xyArr.length; i += 2) {
+ if (xyArr[i] <= 0)
+ return null;
+ xyArrConv[i] = Math.log10(xyArr[i]);
+ xyArrConv[i + 1] = xyArr[i + 1];
+ }
+
+ RegressionResult abr = calculateLinearRegression(xyArrConv);
+ if (abr == null)
+ return null;
+ abr.titel = "log10";
+ abr.formel = "y = " + roundSignificant(abr.a, SP) + " + "
+ + roundSignificant(abr.b, SP) + " * ln(x)";
+ abr.approxFunction = new ApproxFunction() {
+ public double execute(double a, double b, double x) {
+ return a + b * Math.log10(x);
+ }
+ };
+
+ return abr;
+ }
+
+ // Exponentielle Regression
+ // y = a * e^(b * x)
+ // Regression ueber: ln(y) = ln(a) + b * x
+ static RegressionResult calculateExponentialRegression(double[] xyArr) {
+ if (xyArr == null || xyArr.length < 2 || xyArr.length % 2 != 0)
+ return null;
+
+ double[] xyArrConv = new double[xyArr.length];
+
+ for (int i = 0; i < xyArr.length; i += 2) {
+ if (xyArr[i + 1] <= 0)
+ return null;
+ xyArrConv[i] = xyArr[i];
+ xyArrConv[i + 1] = Math.log10(xyArr[i + 1]);
+ }
+
+ RegressionResult abr = calculateLinearRegression(xyArrConv);
+ if (abr == null)
+ return null;
+ abr.a = Math.exp(abr.a);
+ abr.titel = "Exp";
+ abr.formel = "y = " + roundSignificant(abr.a, SP) + " * e ^ ("
+ + roundSignificant(abr.b, SP) + " * x)";
+ abr.approxFunction = new ApproxFunction() {
+ public double execute(double a, double b, double x) {
+ return a * Math.exp(b * x);
+ }
+ };
+
+ return abr;
+ }
+
+ // Gespiegelte und verschobene exponentielle Regression
+ // y = a * ( 1 - e^(-b * x) )
+ // Approximationsfunktion beginnt bei 0 und strebt gegen den Grenzwert
+ // "limit".
+ // Falls "limit" nicht bekannt ist: Iterativ naehern.
+ static RegressionResult calculateOneMinusExponentialRegression(
+ double[] xyArr, double limit) {
+ double[] xyArrTest = new double[xyArr.length];
+
+ for (int i = 0; i < xyArr.length; i += 2) {
+ xyArrTest[i] = -xyArr[i];
+ xyArrTest[i + 1] = limit - xyArr[i + 1];
+ }
+
+ RegressionResult abr = calculateExponentialRegression(xyArrTest);
+ if (abr == null)
+ return null;
+ abr.a = limit;
+ return abr;
+ }
+
+ // Gespiegelte und verschobene exponentielle Regression
+ // y = a * ( 1 - e^(-b * x) )
+ // Approximationsfunktion beginnt bei 0 und strebt gegen den Grenzwert
+ // "limit".
+ static RegressionResult calculateOneMinusExponentialRegression(
+ double[] xyArr) {
+ final double INCR_FACTOR = 1.001;
+ double yMax = 0;
+ if (xyArr == null || xyArr.length < 2 || xyArr.length % 2 != 0)
+ return null;
+
+ for (int i = 1; i < xyArr.length; i += 2)
+ yMax = Math.max(yMax, xyArr[i]);
+
+ double lim = searchMaximumFromFunctionFromX(yMax, INCR_FACTOR, xyArr,
+ new FunctionFromX() {
+ public double execute(double x, Object helpObject) {
+ RegressionResult abr = calculateOneMinusExponentialRegression(
+ (double[]) helpObject, x);
+ if (abr == null)
+ return 0;
+ return abr.rr;
+ }
+ });
+
+ RegressionResult abr = calculateOneMinusExponentialRegression(xyArr,
+ lim);
+
+ if (abr == null)
+ return null;
+ abr.titel = "1_E";
+ abr.formel = "y = " + roundSignificant(abr.a, SP) + " * ( 1 - e ^ (-"
+ + roundSignificant(abr.b, SP) + " * x) )";
+ abr.approxFunction = new ApproxFunction() {
+ public double execute(double a, double b, double x) {
+ return a * (1 - Math.exp(-b * x));
+ }
+ };
+
+ return abr;
+ }
+
+ // Suche den x-Wert fuer den die "FunctionFromX" ein Maximum hat
+ static double searchMaximumFromFunctionFromX(double xStart,
+ double incrFactor, Object helpObject, FunctionFromX functionFromX) {
+ double x1, x2, xTest;
+ double y1, y2, yTest;
+
+ x1 = x2 = xTest = xStart;
+ y1 = y2 = yTest = functionFromX.execute(xTest, helpObject);
+
+ for (int i = 0; i < 1000000; i++) {
+ xTest *= incrFactor;
+ yTest = functionFromX.execute(xTest, helpObject);
+ if (yTest < y1) {
+ x1 = xTest;
+ y1 = yTest;
+ break;
+ }
+ x2 = x1;
+ x1 = xTest;
+ y2 = y1;
+ y1 = yTest;
+ }
+
+ for (int i = 0; i < 1000000; i++) {
+ xTest = (x1 + x2) / 2;
+ yTest = functionFromX.execute(xTest, helpObject);
+ if (y2 >= y1) {
+ x1 = xTest;
+ y1 = yTest;
+ } else {
+ x2 = xTest;
+ y2 = yTest;
+ }
+ if (i > 10 && Math.abs(y2 - y1) < 1.0E-12) {
+ break;
+ }
+ }
+
+ return xTest;
+ }
+
+ private static double[] convertStringArrToDoubleArr(String[] strArr) {
+ if (strArr == null || strArr.length <= 0)
+ return null;
+
+ double[] dblArr = new double[strArr.length];
+
+ for (int i = 0; i < strArr.length; i++) {
+ strArr[i] = strArr[i].replace(',', '.');
+ dblArr[i] = Double.parseDouble(strArr[i]);
+ }
+
+ return dblArr;
+ }
+
+ private static double roundSignificant(double d, int significantPrecision) {
+ if (d == 0 || significantPrecision < 1 || significantPrecision > 14)
+ return d;
+ double mul10 = 1;
+ double minVal = Math.pow(10, significantPrecision - 1);
+ while (Math.abs(d) < minVal) {
+ mul10 *= 10;
+ d *= 10;
+ }
+ return Math.round(d) / mul10;
+ }
+
+ private static String linksbuendigerString(String s,
+ String fillStrWithWantLen) {
+ if (s != null) {
+ int len = s.length();
+ if (len < fillStrWithWantLen.length()) {
+ return (s + fillStrWithWantLen).substring(0,
+ fillStrWithWantLen.length());
+ }
+ }
+ return s;
+ }
+
+ static class RegressionResult {
+ double a;
+ double b;
+ double rr;
+ String titel;
+ String formel;
+ ApproxFunction approxFunction;
+ }
+
+ interface ApproxFunction {
+ double execute(double a, double b, double x);
+ }
+
+ interface FunctionFromX {
+ double execute(double x, Object helpObject);
+ }
+} \ No newline at end of file
diff --git a/helper/FunctionFit.java b/helper/FunctionFit.java
new file mode 100644
index 0000000..4fcf88e
--- /dev/null
+++ b/helper/FunctionFit.java
@@ -0,0 +1,91 @@
+package helper;
+
+import DataStructure.GSMMap;
+import DataStructure.SingleBTS;
+
+/**
+ * Fits GSM receive strength to youngs model at 1.8GHz
+ *
+ * @author richy
+ *
+ */
+public class FunctionFit {
+ final static double log1800 = (float) Math.log10(1800);
+
+ /**
+ * @param type
+ * 0-2 for open, suburban, city. If type is not in range 0...2,
+ * zero is returned
+ * @return Hata Model Parameter K for 1800MHz (precomputed)
+ */
+ @SuppressWarnings("unused")
+ private static double C(int type) {
+ // Parameter at the end of extendet Hata Model
+ switch (type) {
+ case 0:
+ return 31.924;
+ case 1:
+ return 11.9386;
+ default:
+ return 0;
+ }
+ }
+
+ /**
+ * Returns value a(h) of the Hata Model. Use this when calculating DL
+ * (Signal from BTS to MS)
+ *
+ * @param suburban
+ * false, if surrounding is open or with medium buildings. True
+ * if buildings > 15m exits
+ * @param ms_height
+ * height of mobile station antenna (typically around 1.6m)
+ * @return value for a(h2), partly pre computed
+ */
+ private static double a_DL(boolean suburban, double ms_height) {
+ if (suburban) {
+ return ((1.1 * log1800 - 0.7) * ms_height - (1.56 * log1800 - 0.8));
+ } else {
+ return 3.2 * Math.pow(Math.log10(11.75 * ms_height), 2) - 4.97;
+ }
+
+ }
+
+ /**
+ * Returns value a(h) of the Hata Model. Use this when calculating UL
+ * (Signal from MS to BTS)
+ *
+ * @param suburban
+ * false, if surrounding is open or with medium buildings. True
+ * if buildings > 15m exits
+ * @param ms_height
+ * height of mobile station antenna (typically around 1.6m)
+ * @return value for a(h2), partly pre computed
+ */
+ private static double a_UL(boolean suburban, double bts_height) {
+ return a_DL(suburban, bts_height);
+ }
+
+ public static double do_fit(boolean DL, double receive1, double receive2,
+ double receive3) {
+
+ return 0.0;
+ }
+
+ public static boolean try_extrapolation(GSMMap map, SingleBTS arfcn, int x,
+ int y) {
+ if (ListBTS.contains(map.map[x][y], arfcn)) {
+ // check if uplink can be extrapolated
+ if (ListBTS.containsUL(map.map[x][y], arfcn)) {
+ // nothing todo. map[x][y] contains DL and UL
+ } else {
+ // upload is missing. Try Interpolation here. BTS element
+ // already exists
+ }
+
+ } else {
+ // try Interpolation SingleBTS object does not exist
+ }
+ return false;
+ }
+}
diff --git a/helper/LMfunc.java b/helper/LMfunc.java
new file mode 100644
index 0000000..dc16381
--- /dev/null
+++ b/helper/LMfunc.java
@@ -0,0 +1,37 @@
+// LMfunc.java
+
+package helper;
+
+/**
+ * Caller implement this interface to specify the function to be minimized and
+ * its gradient.
+ *
+ * Optionally return an initial guess and some test data, though the LM.java
+ * only uses this in its optional main() test program. Return null if these are
+ * not needed.
+ */
+public interface LMfunc {
+
+ /**
+ * x is a single point, but domain may be mulidimensional
+ */
+ double val(double[] x, double[] a);
+
+ /**
+ * return the kth component of the gradient df(x,a)/da_k
+ */
+ double grad(double[] x, double[] a, int ak);
+
+ /**
+ * return initial guess at a[]
+ */
+ double[] initial();
+
+ /**
+ * return an array[4] of x,a,y,s for a test case; a is the desired final
+ * answer.
+ */
+ Object[] testdata();
+
+} // LMfunc
+
diff --git a/helper/ListBTS.java b/helper/ListBTS.java
new file mode 100644
index 0000000..dac45b0
--- /dev/null
+++ b/helper/ListBTS.java
@@ -0,0 +1,300 @@
+package helper;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+import DataStructure.SingleBTS;
+
+public class ListBTS {
+
+ /**
+ *
+ * @param list
+ * Where to search
+ * @param arfcn
+ * which BTS to search
+ * @return false if BTS not found or list or arfcn is null or empty. True if
+ * BTS is found
+ */
+ public static boolean contains(List<SingleBTS> list, SingleBTS arfcn) {
+ return contains(list, arfcn.ARFCN);
+ }
+
+ public static boolean contains(List<SingleBTS> list, int arfcn) {
+ if (list == null || list.isEmpty()) {
+ return false;
+ }
+ if (list instanceof LinkedList<?>) {
+ ListIterator<SingleBTS> itr = list.listIterator();
+ while (itr.hasNext()) {
+ SingleBTS element = itr.next();
+ if (element.ARFCN == arfcn)
+ return true;
+ }
+ } else {
+ for (int i = list.size() - 1; i >= 0; i--) {
+ if (list.get(i).ARFCN == arfcn) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public static boolean containsUL(List<SingleBTS> list, SingleBTS arfcn) {
+ for (SingleBTS current : list) {
+ if (current.ARFCN == arfcn.ARFCN && current.fullBTS)
+ return true;
+ }
+ return false;
+ }
+
+ public static int countDL(LinkedList<SingleBTS> list, SingleBTS arfcn) {
+ int count = 0;
+ for (SingleBTS current : list) {
+ if (current != null && current.ARFCN == arfcn.ARFCN)
+ count++;
+ }
+ return count;
+ }
+
+ public static int countUL(LinkedList<SingleBTS> list, SingleBTS arfcn) {
+ int count = 0;
+ for (SingleBTS current : list) {
+ if (current != null && current.fullBTS
+ && current.ARFCN == arfcn.ARFCN)
+ count++;
+ }
+ return count;
+ }
+
+ /**
+ * Searches the list for the _first_ BTS with same arfcn. Removes it from
+ * that list and returns the element
+ *
+ * @param list
+ * from which to search
+ * @param arfcn
+ * MR with ARFCN you search for
+ * @return Element from list that got deleted. Null if element is not
+ * present in list
+ */
+ public static SingleBTS removeARFCN(List<SingleBTS> list, SingleBTS arfcn) {
+ return removeARFCN(list, arfcn.ARFCN);
+ }
+
+ public static SingleBTS removeARFCN(List<SingleBTS> list, int arfcn) {
+ ListIterator<SingleBTS> itr = list.listIterator();
+ while (itr.hasNext()) {
+ SingleBTS element = itr.next();
+ if (element.ARFCN == arfcn) {
+ itr.remove();
+ return element;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Gets the first occurence of the specified arfcn from the list. Element
+ * stays in list
+ *
+ * @param list
+ * the list from where to extract the BTS
+ * @param arfcn
+ * arfcn to extract
+ * @return first SingleBTS that matches from the list. Null if Element is
+ * not present
+ */
+ public static SingleBTS getARFCN(List<SingleBTS> list, SingleBTS arfcn) {
+ if (list == null || arfcn == null) {
+ return null;
+ }
+ for (int i = 0; i < list.size(); i++) {
+ if (list.get(i).ARFCN == arfcn.ARFCN) {
+ return list.get(i);
+ }
+ }
+ return null;
+ }
+
+ public static ArrayList<SingleBTS> getAllARFCN(ArrayList<SingleBTS> list,
+ int arfcn) {
+ if (list == null || list.isEmpty()) {
+ return null;
+ }
+ boolean aHitWasFound = false;
+ ArrayList<SingleBTS> result = new ArrayList<SingleBTS>();
+ for (int i = 0; i < list.size(); i++) {
+ if (list.get(i).ARFCN == arfcn) {
+ result.add(list.get(i));
+ aHitWasFound = true;
+ }
+ }
+ if (aHitWasFound)
+ return result;
+ else
+ return null;
+ }
+
+ /**
+ * Gets the first occurence of the specified arfcn from the list. Element
+ * stays in list
+ *
+ * @param list
+ * the list from where to extract the BTS
+ * @param arfcn
+ * arfcn to extract
+ * @return first SingleBTS that matches from the list. Null if Element is
+ * not present
+ */
+ public static SingleBTS getARFCN(List<SingleBTS> list, int arfcn) {
+ for (int i = 0; i < list.size(); i++) {
+ if (list.get(i).ARFCN == arfcn) {
+ return list.get(i);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Takes a list. Returns a copy of that list without null-elements
+ *
+ * @param list
+ * ListBTS where all elements with null will be filtered out
+ * @return a copy of this list without null-elements. Null if the whole list
+ * is null
+ */
+ public static ArrayList<SingleBTS> removeNullElements(List<SingleBTS> list) {
+ if (list == null)
+ return null;
+ ArrayList<SingleBTS> list2 = new ArrayList<SingleBTS>();
+ boolean element_present = false;
+ for (SingleBTS element : list) {
+ if (element != null) {
+ element_present = true;
+ list2.add(element);
+ }
+ }
+ if (element_present)
+ return list2;
+ else
+ return null;
+ }
+
+ /**
+ * ListBTS all the unique SingleBTS's that occur in this list
+ *
+ * @param list
+ * ListBTS with SingleBTS's
+ * @return Array with the unique SingleBTS's. That is, every BTS in this
+ * Array occurs also in the list. Null if the list was empty
+ */
+ public static SingleBTS[] content(List<SingleBTS> list) {
+ // get first element of list.
+ // traverse list and delete every occurence of first element
+ // get next element
+ // copy list to destroy reference
+ LinkedList<SingleBTS> list2 = new LinkedList<SingleBTS>(list);
+ if (list2.isEmpty())
+ return null;
+ // int count = 0;
+ LinkedList<SingleBTS> output = new LinkedList<SingleBTS>();
+ while (!list2.isEmpty()) {
+ SingleBTS bts = list2.getFirst();
+ list2.removeFirst();
+ output.add(bts);
+ // remove the just added bts from the BTS-list
+ // speedup with listiterator
+ /*
+ * for (int i = 0; i < list2.size(); i++) { if (list2.get(i).ARFCN
+ * == bts.ARFCN) { list2.remove(i); i--; }
+ */
+ ListIterator<SingleBTS> itr = list2.listIterator();
+ SingleBTS testelement;
+ while (itr.hasNext()) {
+ testelement = itr.next();
+ if (testelement.ARFCN == bts.ARFCN) {
+ // same element found. Delete it
+ itr.remove();
+ // if we are on the first element, itr.previous will throw
+ // an exception. Just ignore it and go on
+ try {
+ itr.previous();
+ } catch (Exception e) {
+
+ }
+ }
+
+ }
+
+ }
+ return output.toArray(new SingleBTS[1]);
+ }
+
+ /**
+ * Takes two lists. Merges missing parameters. Interpolated BTS will be
+ * overwritten by real measurements. NOT IMPLEMENTED!!!!
+ *
+ * @param list1
+ * @param list2
+ * @return
+ */
+ public static LinkedList<SingleBTS> addMissing(LinkedList<SingleBTS> list1,
+ LinkedList<SingleBTS> list2) {
+ // LinkedList<SingleBTS> result = new LinkedList<SingleBTS>();
+ if ((list1 == null && list2 != null)) {
+ return list2;
+ }
+ if (list1 != null && list2 == null) {
+ return list1;
+ }
+ if (list1.isEmpty() && !list2.isEmpty()) {
+ return list2;
+ }
+ if (!list1.isEmpty() && list2.isEmpty()) {
+ return list1;
+ }
+
+ // for (SingleBTS element1 : list1) {
+ // for (SingleBTS element2 : list2) {
+ // TODO: Code here!
+ // }
+ // }
+ return null;
+ }
+
+ /**
+ * Takes all BTS with same arfcn and adds the Measurements together
+ *
+ * @param List
+ * @param content
+ * @return
+ */
+ public static ArrayList<SingleBTS> generateAveragedList(
+ ArrayList<SingleBTS> List, SingleBTS[] content) {
+ ArrayList<SingleBTS> output = new ArrayList<SingleBTS>();
+ // traverse every unique BTS
+ for (SingleBTS singleBTS : content) {
+ // initialize with ARFCN and Name
+ SingleBTS current = new SingleBTS(singleBTS.ARFCN, singleBTS.name);
+ // add everything from list. SingleBTS-Class takes only correct BTSs
+ for (SingleBTS measure : List) {
+ current.addBTSMeasure(measure);
+ }
+ output.add(current);
+ }
+
+ return output;
+ }
+
+ public static ArrayList<SingleBTS> generateAveragedList(
+ ArrayList<SingleBTS> List) {
+ SingleBTS[] content = content(List);
+ return generateAveragedList(List, content);
+ }
+
+}
diff --git a/helper/ListGPS.java b/helper/ListGPS.java
new file mode 100644
index 0000000..79b383a
--- /dev/null
+++ b/helper/ListGPS.java
@@ -0,0 +1,191 @@
+package helper;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import DataStructure.GPScoordinate;
+
+public class ListGPS {
+
+ /**
+ * Get the intersection between both lists. That is, if one coordinate is in
+ * both lists. add this coordinate to the returning set.
+ *
+ * @param list1
+ * @param list2
+ * @param threshold_dB
+ * when both coordinates are less than threshold_dB meters away,
+ * they count as identical. Threshold may be 0. Then only
+ * identical coordinates get used
+ * @return
+ */
+ public static LinkedList<GPScoordinate> intersect(
+ LinkedList<GPScoordinate> list1, LinkedList<GPScoordinate> list2,
+ int threshold) {
+ LinkedList<GPScoordinate> result = new LinkedList<GPScoordinate>();
+ if (list1 == null || list2 == null)
+ return result;
+ if (threshold == 0) {
+ for (GPScoordinate element1 : list1) {
+ if ((contains(list2, element1)) && !contains(result, element1)) {
+ result.add(element1);
+ }
+ }
+ return result;
+ } else {
+ for (GPScoordinate element1 : list1) {
+ result.addAll(getSimilarValues(list2, element1, threshold));
+
+ }
+ // remove null elements
+ result = removeNullElements(result);
+ // remove duplicate entries
+ GPScoordinate[] resultarray = content(result);
+ // clear result to reuse it
+ result = new LinkedList<GPScoordinate>();
+ if (resultarray == null)
+ return null;
+ for (int i = 0; i < resultarray.length; i++) {
+ result.add(resultarray[i]);
+ }
+ return result;
+ }
+ }
+
+ /**
+ *
+ * @param list
+ * where to search
+ * @param point
+ * get elements near to that point
+ * @param threshold_dB
+ * how far in meters may elements be away from the point
+ * @return LinkedList of elements near point. Every element is only added
+ * once
+ */
+ public static LinkedList<GPScoordinate> getSimilarValues(
+ LinkedList<GPScoordinate> list, GPScoordinate point, int threshold) {
+ if (list == null || list.isEmpty() || point == null)
+ return new LinkedList<GPScoordinate>();
+ LinkedList<GPScoordinate> result = new LinkedList<GPScoordinate>();
+ for (GPScoordinate element : list) {
+ if (Distance.calc(point, element) * 1000 < threshold
+ && !contains(result, element)) {
+ result.add(element);
+
+ }
+ }
+
+ return null;
+
+ }
+
+ public static LinkedList<GPScoordinate> intersect(
+ LinkedList<LinkedList<GPScoordinate>> nestedlist) {
+ LinkedList<GPScoordinate> result = new LinkedList<GPScoordinate>();
+ if (nestedlist.isEmpty())
+ return null;
+ if (nestedlist.size() == 1)
+ return nestedlist.getFirst();
+ // nestedlist has at least 2 elements. do intersect with both. Store in
+ // list. remove null elements first
+ nestedlist.add(removeNullElements(nestedlist.removeLast()));
+ nestedlist.addFirst(removeNullElements(nestedlist.removeFirst()));
+ result.addAll(intersect(nestedlist.removeFirst(),
+ nestedlist.removeLast(), 0));
+ // now do intersect with the rest. This could get a speedup by using
+ // pairwise intersection. would be O(log n) then.
+ while (!nestedlist.isEmpty()) {
+ nestedlist.addFirst(removeNullElements(nestedlist.removeFirst()));
+ result = intersect(result, nestedlist.removeFirst(), 0);
+ }
+ return result;
+ }
+
+ public static GPScoordinate[] content(List<GPScoordinate> list) {
+ // get clone. Not just reference/pointer
+ if (list == null || list.isEmpty())
+ return null;
+ ArrayList<GPScoordinate> list2 = new ArrayList<GPScoordinate>(list);
+ // int count = 0;
+ LinkedList<GPScoordinate> output = new LinkedList<GPScoordinate>();
+ while (!list2.isEmpty()) {
+ GPScoordinate gps = list2.get(0);
+ list2.remove(0);
+ output.add(gps);
+ // remove the just added bts from the GPS-list
+ for (int i = 0; i < list2.size(); i++) {
+ if (list2.get(i).equals(gps)) {
+ // remove every element in the list that is the same as the
+ // first
+ list2.remove(i); // WARNING: this is slow! Do it with list
+ // and iterator
+ i--;
+ }
+
+ }
+
+ }
+ return output.toArray(new GPScoordinate[1]);
+
+ }
+
+ /**
+ * true if list contains element (that is, coord1 and coord2 are identical)
+ *
+ * @param list
+ * @param element
+ * @return
+ */
+ public static boolean contains(LinkedList<GPScoordinate> list,
+ GPScoordinate element) {
+ if (element == null || list == null || list.isEmpty())
+ return false;
+ for (GPScoordinate current : list) {
+ if (current.equals(element))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Takes a list. Returns a copy of that list without null-elements
+ *
+ * @param list
+ * ListBTS where all elements with null will be filtered out
+ * @return a copy of this list without null-elements. Null if the whole list
+ * is null
+ */
+ public static LinkedList<GPScoordinate> removeNullElements(
+ LinkedList<GPScoordinate> list) {
+ if (list == null)
+ return null;
+ LinkedList<GPScoordinate> list2 = new LinkedList<GPScoordinate>();
+ boolean element_present = false;
+ for (GPScoordinate element : list) {
+ if (element != null) {
+ element_present = true;
+ list2.add(element);
+ }
+ }
+ if (element_present)
+ return list2;
+ else
+ return null;
+ }
+
+ public static LinkedList<LinkedList<GPScoordinate>> removeAllNullElements(
+ LinkedList<LinkedList<GPScoordinate>> nestedlist) {
+ LinkedList<LinkedList<GPScoordinate>> result = new LinkedList<LinkedList<GPScoordinate>>();
+ java.util.Iterator<LinkedList<GPScoordinate>> itr = result.iterator();
+ while (itr.hasNext()) {
+ LinkedList<GPScoordinate> intermediate = itr.next();
+ intermediate = removeNullElements(intermediate);
+ if (intermediate != null && !intermediate.isEmpty())
+ result.add(intermediate);
+ }
+ return result;
+ }
+
+}
diff --git a/helper/Polygons.java b/helper/Polygons.java
new file mode 100644
index 0000000..9d3c6ad
--- /dev/null
+++ b/helper/Polygons.java
@@ -0,0 +1,34 @@
+package helper;
+
+import java.awt.Polygon;
+
+public class Polygons {
+ public static double area(Polygon poly) {
+ double area = 0;
+ // make list out of polygon. see
+ // http://anklick-bar.de/matheprojekt/kurbel-gauss.pdf
+ Point[] list = new Point[poly.npoints + 2];
+
+ for (int i = 0; i < poly.npoints; i++) {
+ list[i] = new Point(poly.xpoints[i], poly.ypoints[i]);
+ }
+ list[poly.npoints] = new Point(poly.xpoints[0], poly.ypoints[0]);
+ list[poly.npoints + 1] = new Point(poly.xpoints[1], poly.ypoints[1]);
+ for (int i = 1; i <= poly.npoints; i++) {
+ // area of polygon is left to the line
+ area = area + (list[i + 1].y - list[i - 1].y) * list[i].x;
+ }
+ return area * (-1);
+
+ }
+}
+
+class Point {
+ int x;
+ int y;
+
+ public Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+}