FileDocCategorySizeDatePackage
BaseCluster.javaAPI DocAndroid 5.1 API6707Thu Mar 12 22:22:48 GMT 2015android.bordeaux.services

BaseCluster

public class BaseCluster extends Object

Fields Summary
public static String
TAG
public double[]
mCenter
protected static final int
VECTOR_LENGTH
private static final long
FORGETTING_ENUMERATOR
private static final long
FORGETTING_DENOMINATOR
protected HashMap
mHistogram
protected long
mDuration
protected String
mSemanticId
protected static final double
EARTH_RADIUS
Constructors Summary
public BaseCluster(android.location.Location location)


       
        mCenter = getLocationVector(location);
        mDuration = 0;
    
public BaseCluster(String semanticId, double longitude, double latitude, long duration)

        mSemanticId = semanticId;
        mCenter = getLocationVector(longitude, latitude);
        mDuration = duration;
    
Methods Summary
public voidabsorbCluster(android.bordeaux.services.BaseCluster cluster)

        averageCenter(cluster.mCenter, cluster.mDuration);
        absorbHistogram(cluster);
    
private voidabsorbHistogram(android.bordeaux.services.BaseCluster cluster)

        for (Map.Entry<String, Long> entry : cluster.mHistogram.entrySet()) {
            String timeLabel = entry.getKey();
            long duration = entry.getValue();

            if (mHistogram.containsKey(timeLabel)) {
                duration += mHistogram.get(timeLabel);
            }
            mHistogram.put(timeLabel, duration);
        }
        mDuration += cluster.mDuration;
    
protected voidaverageCenter(double[] newCenter, long newDuration)

        double weight = ((double) mDuration) / (mDuration + newDuration);
        double newWeight = 1f - weight;

        double norm = 0;
        for (int i = 0; i < VECTOR_LENGTH; ++i) {
            mCenter[i] = weight * mCenter[i] + newWeight * newCenter[i];
            norm += mCenter[i] * mCenter[i];
        }
        norm = Math.sqrt(norm);
        for (int i = 0; i < VECTOR_LENGTH; ++i) {
            mCenter[i] /= norm;
        }
    
private doublecomputeDistance(double[] vector1, double[] vector2)

        double product = 0f;
        for (int i = 0; i < VECTOR_LENGTH; ++i) {
            product += vector1[i] * vector2[i];
        }
        double radian = Math.acos(Math.min(product, 1f));
        return radian * EARTH_RADIUS;
    
public floatdistanceToCenter(android.location.Location location)

        return (float) computeDistance(mCenter, getLocationVector(location));
    
public floatdistanceToCluster(android.bordeaux.services.BaseCluster cluster)

        return (float) computeDistance(mCenter, cluster.mCenter);
    
public voidforgetPastHistory()

        mDuration *= FORGETTING_ENUMERATOR;
        mDuration /= FORGETTING_DENOMINATOR;

        for (Map.Entry<String, Long> entry : mHistogram.entrySet()) {
            String key = entry.getKey();
            long value = entry.getValue();

            value *= FORGETTING_ENUMERATOR;
            value /= FORGETTING_DENOMINATOR;

            mHistogram.put(key, value);
        }
    
public voidgenerateSemanticId(long index)

        mSemanticId = "cluser: " + String.valueOf(index);
    
protected doublegetCenterLatitude()

        return Math.toDegrees(Math.asin(mCenter[2]));
    
protected doublegetCenterLongitude()

        // Because latitude ranges from -90 to 90 degrees, cosPhi >= 0.
        double cosPhi = Math.cos(Math.asin(mCenter[2]));
        double longitude = Math.toDegrees(Math.asin(mCenter[1] / cosPhi));
        if (mCenter[0] < 0) {
            longitude = (longitude > 0) ? 180f - longitude : -180 - longitude;
        }
        return longitude;
    
public longgetDuration()

        return mDuration;
    
public final java.util.HashMapgetHistogram()

        return mHistogram;
    
protected double[]getLocationVector(android.location.Location location)

        return getLocationVector(location.getLongitude(), location.getLatitude());
    
protected double[]getLocationVector(double longitude, double latitude)

        double vector[] = new double[VECTOR_LENGTH];
        double lambda = Math.toRadians(longitude);
        double phi = Math.toRadians(latitude);

        vector[0] = Math.cos(lambda) * Math.cos(phi);
        vector[1] = Math.sin(lambda) * Math.cos(phi);
        vector[2] = Math.sin(phi);
        return vector;
    
public java.lang.StringgetSemanticId()

        return mSemanticId;
    
public booleanhasSemanticId()

        return mSemanticId != null;
    
protected voidnormalizeCenter()

        double norm = 0;
        for (int i = 0; i < VECTOR_LENGTH; ++i) {
            norm += mCenter[i] * mCenter[i];
        }
        norm = Math.sqrt(norm);
        for (int i = 0; i < VECTOR_LENGTH; ++i) {
            mCenter[i] /= norm;
        }
    
public booleanpassThreshold(long durationThreshold)

        // TODO: might want to keep semantic cluster
        return mDuration > durationThreshold;
    
public voidsetCluster(android.bordeaux.services.BaseCluster cluster)

        for (int i = 0; i < VECTOR_LENGTH; ++i) {
            mCenter[i] = cluster.mCenter[i];
        }
        mHistogram.clear();
        mHistogram.putAll(cluster.mHistogram);
        mDuration = cluster.mDuration;
    
public voidsetHistogram(java.util.Map histogram)

        mHistogram.clear();
        mHistogram.putAll(histogram);

        mDuration = 0;
        if (mHistogram.containsKey(TimeStatsAggregator.WEEKEND)) {
            mDuration += mHistogram.get(TimeStatsAggregator.WEEKEND);
        }
        if (mHistogram.containsKey(TimeStatsAggregator.WEEKDAY)) {
            mDuration += mHistogram.get(TimeStatsAggregator.WEEKDAY);
        }