public static void updateDeviceLocation(String deviceId) {

    if (!useParticleFilter) {
      // Standard Trilateration
      Map<DeviceDistance, DeviceLocation> devicesDistances = getScaledDeviceDistancePerPI(deviceId);
      if (devicesDistances == null || devicesDistances.size() == 0) return;

      Iterator<DeviceDistance> keys = devicesDistances.keySet().iterator();
      double[][] positions = new double[devicesDistances.size()][devicesDistances.size()];
      double[] distances = new double[devicesDistances.size()];

      int index = 0;
      while (keys.hasNext()) {
        DeviceDistance distance = keys.next();
        distances[index] = distance.getDistance();
        DeviceLocation piLocation = devicesDistances.get(distance);
        positions[index] = new double[] {piLocation.getX(), piLocation.getY()};
        index++;
      }

      double[] location = Trilateration.calculate(positions, distances);
      DeviceLocation deviceLocation = new DeviceLocation();
      deviceLocation.setDeviceId(deviceId);
      deviceLocation.setX(location[0]);
      deviceLocation.setY(location[1]);
    } else {
      // Particle Filter
      Map<DeviceDistance, DeviceLocation> deviceDistancePerPI =
          getScaledDeviceDistancePerPI(deviceId);
      ParticleFilter particleFilter = new ParticleFilter(deviceId, deviceDistancePerPI);
      DeviceLocation deviceLocation = particleFilter.calculate();
      GeodeClient.getInstance().updateDeviceLocation(deviceLocation);
    }
  }
  public static Map<DeviceDistance, DeviceLocation> getScaledDeviceDistancePerPI(String deviceId) {

    Map<DeviceDistance, DeviceLocation> deviceDistancePerPI =
        GeodeClient.getInstance().getDeviceDistancePerPI(deviceId);

    Iterator<DeviceDistance> distancesIt = deviceDistancePerPI.keySet().iterator();
    while (distancesIt.hasNext()) {

      DeviceDistance distance = distancesIt.next();
      distance.setDistance(distance.getDistance() * Scale.getInstance().getScaleFactor());
    }
    return deviceDistancePerPI;
  }