public Map<Integer, List<LocationBean>> groupPointsByWeightForContours(int interval) {
    Map<Integer, List<LocationBean>> groupings = new HashMap<Integer, List<LocationBean>>();
    boolean flag = false;
    int minutes = interval;

    while (flag == false) {
      List<LocationBean> currentGroup = new ArrayList<LocationBean>();
      for (LocationBean location : locations) {
        if (location.getGoogleContourWeightFloor() >= minutes) {
          LocationBean newLocation = new LocationBean(location);
          double newWeight = (double) minutes;
          newLocation.setWeight(newWeight);
          currentGroup.add(newLocation);
        }
      }

      if (currentGroup.size() == 0) {
        flag = true;
      } else {
        groupings.put(minutes, currentGroup);
      }

      minutes += interval;
    }

    return groupings;
  }
  public Map<Integer, List<LocationBean>> groupLocationsByWeight() {
    Map<Integer, List<LocationBean>> groupings = new HashMap<Integer, List<LocationBean>>();

    for (LocationBean location : this.locations) {
      int weight = location.getGoogleContourWeightFloor();

      if (!groupings.containsKey(weight)) {
        System.out.println(
            "Creating new grouping for weight: " + weight + " from " + location.getWeight());
        groupings.put(weight, new ArrayList<LocationBean>());
      }
      groupings.get(weight).add(location);
    }

    return groupings;
  }
  // very innefficient, but works well enough for simple testing
  public void printGrouping(List<LocationBean> grouping, LocationBean[][] locationArray) {
    int rows = locationArray[0].length;
    int cols = locationArray.length;
    LocationBean[][] groupedLocationArray = new LocationBean[cols][rows];

    for (int x = 0; x < rows; x++) {
      for (int y = 0; y < cols; y++) {
        for (LocationBean location : grouping) {
          if (location == locationArray[x][y]) {
            groupedLocationArray[x][y] = new LocationBean(1.0, 1.0, location.getWeight());
          }
        }
      }
    }

    printLocationWeightsAsMap(groupedLocationArray);
  }
  public double[][] createDistanceArray(List<LocationBean> locations) {
    double[][] distanceArray = new double[locations.size()][locations.size()];

    for (int x = 0; x < locations.size(); x++) {

      LocationBean startLocation = locations.get(x);
      for (int y = 0; y < locations.size(); y++) {
        LocationBean endLocation = locations.get(y);

        if (y <= x) {
          distanceArray[x][y] = 0.0;
        } else {
          distanceArray[x][y] = startLocation.getDistanceFrom(endLocation);
        }
      }
    }

    return distanceArray;
  }
  public Map<Integer, List<LocationBean>> clusterFromArray(
      double[][] distanceArray, List<LocationBean> locations, double distance) {
    Map<Integer, List<LocationBean>> groupings = new HashMap<Integer, List<LocationBean>>();
    int grouping = 1;
    for (LocationBean location : locations) {
      location.setGroup(0);
    }

    for (int x = 0; x < locations.size(); x++) {
      if (locations.get(x).getGroup() == 0) {
        while (groupings.containsKey(grouping)) {
          grouping++;
        }
        // System.out.println("Creating new group: " + grouping + " for point at " + x + " with name
        // " + locations.get(x).getName());
        locations.get(x).setGroup(grouping);
        groupings.put(grouping, new ArrayList<LocationBean>());
        groupings.get(grouping).add(locations.get(x));
      } else {
        grouping = locations.get(x).getGroup();
      }
      for (int y = 0; y < locations.size(); y++) {
        if (y > x) { // // avoid processing the duplicate half of the array
          if (distanceArray[x][y] <= distance) {
            if (locations.get(y).getGroup() == 0) {
              locations.get(y).setGroup(grouping);
              groupings.get(grouping).add(locations.get(y));
              // System.out.print(" +" + locations.get(y).getName() + " ");
            } else if (locations.get(y).getGroup() == grouping) {
              //// do nothing?
            } else { // combine groups
              int otherGroup = locations.get(y).getGroup();
              // System.out.println("Combining groups " + grouping + " (" +
              // groupings.get(grouping).size() + ") and " + otherGroup + "(" +
              // groupings.get(otherGroup).size() + ")");
              int originalSize = groupings.get(grouping).size();
              for (int i = 0; i < originalSize; i++) {
                // System.out.print(i + " ");
                groupings.get(otherGroup).add(groupings.get(grouping).remove(0));
              }
              locations.get(x).setGroup(otherGroup);
            }
          }
        }
      }
      // System.out.println("Group " + grouping + " has size " + groupings.get(grouping).size());
    }

    //// Prune empty groupings - not a necessary step, but helps clean up the result a bit.
    Set<Integer> keys = groupings.keySet();
    int maxKey = 0;
    for (Integer key :
        keys) { // since there is no gaurantee about consecutive group numbers, we have to go
                // through all possible keys
      if (key > maxKey) maxKey = key;
    }
    for (int i = 1; i <= maxKey; i++) {
      if (groupings.containsKey(i) && groupings.get(i).size() == 0) {
        // System.out.println("removing group " + i);
        groupings.remove(i);
      }
    }

    return groupings;
  }