<commit_before>package fr.jayps.android;

import android.location.Location;
import android.util.Log;
import android.content.Context;
import android.widget.Toast;

public class AdvancedLocation {
    private static final String TAG = "AdvancedLocation";
    
    protected class LocationWithExtraFields extends Location {

        public float distance = 0; // in m
        public LocationWithExtraFields(Location l) {
            super(l);
            this.distance = _distance;
        }
    }

    protected LocationWithExtraFields lastLocation = null;            // last received location
    protected LocationWithExtraFields lastGoodLocation = null;        // last location with accuracy below _minAccuracy
    protected LocationWithExtraFields lastGoodAscentLocation = null;  // last location with changed ascent
    protected LocationWithExtraFields lastGoodAscentRateLocation = null;  // last location with changed ascentRate
    protected LocationWithExtraFields firstLocation = null;           // first received location
    protected LocationWithExtraFields firstGoodLocation = null;       // first location with accuracy below _minAccuracy
    
    protected float _minAccuracy = 10;   // in m
    protected float _minAccuracyIni = _minAccuracy;
    
    // max value for _minAccuracy
    protected float _maxMinAccuracy = 50;   // in m
    
    // always remember that accuracy is 3x worth on altitude than on latitude/longitude
    protected float _minAccuracyForAltitudeChangeLevel1 = 4; // in m
    protected float _minAltitudeChangeLevel1 = 10; // in m
    protected float _minAccuracyForAltitudeChangeLevel2 = 7; // in m
    protected float _minAltitudeChangeLevel2 = 20; // in m
    protected float _minAccuracyForAltitudeChangeLevel3 = 12; // in m
    protected float _minAltitudeChangeLevel3 = 50; // in m
    protected long _minDeltaTimeForAscentRate = 120*1000; // in ms

    protected long _minDeltaTimeToSaveLocation = 3000; // in ms
    protected float _minDeltaDistanceToSaveLocation = 20;   // in m
    
    // min speed to compute _elapsedTime or _ascent
    // 0.3m/s <=> 1.08km/h
    protected float _minSpeedToComputeStats = 0.3f; // in m/s 
    
    public int nbOnLocationChanged = 0;
    public int nbGoodLocations = 0;
    protected int _nbBadAccuracyLocations = 0;
    
    protected float _distance = 0; // in m
    protected double _ascent = 0; // in m
    protected long _elapsedTime = 0; // in ms

    protected float _averageSpeed = 0; // in m/s
    protected float _ascentRate = 0; // in m/s
    
    protected float _slope = 0; // in %
    
    // debug levels
    public int debugLevel = 0;
    public int debugLevelToast = 0;

    

    protected Context _context = null;
    public AdvancedLocation() {
        this._context = null;
    }    
    public AdvancedLocation(Context context) {
        this._context = context;
    }
    
    // getters
    public double getAltitude() {
        if (lastGoodLocation != null) {
            return lastGoodLocation.getAltitude();
        }
        return 0;
    }
    public double getGoodAltitude() {
        if (lastGoodAscentLocation != null) {
            return lastGoodAscentLocation.getAltitude();
        }
        return 0;
    }

    public float getAccuracy() {
        if (lastLocation != null) {
            return lastLocation.getAccuracy();
        }
        return 0.0f;
    }    
    public float getSpeed() {
        if (lastLocation != null) {
            return lastLocation.getSpeed();
        }
        return 0.0f;
    }
    public float getAverageSpeed() {
        if ((_averageSpeed == 0) && (_elapsedTime > 0)) {
            // not yet calculated yet?
            _averageSpeed = (float) _distance / ((float) _elapsedTime / 1000f);
        }
        return _averageSpeed;
    }
    public long getElapsedTime() {
        return _elapsedTime;
    }
    public float getDistance() {
        return _distance;
    }    
    public double getAscent() {
        return _ascent;
    }
    public float getAscentRate() {
        return _ascentRate;
    }
    public float getSlope() {
        return _slope;
    }
    
    // setters
    public void setElapsedTime(long elapsedTime) {
        this._elapsedTime = elapsedTime;
    }
    public void setDistance(float distance) {
        this._distance = distance;
    }    
    public void setAscent(double ascent) {
        this._ascent = ascent;
    }

