Back to project page sthlmtraveling.
The source code is released under:
Apache License
If you think the Android project sthlmtraveling listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * Copyright (C) 2009-2014 Johan Nilsson <http://markupartist.com> *//from www . j av a2s. c o m * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.markupartist.sthlmtraveling.provider.planner; import android.content.Context; import android.graphics.Color; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; import com.markupartist.sthlmtraveling.R; import com.markupartist.sthlmtraveling.utils.DateTimeUtil; import com.markupartist.sthlmtraveling.utils.HttpHelper; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.net.HttpURLConnection; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import static com.markupartist.sthlmtraveling.provider.ApiConf.apiEndpoint2; /** * Journey planner for the sl.se API. */ public class Planner { private static final String TAG = "Planner"; private static Planner instance = null; /** * Constructs a new Planner */ private Planner() { } public static int plannerErrorCodeToStringRes(String errorCode) { // Make sure to have the common error codes as high as possible. if ("H9220".equals(errorCode)) { return R.string.planner_error_H9220; } else if ("H895".equals(errorCode)) { return R.string.planner_error_H895; } else if ("H9300".equals(errorCode)) { return R.string.planner_error_H9300; } else if ("H9360".equals(errorCode)) { return R.string.planner_error_H9360; } else if ("H9380".equals(errorCode)) { return R.string.planner_error_H9380; } else if ("H9320".equals(errorCode)) { return R.string.planner_error_H9320; } else if ("H9280".equals(errorCode)) { return R.string.planner_error_H9280; } else if ("H9260".equals(errorCode)) { return R.string.planner_error_H9260; } else if ("H9250".equals(errorCode)) { return R.string.planner_error_H9250; } else if ("H9240".equals(errorCode)) { return R.string.planner_error_H9240; } else if ("H9230".equals(errorCode)) { return R.string.planner_error_H9230; } else if ("H900".equals(errorCode)) { return R.string.planner_error_H900; } else if ("H892".equals(errorCode)) { return R.string.planner_error_H892; } else if ("H891".equals(errorCode)) { return R.string.planner_error_H891; } else if ("H890".equals(errorCode)) { return R.string.planner_error_H890; } else if ("H500".equals(errorCode)) { return R.string.planner_error_H500; } else if ("H455".equals(errorCode)) { return R.string.planner_error_H455; } else if ("H410".equals(errorCode)) { return R.string.planner_error_H410; } else if ("H390".equals(errorCode)) { return R.string.planner_error_H390; } return R.string.planner_error_unknown; } public Response findPreviousJourney(final Context context, JourneyQuery query) throws IOException, BadResponse { return doJourneyQuery(context, query, 2); } public Response findNextJourney(final Context context, JourneyQuery query) throws IOException, BadResponse { return doJourneyQuery(context, query, 1); } public Response findJourney(final Context context, JourneyQuery query) throws IOException, BadResponse { return doJourneyQuery(context, query, -1); } public Trip2 addIntermediateStops(final Context context, Trip2 trip, JourneyQuery query) throws IOException{ Uri u = Uri.parse(apiEndpoint2()); Uri.Builder b = u.buildUpon(); b.appendEncodedPath("journey/v1/intermediate/"); b.appendQueryParameter("ident", query.ident); b.appendQueryParameter("seqnr", query.seqnr); int references = 0; String reference = null; for (SubTrip st : trip.subTrips) { if ((!TextUtils.isEmpty(st.reference)) && st.intermediateStop.isEmpty()) { b.appendQueryParameter("reference", st.reference); references++; reference = st.reference; } } u = b.build(); if (references == 0) { return trip; } HttpHelper httpHelper = HttpHelper.getInstance(context); HttpURLConnection connection = httpHelper.getConnection(u.toString()); String rawContent; int statusCode = connection.getResponseCode(); switch (statusCode) { case 200: rawContent = httpHelper.getBody(connection); try { JSONObject baseResponse = new JSONObject(rawContent); if (baseResponse.has("stops")) { if (baseResponse.isNull("stops")) { Log.d(TAG, "stops was null, ignoring."); } else if (references == 1) { JSONArray intermediateStopsJson = baseResponse.getJSONArray("stops"); for (SubTrip st : trip.subTrips) { if (reference.equals(st.reference)) { for (int i = 0; i < intermediateStopsJson.length(); i++) { st.intermediateStop.add(IntermediateStop.fromJson( intermediateStopsJson.getJSONObject(i))); } } } } else { JSONObject intermediateStopsJson = baseResponse.getJSONObject("stops"); for (SubTrip st : trip.subTrips) { if (intermediateStopsJson.has(st.reference)) { JSONArray jsonArray = intermediateStopsJson.getJSONArray(st.reference); for (int i = 0; i < jsonArray.length(); i++) { st.intermediateStop.add(IntermediateStop.fromJson( jsonArray.getJSONObject(i))); } } } } } else { Log.w(TAG, "Invalid response when fetching intermediate stops."); } } catch (JSONException e) { Log.w(TAG, "Could not parse the reponse for intermediate stops."); } break; case 400: // Bad request rawContent = httpHelper.getErrorBody(connection); try { BadResponse br = BadResponse.fromJson(new JSONObject(rawContent)); Log.e(TAG, "Invalid response for intermediate stops: " + br.toString()); } catch (JSONException e) { Log.e(TAG, "Could not parse the reponse for intermediate stops."); } default: Log.e(TAG, "Status code not OK from intermediate stops API, was " + statusCode); } return trip; } public SubTrip addIntermediateStops(Context context, SubTrip subTrip, JourneyQuery query) throws IOException { Uri u = Uri.parse(apiEndpoint2()); Uri.Builder b = u.buildUpon(); b.appendEncodedPath("journey/v1/intermediate/"); b.appendQueryParameter("ident", query.ident); b.appendQueryParameter("seqnr", query.seqnr); b.appendQueryParameter("reference", subTrip.reference); u = b.build(); HttpHelper httpHelper = HttpHelper.getInstance(context); HttpURLConnection connection = httpHelper.getConnection(u.toString()); String rawContent; int statusCode = connection.getResponseCode(); switch (statusCode) { case 200: rawContent = httpHelper.getBody(connection); try { JSONObject baseResponse = new JSONObject(rawContent); if (baseResponse.has("stops")) { JSONArray intermediateStopJsonArray = baseResponse.getJSONArray("stops"); for (int i = 0; i < intermediateStopJsonArray.length(); i++) { subTrip.intermediateStop.add(IntermediateStop.fromJson( intermediateStopJsonArray.getJSONObject(i))); } } else { Log.w(TAG, "Invalid response when fetching intermediate stops."); } } catch (JSONException e) { Log.w(TAG, "Could not parse the reponse for intermediate stops."); } break; case 400: rawContent = httpHelper.getErrorBody(connection); try { BadResponse br = BadResponse.fromJson(new JSONObject(rawContent)); Log.e(TAG, "Invalid response for intermediate stops: " + br.toString()); } catch (JSONException e) { Log.e(TAG, "Could not parse the reponse for intermediate stops."); } default: Log.e(TAG, "Status code not OK from intermediate stops API, was " + statusCode); } return subTrip; } private Response doJourneyQuery(final Context context, JourneyQuery query, int scrollDirection) throws IOException, BadResponse { Uri u = Uri.parse(apiEndpoint2()); Uri.Builder b = u.buildUpon(); b.appendEncodedPath("v1/journey/"); if (scrollDirection > -1) { b.appendQueryParameter("dir", String.valueOf(scrollDirection)); b.appendQueryParameter("ident", query.ident); b.appendQueryParameter("seq", query.seqnr); } else { if (query.origin.hasLocation()) { b.appendQueryParameter("origin", query.origin.name); b.appendQueryParameter("origin_latitude", String.valueOf(query.origin.latitude / 1E6)); b.appendQueryParameter("origin_longitude", String.valueOf(query.origin.longitude / 1E6)); } else { b.appendQueryParameter("origin", String.valueOf(query.origin.getNameOrId())); } if (query.destination.hasLocation()) { b.appendQueryParameter("destination", query.destination.name); b.appendQueryParameter("destination_latitude", String.valueOf(query.destination.latitude / 1E6)); b.appendQueryParameter("destination_longitude", String.valueOf(query.destination.longitude / 1E6)); } else { b.appendQueryParameter("destination", String.valueOf(query.destination.getNameOrId())); } for (String transportMode : query.transportModes) { b.appendQueryParameter("transport", transportMode); } if (query.time != null) { b.appendQueryParameter("date", query.time.format("%d.%m.%Y")); b.appendQueryParameter("time", query.time.format("%H:%M")); } if (!query.isTimeDeparture) { b.appendQueryParameter("arrival", "1"); } if (query.hasVia()) { b.appendQueryParameter("via", query.via.name); } if (query.alternativeStops) { b.appendQueryParameter("alternative", "1"); } } // Include intermediate stops. //b.appendQueryParameter("intermediate_stops", "1"); u = b.build(); HttpHelper httpHelper = HttpHelper.getInstance(context); HttpURLConnection connection = httpHelper.getConnection(u.toString()); Response r = null; String rawContent; int statusCode = connection.getResponseCode(); switch (statusCode) { case 200: rawContent = httpHelper.getBody(connection); try { JSONObject baseResponse = new JSONObject(rawContent); if (baseResponse.has("journey")) { r = Response.fromJson(baseResponse.getJSONObject("journey")); } else { Log.w(TAG, "Invalid response"); } } catch (JSONException e) { Log.d(TAG, "Could not parse the reponse..."); throw new IOException("Could not parse the response."); } break; case 400: rawContent = httpHelper.getErrorBody(connection); BadResponse br; try { br = BadResponse.fromJson(new JSONObject(rawContent)); } catch (JSONException e) { Log.d(TAG, "Could not parse the reponse..."); throw new IOException("Could not parse the response."); } throw br; default: Log.d(TAG, "Status code not OK from API, was " + statusCode); throw new IOException("A remote server error occurred when getting deviations."); } return r; } /** * Get an instance of Planner. * @return a Planner */ public static Planner getInstance() { if (instance == null) instance = new Planner(); return instance; } public static class BadResponse extends Exception { public String errorCode; public String description; public static BadResponse fromJson(JSONObject json) throws JSONException { BadResponse br = new BadResponse(); if (json.has("code")) { br.errorCode = json.getString("code"); } else { br.errorCode = "-1"; } if (json.has("description")) { br.description = json.getString("description"); } else { br.description = "Unknown error"; } return br; } @Override public String toString() { return "BadResponse [description=" + description + ", errorCode=" + errorCode + "]"; } } public static class Response implements Parcelable { // TODO: Parse out the ident. public String ident; public String seqnr; public int numberOfTrips; public ArrayList<Trip2> trips = new ArrayList<Trip2>(); private String tariffZones; public Response() { } public Response(Parcel parcel) { ident = parcel.readString(); seqnr = parcel.readString(); trips = new ArrayList<Trip2>(); seqnr = parcel.readString(); parcel.readTypedList(trips, Trip2.CREATOR); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(ident); dest.writeString(seqnr); dest.writeTypedList(trips); dest.writeString(tariffZones); } public boolean canBuySmsTicket() { tariffZones = null; for (Trip2 trip : trips) { if (!trip.canBuySmsTicket()) { return false; } if (tariffZones != null && !tariffZones.equals(trip.tariffZones)) { tariffZones = null; return false; } tariffZones = trip.tariffZones; } return true; } public String getTariffZones() { if (tariffZones == null) { for (Trip2 trip : trips) { if (tariffZones != null && !tariffZones.equals(trip.tariffZones)) { tariffZones = null; return null; } tariffZones = trip.tariffZones; } } return tariffZones; } @Override public String toString() { return "Response{" + "ident='" + ident + '\'' + ", seqnr='" + seqnr + '\'' + ", numberOfTrips=" + numberOfTrips + ", trips=" + trips + '}'; } public static Response fromJson(JSONObject json) throws JSONException { Response r = new Response(); if (json.has("ident")) { r.ident = json.getString("ident"); } if (json.has("seqnr")) { r.seqnr = json.getString("seqnr"); } JSONArray jsonTrips = json.getJSONArray("trips"); for (int i = 0; i < jsonTrips.length(); i++) { try { r.trips.add(Trip2.fromJson(jsonTrips.getJSONObject(i))); } catch (JSONException e) { e.printStackTrace(); Log.d(TAG, "Failed to parse trip: " + e.getMessage()); } } return r; } public static final Creator<Response> CREATOR = new Creator<Response>() { public Response createFromParcel(Parcel parcel) { return new Response(parcel); } public Response[] newArray(int size) { return new Response[size]; } }; } public static class Trip2 implements Parcelable { public Location origin; public Location destination; public String departureDate; // TODO: Combine date and time public String departureTime; public String arrivalDate; // TODO: Combine date and time public String arrivalTime; public int changes; public String duration; public String tariffZones; public String tariffRemark; public String co2; public boolean mt6MessageExist; public boolean rtuMessageExist; public boolean remarksMessageExist; public ArrayList<SubTrip> subTrips = new ArrayList<SubTrip>(); public Trip2() { } public Trip2(Parcel parcel) { origin = parcel.readParcelable(Location.class.getClassLoader()); destination = parcel.readParcelable(Location.class.getClassLoader()); departureDate = parcel.readString(); departureTime = parcel.readString(); arrivalDate = parcel.readString(); arrivalTime = parcel.readString(); changes = parcel.readInt(); duration = parcel.readString(); tariffZones = parcel.readString(); tariffRemark = parcel.readString(); co2 = parcel.readString(); mt6MessageExist = (parcel.readInt() == 1) ? true : false; rtuMessageExist = (parcel.readInt() == 1) ? true : false; remarksMessageExist = (parcel.readInt() == 1) ? true : false; subTrips = new ArrayList<SubTrip>(); parcel.readTypedList(subTrips, SubTrip.CREATOR); } /** * @return returns true if this trip can be purchased with SMS. */ public boolean canBuySmsTicket() { // TODO: Add support for checking tariff messages return tariffZones.equals("A") || tariffZones.equals("B") || tariffZones.equals("C") || tariffZones.equals("AB") || tariffZones.equals("BC") || tariffZones.equals("ABC"); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(origin, 0); dest.writeParcelable(destination, 0); dest.writeString(departureDate); dest.writeString(departureTime); dest.writeString(arrivalDate); dest.writeString(arrivalTime); dest.writeInt(changes); dest.writeString(duration); dest.writeString(tariffZones); dest.writeString(tariffRemark); dest.writeString(co2); dest.writeInt((mt6MessageExist == true) ? 1 : 0); dest.writeInt((rtuMessageExist == true) ? 1 : 0); dest.writeInt((remarksMessageExist == true) ? 1 : 0); dest.writeTypedList(subTrips); } public static Trip2 fromJson(JSONObject json) throws JSONException { //parseLocation(json.getJSONObject("origin")); Trip2 trip = new Trip2(); trip.departureDate = json.getString("departure_date"); JSONArray jsonSubTrips = json.getJSONArray("sub_trips"); for (int i = 0; i < jsonSubTrips.length(); i++) { try { trip.subTrips.add(SubTrip.fromJson(jsonSubTrips.getJSONObject(i))); } catch (JSONException e) { e.printStackTrace(); Log.d(TAG, "Failed to parse sub trip: " + e.getMessage()); } } trip.arrivalDate = json.getString("arrival_date"); trip.arrivalTime = json.getString("arrival_time"); trip.changes = json.getInt("changes"); trip.co2 = json.getString("co2"); trip.departureDate = json.getString("departure_date"); trip.departureTime = json.getString("departure_time"); trip.destination = Location.fromJson(json.getJSONObject("destination")); trip.duration = json.getString("duration"); trip.mt6MessageExist = json.getBoolean("mt6_messages_exist"); trip.origin = Location.fromJson(json.getJSONObject("origin")); if (json.has("tariff_zones")) { trip.tariffZones = json.getString("tariff_zones"); trip.tariffZones = trip.tariffZones.trim(); } if (json.has("tariff_remark")) { trip.tariffRemark = json.getString("tariff_remark"); } trip.remarksMessageExist = json.getBoolean("remark_messages_exist"); trip.rtuMessageExist = json.getBoolean("rtu_messages_exist"); return trip; } @Override public String toString() { return "Trip{" + "origin=" + origin + ", destination=" + destination + ", departureDate='" + departureDate + '\'' + ", departureTime='" + departureTime + '\'' + ", arrivalDate='" + arrivalDate + '\'' + ", arrivalTime='" + arrivalTime + '\'' + ", changes=" + changes + ", duration='" + duration + '\'' + ", tariffZones='" + tariffZones + '\'' + ", tariffRemark='" + tariffRemark + '\'' + ", co2='" + co2 + '\'' + ", mt6MessageExist=" + mt6MessageExist + ", rtuMessageExist=" + rtuMessageExist + ", remarksMessageExist=" + remarksMessageExist + ", subTrips=" + subTrips + '}'; } public String toText() { String durationInMinutes = duration; try { DateFormat df = new SimpleDateFormat("H:mm"); Date tripDate = df.parse(duration); if (tripDate.getHours() == 0) { int start = duration.indexOf(":") + 1; if (duration.substring(start).startsWith("0")) { start++; } durationInMinutes = duration.substring(start) + " min"; } } catch (ParseException e) { Log.e(TAG, "Error parsing duration, " + e.getMessage()); } /*int end = departureDate.lastIndexOf("."); String departureDateString = departureDate.substring(0, end).replace(".", "/");*/ return String.format("%s %s (%s)", departureTime, arrivalTime, durationInMinutes); } public static final Creator<Trip2> CREATOR = new Creator<Trip2>() { public Trip2 createFromParcel(Parcel parcel) { return new Trip2(parcel); } public Trip2[] newArray(int size) { return new Trip2[size]; } }; public String getDurationText() { String durationInMinutes = duration; try { DateFormat df = new SimpleDateFormat("H:mm"); Date tripDate = df.parse(duration); if (tripDate.getHours() == 0) { int start = duration.indexOf(":") + 1; if (duration.substring(start).startsWith("0")) { start++; } durationInMinutes = duration.substring(start) + " min"; } } catch (ParseException e) { Log.e(TAG, "Error parsing duration, " + e.getMessage()); } return durationInMinutes; } } /** * Representation of a intermediate stop. */ public static class IntermediateStop implements Parcelable { public String arrivalDate; public String arrivalTime; public Location location; public IntermediateStop(Parcel parcel) { arrivalDate = parcel.readString(); arrivalTime = parcel.readString(); location = parcel.readParcelable(Location.class.getClassLoader()); } public IntermediateStop() { } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(arrivalDate); dest.writeString(arrivalTime); dest.writeParcelable(location, 0); } public static IntermediateStop fromJson(JSONObject json) throws JSONException { IntermediateStop is = new IntermediateStop(); is.arrivalDate = json.getString("arrival_date"); is.arrivalTime = json.getString("arrival_time"); is.location = Location.fromJson(json.getJSONObject("location")); return is; } @Override public String toString() { return "IntermediateStop [arrivalDate=" + arrivalDate + ", arrivalTime=" + arrivalTime + ", location=" + location + "]"; } public static final Creator<IntermediateStop> CREATOR = new Creator<IntermediateStop>() { public IntermediateStop createFromParcel(Parcel parcel) { return new IntermediateStop(parcel); } public IntermediateStop[] newArray(int size) { return new IntermediateStop[size]; } }; } public static class SubTrip implements Parcelable { public Location origin; public Location destination; public String departureDate; // TODO: Combine date and time public String departureTime; public String arrivalDate; // TODO: Combine date and time public String arrivalTime; public TransportType transport; public ArrayList<String> remarks = new ArrayList<String>(); public ArrayList<String> rtuMessages = new ArrayList<String>(); public ArrayList<String> mt6Messages = new ArrayList<String>(); public String reference; public ArrayList<IntermediateStop> intermediateStop = new ArrayList<IntermediateStop>(); private Date departureDateTime; private Date arrivalDateTime; public SubTrip() { } public SubTrip(Parcel parcel) { origin = parcel.readParcelable(Location.class.getClassLoader()); destination = parcel.readParcelable(Location.class.getClassLoader()); departureDate = parcel.readString(); departureTime = parcel.readString(); arrivalDate = parcel.readString(); arrivalTime = parcel.readString(); transport = parcel.readParcelable(TransportType.class.getClassLoader()); remarks = new ArrayList<String>(); parcel.readStringList(remarks); rtuMessages = new ArrayList<String>(); parcel.readStringList(rtuMessages); mt6Messages = new ArrayList<String>(); parcel.readStringList(mt6Messages); reference = parcel.readString(); intermediateStop = new ArrayList<IntermediateStop>(); parcel.readList(intermediateStop, Location.class.getClassLoader()); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(origin, 0); dest.writeParcelable(destination, 0); dest.writeString(departureDate); dest.writeString(departureTime); dest.writeString(arrivalDate); dest.writeString(arrivalTime); dest.writeParcelable(transport, 0); dest.writeStringList(remarks); dest.writeStringList(rtuMessages); dest.writeStringList(mt6Messages); dest.writeString(reference); dest.writeList(intermediateStop); } public static SubTrip fromJson(JSONObject json) throws JSONException { SubTrip st = new SubTrip(); st.origin = Location.fromJson(json.getJSONObject("origin")); st.destination = Location.fromJson(json.getJSONObject("destination")); st.departureDate = json.getString("departure_date"); st.departureTime = json.getString("departure_time"); st.arrivalDate = json.getString("arrival_date"); st.arrivalTime = json.getString("arrival_time"); st.transport = TransportType.fromJson(json.getJSONObject("transport")); if (json.has("remark_messages")) { fromJsonArray(json.getJSONArray("remark_messages"), st.remarks); } if (json.has("rtu_messages")) { fromJsonArray(json.getJSONArray("rtu_messages"), st.rtuMessages); } if (json.has("mt6_messages")) { fromJsonArray(json.getJSONArray("mt6_messages"), st.mt6Messages); } if (!json.isNull("reference")) { st.reference = json.getString("reference"); } if (json.has("intermediate_stops") && !json.isNull("intermediate_stops")) { JSONArray intermediateStopJsonArray = json.getJSONArray("intermediate_stops"); for (int i = 0; i < intermediateStopJsonArray.length(); i++) { st.intermediateStop.add(IntermediateStop.fromJson( intermediateStopJsonArray.getJSONObject(i))); } } return st; } private static void fromJsonArray(JSONArray jsonArray, ArrayList<String> list) throws JSONException { for (int i = 0; i < jsonArray.length(); i++) { list.add(jsonArray.getString(i)); } } public long getDurationMillis() { return getArrival().getTime() - getDeparture().getTime(); } public Date getDeparture() { if (departureDateTime == null) { departureDateTime = DateTimeUtil.fromSlDateTime(departureDate, departureTime); } return departureDateTime; } public Date getArrival() { if (arrivalDateTime == null) { arrivalDateTime = DateTimeUtil.fromSlDateTime(arrivalDate, arrivalTime); } return arrivalDateTime; } @Override public String toString() { return "SubTrip [arrivalDate=" + arrivalDate + ", arrivalTime=" + arrivalTime + ", departureDate=" + departureDate + ", departureTime=" + departureTime + ", destination=" + destination + ", intermediateStop=" + intermediateStop + ", mt6Messages=" + mt6Messages + ", origin=" + origin + ", reference=" + reference + ", remarks=" + remarks + ", rtuMessages=" + rtuMessages + ", transport=" + transport + "]"; } public static final Creator<SubTrip> CREATOR = new Creator<SubTrip>() { public SubTrip createFromParcel(Parcel parcel) { return new SubTrip(parcel); } public SubTrip[] newArray(int size) { return new SubTrip[size]; } }; } public static class Location implements Parcelable { public static String TYPE_MY_LOCATION = "MY_LOCATION"; public int id = 0; public String name; public int latitude; public int longitude; public Location() {} public Location(Location location) { id = location.id; name = location.name; latitude = location.latitude; longitude = location.longitude; } public Location(Parcel parcel) { id = parcel.readInt(); name = parcel.readString(); latitude = parcel.readInt(); longitude = parcel.readInt(); } public boolean isMyLocation() { return TYPE_MY_LOCATION.equals(name); } public boolean hasLocation() { return latitude != 0 && longitude != 0; } public String getNameOrId() { if (hasLocation() || id == 0) { return name; } return String.valueOf(id); } public static Location fromJson(JSONObject json) throws JSONException { Location l = new Location(); if (json.has("id")) { l.id = json.getInt("id"); } l.name = json.getString("name"); l.longitude = (int) (json.getDouble("longitude") * 1E6); l.latitude = (int) (json.getDouble("latitude") * 1E6); return l; } @Override public String toString() { return "Location{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", latitude=" + latitude + ", longitude=" + longitude + '}'; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(id); dest.writeString(name); dest.writeInt(latitude); dest.writeInt(longitude); } public static final Creator<Location> CREATOR = new Creator<Location>() { public Location createFromParcel(Parcel parcel) { return new Location(parcel); } public Location[] newArray(int size) { return new Location[size]; } }; public boolean hasName() { return !TextUtils.isEmpty(name); } /** * Get a clean representation of the stop name. * * @return The name */ public CharSequence getCleanName() { if (TextUtils.isEmpty(name)) { return ""; } return name.replaceAll("\\(.*\\)", ""); } } public static class TransportType implements Parcelable { public String type = ""; public String name = ""; public String towards = ""; public TransportType() { } public TransportType(Parcel parcel) { type = parcel.readString(); name = parcel.readString(); towards = parcel.readString(); } @Override public int describeContents() { // TODO Auto-generated method stub return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(type); dest.writeString(name); dest.writeString(towards); } public static TransportType fromJson(JSONObject json) throws JSONException { TransportType t = new TransportType(); if (json.has("name")) { t.name = json.getString("name"); } if (json.has("towards")) { t.towards = json.getString("towards"); } t.type = json.getString("type"); return t; } public int getImageResource() { if ("BUS".equals(type)) { if (name.contains("bl")) { return R.drawable.transport_bus_blue; } return R.drawable.transport_bus_red; } else if ("MET".equals(type)) { if (name.contains("grn")) { return R.drawable.transport_metro_green; } else if (name.contains("rd")) { return R.drawable.transport_metro_red; } else if (name.contains("bl")) { return R.drawable.transport_metro_blue; } } else if ("NAR".equals(type)) { return R.drawable.transport_nar; } else if ("Walk".equals(type)) { return R.drawable.transport_walk; } else if ("TRN".equals(type)) { return R.drawable.transport_train; } else if ("TRM".equals(type)) { return R.drawable.transport_tram_car; } else if ("SHP".equals(type)) { return R.drawable.transport_boat; } else if ("FLY".equals(type)) { return R.drawable.transport_fly; } else if ("AEX".equals(type)) { return R.drawable.transport_aex; } Log.d(TAG, "Unknown transport type " + type); return R.drawable.transport_unkown; } public int getColor(final Context context) { if ("BUS".equals(type)) { if (name.contains("bl")) { return context.getResources().getColor(R.color.bus_blue); } return context.getResources().getColor(R.color.metro_red); } else if ("MET".equals(type)) { if (name.contains("grn")) { return context.getResources().getColor(R.color.metro_green); } else if (name.contains("rd")) { return context.getResources().getColor(R.color.metro_red); } else if (name.contains("bl")) { return context.getResources().getColor(R.color.metro_blue); } } else if ("NAR".equals(type)) { return Color.WHITE; } else if ("Walk".equals(type)) { return Color.BLACK; } else if ("TRN".equals(type)) { return context.getResources().getColor(R.color.train); } else if ("TRM".equals(type)) { return context.getResources().getColor(R.color.train); } else if ("SHP".equals(type)) { return 0xff09693E; } else if ("FLY".equals(type)) { return Color.DKGRAY; } else if ("AEX".equals(type)) { return Color.YELLOW; } Log.d(TAG, "Unknown transport type " + type); return Color.DKGRAY; } @Override public String toString() { return "Transport{" + "type='" + type + '\'' + ", name='" + name + '\'' + ", towards='" + towards + '\'' + '}'; } public static final Creator<TransportType> CREATOR = new Creator<TransportType>() { public TransportType createFromParcel(Parcel parcel) { return new TransportType(parcel); } public TransportType[] newArray(int size) { return new TransportType[size]; } }; } }