package org.mtransit.android.task;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.mtransit.android.commons.ArrayUtils;
import org.mtransit.android.commons.LocationUtils;
import org.mtransit.android.commons.MTLog;
import org.mtransit.android.commons.RuntimeUtils;
import org.mtransit.android.data.AgencyProperties;
import org.mtransit.android.data.DataSourceProvider;
import org.mtransit.android.data.POIManager;
import android.content.Context;
public class NearbyPOIListLoader extends MTAsyncTaskLoaderV4<ArrayList<POIManager>> {
private static final String TAG = NearbyPOIListLoader.class.getSimpleName();
@Override
public String getLogTag() {
return TAG;
}
private ArrayList<POIManager> pois;
private String[] agenciesAuthority;
private double lat;
private double lng;
private double aroundDiff;
private int maxSize;
private float minCoverageInMeters;
private boolean hideDescentOnly;
private boolean avoidLoading;
public NearbyPOIListLoader(Context context, double lat, double lng, double aroundDiff, float minCoverageInMeters, int maxSize, boolean hideDescentOnly,
boolean avoidLoading, ArrayList<String> agenciesAuthority) {
this(context, lat, lng, aroundDiff, minCoverageInMeters, maxSize, hideDescentOnly, avoidLoading, agenciesAuthority == null ? null : agenciesAuthority
.toArray(new String[agenciesAuthority.size()]));
}
public NearbyPOIListLoader(Context context, double lat, double lng, double aroundDiff, float minCoverageInMeters, int maxSize, boolean hideDescentOnly,
boolean avoidLoading, String... agenciesAuthority) {
super(context);
this.agenciesAuthority = agenciesAuthority;
this.lat = lat;
this.lng = lng;
this.aroundDiff = aroundDiff;
this.minCoverageInMeters = minCoverageInMeters;
this.maxSize = maxSize;
this.hideDescentOnly = hideDescentOnly;
this.avoidLoading = avoidLoading;
}
@Override
public ArrayList<POIManager> loadInBackgroundMT() {
if (this.pois == null) {
this.pois = new ArrayList<POIManager>();
}
if (ArrayUtils.getSize(this.agenciesAuthority) == 0) {
return this.pois;
}
ThreadPoolExecutor executor = new ThreadPoolExecutor(RuntimeUtils.NUMBER_OF_CORES, RuntimeUtils.NUMBER_OF_CORES, 1, TimeUnit.SECONDS,
new LinkedBlockingDeque<Runnable>(this.agenciesAuthority.length));
ArrayList<Future<ArrayList<POIManager>>> taskList = new ArrayList<Future<ArrayList<POIManager>>>();
for (String agencyAuthority : this.agenciesAuthority) {
FindNearbyAgencyPOIsTask task = new FindNearbyAgencyPOIsTask(getContext(), agencyAuthority, this.lat, this.lng, this.aroundDiff,
this.hideDescentOnly, this.avoidLoading, this.minCoverageInMeters, this.maxSize);
taskList.add(executor.submit(task));
}
for (Future<ArrayList<POIManager>> future : taskList) {
try {
ArrayList<POIManager> agencyNearbyStops = future.get();
if (agencyNearbyStops != null) {
this.pois.addAll(agencyNearbyStops);
}
} catch (Exception e) {
MTLog.w(this, e, "Error while loading in background!");
}
}
executor.shutdown();
LocationUtils.removeTooMuchWhenNotInCoverage(this.pois, this.minCoverageInMeters, this.maxSize);
return this.pois;
}
public static void filterAgencies(Collection<AgencyProperties> agencies, double lat, double lng, LocationUtils.AroundDiff ad, Double optLastAroundDiff) {
if (agencies != null) {
LocationUtils.Area area = LocationUtils.getArea(lat, lng, ad.aroundDiff);
LocationUtils.Area optLastArea = optLastAroundDiff == null ? null : LocationUtils.getArea(lat, lng, optLastAroundDiff);
Iterator<AgencyProperties> it = agencies.iterator();
while (it.hasNext()) {
AgencyProperties agency = it.next();
if (!agency.isInArea(area)) {
it.remove();
} else if (optLastArea != null && agency.isEntirelyInside(optLastArea)) {
}
}
}
}
public static ArrayList<AgencyProperties> findTypeAgencies(Context context, int typeId, double lat, double lng, double aroundDiff, Double optLastAroundDiff) {
ArrayList<AgencyProperties> allTypeAgencies = DataSourceProvider.get(context).getTypeDataSources(context, typeId);
if (allTypeAgencies != null) {
LocationUtils.Area area = LocationUtils.getArea(lat, lng, aroundDiff);
LocationUtils.Area optLastArea = optLastAroundDiff == null ? null : LocationUtils.getArea(lat, lng, optLastAroundDiff);
Iterator<AgencyProperties> it = allTypeAgencies.iterator();
while (it.hasNext()) {
AgencyProperties agency = it.next();
if (!agency.isInArea(area)) {
it.remove();
} else if (optLastArea != null && agency.isEntirelyInside(optLastArea)) {
}
}
}
return allTypeAgencies;
}
public static ArrayList<String> findTypeAgenciesAuthority(Context context, int typeId, double lat, double lng, double aroundDiff, Double optLastAroundDiff) {
ArrayList<String> authorities = new ArrayList<String>();
ArrayList<AgencyProperties> agencies = findTypeAgencies(context, typeId, lat, lng, aroundDiff, optLastAroundDiff);
if (agencies != null) {
for (AgencyProperties agency : agencies) {
authorities.add(agency.getAuthority());
}
}
return authorities;
}
@Override
public void deliverResult(ArrayList<POIManager> data) {
this.pois = data;
if (isStarted()) {
super.deliverResult(data);
}
}
@Override
protected void onStartLoading() {
super.onStartLoading();
if (this.pois != null) {
deliverResult(this.pois);
}
if (this.pois == null) {
forceLoad();
}
}
@Override
protected void onStopLoading() {
super.onStopLoading();
cancelLoad();
}
@Override
public void onCanceled(ArrayList<POIManager> data) {
super.onCanceled(data);
}
@Override
protected void onReset() {
super.onReset();
onStopLoading();
}
}