    public void onLocationChanged(Location location) {
        long deltaTime = 0;
        float deltaDistance = 0;
        double deltaAscent = 0;

        nbOnLocationChanged++;
        Logger("onLocationChanged: " +nbGoodLocations+"/"+nbOnLocationChanged+" Alt:"+ location.getAltitude() + "m-" + location.getAccuracy() + "m " + location.getLatitude() + "-" + location.getLongitude());
        
        if (firstLocation == null) {
            // 1st location
            firstLocation = lastLocation = new LocationWithExtraFields(location);
        }

        deltaTime = location.getTime() - lastLocation.getTime();
    
        if ((lastGoodLocation != null) && ((location.getTime() - lastGoodLocation.getTime()) < 1000)) {
            // less than 1000ms, skip this location
            return;
        }
        
        deltaDistance = location.distanceTo(lastLocation);

        if (location.getAccuracy() > _minAccuracy) {
            _nbBadAccuracyLocations++;
            if (_nbBadAccuracyLocations > 10) {
                float _prevMinAccuracy = _minAccuracy;
                
                _minAccuracy = (float) Math.floor(1.5f * _minAccuracy);
                
                if (_minAccuracy > _maxMinAccuracy) {
                    // max value for _minAccuracy
                    _minAccuracy = _maxMinAccuracy;
                }
                
                if (_minAccuracy != _prevMinAccuracy) {
                    _nbBadAccuracyLocations = 0;
                
                    Logger("Accuracy to often above _minAccuracy, augment _minAccuracy to " + _minAccuracy,  LoggerType.TOAST);
                }
            }
        }

        if (location.getAccuracy() <= _minAccuracy) {

            if (firstGoodLocation == null) {
                firstGoodLocation = new LocationWithExtraFields(location);
            }  
            <commit_msg>Check accuracy for first location<commit_after>package fr.jayps.android;

import android.location.Location;
import android.util.Log;
import android.content.Context;
import android.widget.Toast;

public class AdvancedLocation {
    private static final String TAG = "AdvancedLocation";
    
    protected class LocationWithExtraFields extends Location {

        public float distance = 0; // in m
        public LocationWithExtraFields(Location l) {
            super(l);
            this.distance = _distance;
        }
    }

    protected LocationWithExtraFields lastLocation = null;            // last received location
    protected LocationWithExtraFields lastGoodLocation = null;        // last location with accuracy below _minAccuracy
    protected LocationWithExtraFields lastGoodAscentLocation = null;  // last location with changed ascent
    protected LocationWithExtraFields lastGoodAscentRateLocation = null;  // last location with changed ascentRate
    protected LocationWithExtraFields firstLocation = null;           // first received location
    protected LocationWithExtraFields firstGoodLocation = null;       // first location with accuracy below _minAccuracy
    
    protected float _minAccuracy = 10;   // in m
    protected float _minAccuracyIni = _minAccuracy;
    
    // max value for _minAccuracy
    protected float _maxMinAccuracy = 50;   // in m
    
    // always remember that accuracy is 3x worth on altitude than on latitude/longitude
    protected float _minAccuracyForAltitudeChangeLevel1 = 4; // in m
    protected float _minAltitudeChangeLevel1 = 10; // in m
    protected float _minAccuracyForAltitudeChangeLevel2 = 7; // in m
    protected float _minAltitudeChangeLevel2 = 20; // in m
    protected float _minAccuracyForAltitudeChangeLevel3 = 12; // in m
    protected float _minAltitudeChangeLevel3 = 50; // in m
    protected long _minDeltaTimeForAscentRate = 120*1000; // in ms

    protected long _minDeltaTimeToSaveLocation = 3000; // in ms
    protected float _minDeltaDistanceToSaveLocation = 20;   // in m
    
    // min speed to compute _elapsedTime or _ascent
    // 0.3m/s <=> 1.08km/h
    protected float _minSpeedToComputeStats = 0.3f; // in m/s 
    
    public int nbOnLocationChanged = 0;
    public int nbGoodLocations = 0;
    protected int _nbBadAccuracyLocations = 0;
    
    protected float _distance = 0; // in m
    protected double _ascent = 0; // in m
    protected long _elapsedTime = 0; // in ms

    protected float _averageSpeed = 0; // in m/s
    protected float _ascentRate = 0; // in m/s
    
    protected float _slope = 0; // in %
    
    // debug levels
    public int debugLevel = 0;
    public int debugLevelToast = 0;

    

    protected Context _context = null;
    public AdvancedLocation() {
        this._context = null;
    }    
    public AdvancedLocation(Context context) {
        this._context = context;
    }
    
    // getters
    public double getAltitude() {
        if (lastGoodLocation != null) {
            return lastGoodLocation.getAltitude();
        }
        return 0;
    }
    public double getGoodAltitude() {
        if (lastGoodAscentLocation != null) {
            return lastGoodAscentLocation.getAltitude();
        }
        return 0;
    }

    public float getAccuracy() {
        if (lastLocation != null) {
            return lastLocation.getAccuracy();
        }
        return 0.0f;
    }    
    public float getSpeed() {
        if (lastLocation != null) {
            return lastLocation.getSpeed();
        }
        return 0.0f;
    }
    public float getAverageSpeed() {
        if ((_averageSpeed == 0) && (_elapsedTime > 0)) {
            // not yet calculated yet?
            _averageSpeed = (float) _distance / ((float) _elapsedTime / 1000f);
        }
        return _averageSpeed;
    }
    public long getElapsedTime() {
        return _elapsedTime;
    }
    public float getDistance() {
        return _distance;
    }    
    public double getAscent() {
        return _ascent;
    }
    public float getAscentRate() {
        return _ascentRate;
    }
    public float getSlope() {
        return _slope;
    }
    
    // setters
    public void setElapsedTime(long elapsedTime) {
        this._elapsedTime = elapsedTime;
    }
    public void setDistance(float distance) {
        this._distance = distance;
    }    
    public void setAscent(double ascent) {
        this._ascent = ascent;
    }

    public void onLocationChanged(Location location) {
        long deltaTime = 0;
        float deltaDistance = 0;
        double deltaAscent = 0;

        nbOnLocationChanged++;
        Logger("onLocationChanged: " +nbGoodLocations+"/"+nbOnLocationChanged+" Alt:"+ location.getAltitude() + "m-" + location.getAccuracy() + "m " + location.getLatitude() + "-" + location.getLongitude());
        
        if (location.getAccuracy() > _minAccuracy) {
            _nbBadAccuracyLocations++;
            if (_nbBadAccuracyLocations > 10) {
                float _prevMinAccuracy = _minAccuracy;
                
                _minAccuracy = (float) Math.floor(1.5f * _minAccuracy);
                
                if (_minAccuracy > _maxMinAccuracy) {
                    // max value for _minAccuracy
                    _minAccuracy = _maxMinAccuracy;
                }
                
                if (_minAccuracy != _prevMinAccuracy) {
                    _nbBadAccuracyLocations = 0;
                
                    Logger("Accuracy to often above _minAccuracy, augment _minAccuracy to " + _minAccuracy,  LoggerType.TOAST);
                }
            }
        }

        if (firstLocation == null) {
            // 1st location
            firstLocation = lastLocation = new LocationWithExtraFields(location);
        }

        deltaTime = location.getTime() - lastLocation.getTime();
    
        if ((lastGoodLocation != null) && ((location.getTime() - lastGoodLocation.getTime()) < 1000)) {
            // less than 1000ms, skip this location
            return;
        }
        
        deltaDistance = location.distanceTo(lastLocation);

        if (location.getAccuracy() <= _minAccuracy) {

            if (firstGoodLocation == null) {
                firstGoodLocation = new LocationWithExtraFields(location);
            }  
            
{'fraction_non_alphanumeric': 0.08074238578680203, 'fraction_numerical': 0.01300761421319797, 'mean_word_length': 2.1033718926901304, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2755128', 'n_tokens_mistral': 3649, 'n_tokens_neox': 3338, 'n_words': 926}