package no.weather.weatherProvider;
import java.security.InvalidParameterException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import no.weather.WeatherElement;
import no.weather.WeatherStation;
import no.weather.WeatherType;
import no.weather.misc.IProgress;
import no.weather.weatherProxy.wsKlima.WsKlimaProxy;
import android.content.Context;
import android.database.Cursor;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
public class WeatherProvider implements WeatherManagerInterface {
private WeatherDatabase db;
private final LocationManager locationManager;
private WsKlimaProxy wsklima;
public WeatherProvider(Context context) {
db = new WeatherDatabase(context);
locationManager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
wsklima = new WsKlimaProxy(context);
}
public static Location getLocationFromCursor(Cursor cursor,
Integer latColumn, Integer lonColumn, Location resiclerLocation) {
if (resiclerLocation == null) {
resiclerLocation = new Location("");
}
resiclerLocation.setLongitude(cursor.getDouble(lonColumn));
resiclerLocation.setLatitude(cursor.getDouble(latColumn));
return resiclerLocation;
}
public void addFavorite(String stationId, String stationProvider) {
db.addFavorite(stationId, stationProvider);
}
public void deleteFavorite(String stationId, String stationProvider) {
db.deleteFavorite(stationId, stationProvider);
}
public Cursor getAllStations() {
return db.getAllStations(null);
}
public Cursor getAllStations(String orderBy) {
return db.getAllStations(orderBy);
}
public Cursor getAllStations(String orderBy, CharSequence constraint) {
return db.getAllStations(orderBy, constraint);
}
public WeatherDatabase getDB() {
return db;
}
public Cursor getFavoriteStations(String orderBy) {
return db.getFavoriteStations(orderBy);
}
private Location getLocation() {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
return locationManager.getLastKnownLocation(locationManager
.getBestProvider(criteria, true));
}
public WeatherStation getNearestStation() {
return getNearestStation(null);
}
@SuppressWarnings("null")
public WeatherStation getNearestStation(List<WeatherType> minTypes) {
Location currentLocation = getLocation();
Location tempLocation;
List<Pair> distances = new LinkedList<Pair>();
Cursor cursor = db.getAllStations(null);
Integer latColumn = cursor
.getColumnIndex(WeatherDatabase.STATION_LATITUDE);
Integer lonColumn = cursor
.getColumnIndex(WeatherDatabase.STATION_LONGTITUDE);
if (cursor == null || cursor.getCount() == 0) {
updateStations();
return getNearestStation(minTypes);
}
cursor.moveToFirst();
tempLocation = new Location("");
tempLocation = getLocationFromCursor(cursor, latColumn, lonColumn,
tempLocation);
Pair pair = new Pair();
cursor.moveToNext();
while (!cursor.isLast()) {
tempLocation = getLocationFromCursor(cursor, latColumn, lonColumn,
tempLocation);
pair = new Pair(cursor.getPosition(),
tempLocation.distanceTo(currentLocation));
// pair.setKey(cursor.getPosition());
// pair.setValue(tempLocation.distanceTo(currentLocation));
distances.add(pair);
cursor.moveToNext();
}
Collections.sort(distances);
WeatherStation station = null;
if (minTypes != null) {
for (int i = 0; i < distances.size(); i++) {
cursor.moveToPosition(distances.get(i).getKey());
String id = cursor.getString(cursor
.getColumnIndex(WeatherDatabase.STATION_ID));
String provider = cursor.getString(cursor
.getColumnIndex(WeatherDatabase.STATION_PROVIDER));
Boolean stationIsDeleted = false;
try {
station = getStation(id, provider, true);
} catch (StationIsDeletedException e) {
stationIsDeleted = true;
}
// If the station have all types return else go to next
if (!stationIsDeleted && station.hasAllTypes(minTypes)) {
break;
}
station = null;
}
} else {
cursor.moveToPosition(distances.get(0).getKey());
String id = cursor.getString(cursor
.getColumnIndex(WeatherDatabase.STATION_ID));
String provider = cursor.getString(cursor
.getColumnIndex(WeatherDatabase.STATION_PROVIDER));
try {
station = getStation(id, provider, true);
} catch (StationIsDeletedException e) {
return getNearestStation(null);
}
}
// Close cursor and database
db.close();
cursor.close();
return station;
}
public WeatherStation getStation(String stationId, String stationProvider,
boolean getProvidedElementIfUnknown)
throws StationIsDeletedException {
WeatherStation station = db.getStation(stationId, stationProvider);
if (getProvidedElementIfUnknown && !station.getTypesIsKnown()) {
getWeatherTypes(station);
}
return station;
}
public Cursor getStationsFromProvider(String provider, String columns[]) {
return db.getStationsFromProvider(provider, columns);
}
public List<WeatherElement> getWeather(WeatherStation station, int year,
int month, int day, int hour) throws StationIsDeletedException {
if (!station.getTypesIsKnown()) {
station.setTypes(getWeatherTypes(station.getId(),
station.getProvider(), false));
}
if (station.getProvider().equals(WsKlimaProxy.PROVIDER))
return wsklima.getWeather(station, year, month, day, hour);
else
throw new InvalidParameterException(station.getProvider()
+ " is not provided in getWeatherNow");
}
public List<WeatherElement> getWeatherNow(WeatherStation station)
throws StationIsDeletedException {
return getWeatherNow(station,null,0);
}
public List<WeatherElement> getWeatherNow(WeatherStation station,IProgress progress, Integer maxAgeInSeconds)
throws StationIsDeletedException {
if (!station.getTypesIsKnown()) {
station.setTypes(getWeatherTypes(station.getId(),
station.getProvider(), false));
}
if (station.getProvider().equals(WsKlimaProxy.PROVIDER))
return wsklima.getWeatherNow(station,progress,maxAgeInSeconds);
else
throw new InvalidParameterException(station.getProvider()
+ " is not provided in getWeatherNow");
}
/**
* @param id
* Station id
* @param stationProvider
* Provider of the data
* @param includeNotProvidingElements
* @return
* @throws StationIsDeletedException
*/
public List<WeatherType> getWeatherTypes(String id, String stationProvider,
Boolean includeNotProvidingElements)
throws StationIsDeletedException {
if (stationProvider.equals(WsKlimaProxy.PROVIDER)) {
List<WeatherType> types = wsklima.getProvidedWeatherType(id,
includeNotProvidingElements);
db.setTypesToStation(types, id, stationProvider);
return types;
} else
throw new InvalidParameterException("Unknown provider");
}
/**
* Takes in a station and either get the types from the database or get it
* from the proxy
*
* @param station
* To be filled in with types
* @throws StationIsDeletedException
* if do not provides any types it is deleted
*/
public void getWeatherTypes(final WeatherStation station)
throws StationIsDeletedException {
station.setTypes(getWeatherTypes(station.getId(),
station.getProvider(), false));
}
public void resetStationDb() {
db.resetDb();
}
public void updateStations() {
List<WeatherStation> stations = wsklima
.getAllWeatherStationsFromTimeserie("2", false);
for (WeatherStation weatherStation : stations)
if (!db.isStationInDatabase(weatherStation.getId())) {
try {
db.add(weatherStation);
} catch (StationIsDeletedException e) {
}
}
}
private class Pair implements Comparable<Pair> {
private int Key;
private float Value;
public Pair() {
super();
}
public Pair(int key, float value) {
super();
Key = key;
Value = value;
}
@Override
public Pair clone() {
try {
return (Pair) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
public int compareTo(Pair another) {
// TODO Auto-generated method stub
return (int) (Value - another.Value);
}
@Override
public boolean equals(Object o) {
if (o.getClass().equals(this.getClass()))
return Value == ((Pair) o).Value;
else
return false;
}
public int getKey() {
return Key;
}
@SuppressWarnings("unused")
public float getValue() {
return Value;
}
@SuppressWarnings("unused")
public void setKey(int key) {
Key = key;
}
@SuppressWarnings("unused")
public void setValue(float value) {
Value = value;
}
}
}
|