Skip to content
Browse files

resolving merge conflicts

  • Loading branch information...
2 parents 19ef646 + 3b40a82 commit fb3b551e3560a7244fa7e29d54cfd3afdae9edc5 Colleen Ross committed May 25, 2012
View
19 src/we/should/CustomDialog.java
@@ -27,16 +27,16 @@ protected void onCreate(Bundle savedInstanceState) {
TextView tvDistance = (TextView) findViewById(R.id.tvPopupDis);
TextView tvAddr = (TextView) findViewById(R.id.tvPopUpAddr);
Button moreInfo = (Button) findViewById(R.id.btnMoreInfo);
- tvName.setText("Name: " + item.getName());
- tvDistance.setText("Distance: " + distance);
+ tvName.setText(item.getName());
+ tvDistance.setText(distance + " miles away");
String addr = item.get(Field.ADDRESS);
- tvAddr.setText("Address: " + addr);
+ tvAddr.setText(addr);
moreInfo.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
-// Intent intent = new Intent(getApplicationContext(), ViewScreen.class);
-// intent.putExtra(WeShouldActivity.CATEGORY, item.getCategory().getName());
-// intent.putExtra(WeShouldActivity.INDEX, position);
-// startActivity(intent, ActivityKey.VIEW_ITEM.ordinal());
+ Intent intent = new Intent(CustomDialog.this.getContext(), ViewScreen.class);
+ intent.putExtra(WeShouldActivity.CATEGORY, item.getCategory().getName());
+ intent.putExtra(WeShouldActivity.INDEX, item.getId());
+ CustomDialog.this.startActivity(intent);
}
});
@@ -46,6 +46,11 @@ public void onClick(View v) {
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
+ private void startActivity(Intent i){
+ this.dismiss();
+ getContext().startActivity(i);
+
+ }
}
View
205 src/we/should/WeShouldActivity.java
@@ -1,5 +1,5 @@
package we.should;
-
+import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -8,6 +8,7 @@
import we.should.communication.GetReferralsService;
import we.should.communication.RestoreService;
+
import we.should.database.WSdb;
import we.should.list.Category;
import we.should.list.Field;
@@ -17,19 +18,22 @@
import we.should.list.Referrals;
import we.should.list.Tag;
import we.should.search.CustomPinPoint;
+import android.app.AlertDialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
+
+import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
-import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
@@ -53,7 +57,7 @@
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
-import com.google.android.maps.Projection;
+import com.google.android.maps.OverlayItem;
public class WeShouldActivity extends MapActivity implements LocationListener {
@@ -69,7 +73,6 @@
private final Category RESTAURANTS = new GenericCategory(Category.Special.Restaurants.toString(), Field.getDefaultFields(), this);
private final Category MOVIES = new Movies(this);
-
private final Category REFERRALS = new Referrals(this);
@@ -90,6 +93,9 @@
/** A map that maps the name of each tag to its values. **/
private Map<String, Tag> mTags;
+ /** A global reference to the selected Item **/
+ private Item mItem;
+
/** A mapping from id's to categories, used for submenu creation. **/
private Map<Integer, Category> mMenuIDs;
private MapView map;
@@ -99,12 +105,11 @@
private MyLocationOverlay myLocationOverlay;
private List<Overlay> overlayList;
private ImageButton zoomButton;
- private Projection projection;
protected WSdb db;
protected String DBFILE;
-
- /** An enum describing how we want to group our tabs. **/
+
+ /** An enum describing how we want to group our tabs. **/
private static enum SortType {
Category, Tag;
}
@@ -119,24 +124,23 @@ public void onCreate(Bundle savedInstanceState) {
map = (MapView) findViewById(R.id.mapview);
controller = map.getController();
overlayList = map.getOverlays();
- projection = map.getProjection();
-
this.mTabHost = (TabHost) findViewById(android.R.id.tabhost);
this.zoomButton = (ImageButton) findViewById(R.id.my_location_button);
mSortType = SortType.Category;
updateTabs();
this.mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
public void onTabChanged(String tabId) {
- updatePins(tabId.trim());
+ updateView(tabId.trim());
+
}
});
this.zoomButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
GeoPoint loc = getDeviceLocation();
if(loc != null) {
- zoomLocation(getDeviceLocation());
+ zoomLocation(loc);
}
}
});
@@ -152,45 +156,56 @@ public void onClick(View arg0) {
map.postInvalidate();
}
- protected void updatePins(String name) {
- //clear the pin everytime we load a new tab.
- for(CustomPinPoint pin : lstPinPoints) {
- overlayList.remove(pin);
- }
+ protected void updateView(String name) {
List<Item> items = null;
+
//TODO: Lawrence String color = null; get color of category or tag
+ String color = null;
+
switch (mSortType) {
case Category:
items = mCategories.get(name).getItems();
+ color = mCategories.get(name).getColor();
break;
case Tag:
items = new ArrayList<Item>(Item.getItemsOfTag(mTags.get(name), this));
+ color = mTags.get(name).getColor();
break;
}
+ mAdapter = new ItemAdapter(WeShouldActivity.this, items);
+ mAdapter.notifyDataSetChanged();
+ updatePins(color, items);
+
+
+ }
+ private void updatePins(String color, List<Item> items){
+ //clear the pin everytime we load a new tab.
+ for(CustomPinPoint pin : lstPinPoints) {
+ overlayList.remove(pin);
+ }
+ if(color == null || items == null) {
+ throw new RuntimeException("fail to get item from category or tags");
+ }
+
for (Item item : items) {
Set<Address> addrs = item.getAddresses();
for(Address addr : addrs) {
- try {
+ if(addr.hasLatitude() && addr.hasLongitude()) {
int locX = (int) (addr.getLatitude() * 1E6);
int locY = (int) (addr.getLongitude() * 1E6);
GeoPoint placeLocation = new GeoPoint(locX, locY);
- CustomPinPoint custom = new CustomPinPoint(WeShouldActivity.this, item, placeLocation, this.projection, Color.BLUE);
-
- lstPinPoints.add(custom);
- overlayList.add(custom);
- } catch (IllegalStateException ex) {
- Log.v("UPDATEMAPVIEW", item.getName() + "'s address doesn't have lat or lng value");
- }
-
+ addPin(placeLocation, color, item, false);
+ }
}
}
- }
-
+
+ }
/**
* Updates the tabs depending on what we want to sort by.
*/
private void updateTabs() {
+ String tabId = mTabHost.getCurrentTabTag();
switch (mSortType) {
case Category:
updateTabsCategory();
@@ -199,7 +214,7 @@ private void updateTabs() {
updateTabsTag();
break;
}
- updatePins(mTabHost.getCurrentTabTag().trim());
+ mTabHost.setCurrentTabByTag(tabId);
}
/**
@@ -254,7 +269,6 @@ private void updateTabsTag() {
@Override
protected void onPause() {
- //TODO: Lawrence remember to stop all asynTask before exit!!!!
super.onPause();
myLocationOverlay.disableMyLocation();
lm.removeUpdates(this);
@@ -265,14 +279,14 @@ protected void onResume() {
super.onResume();
myLocationOverlay.enableMyLocation();
lm.requestLocationUpdates(towers, 500, 1, this);
+ updateView(mTabHost.getCurrentTabTag());
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
-
// Set up the toggle item
MenuItem toggle = menu.findItem(R.id.toggle);
switch (mSortType) {
@@ -354,23 +368,36 @@ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuIn
@Override
public boolean onContextItemSelected(MenuItem menuItem) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuItem.getMenuInfo();
- Item item = mAdapter.getItem(info.position);
+ mItem = mAdapter.getItem(info.position);
switch(menuItem.getItemId()) {
case R.id.view:
Intent intent = new Intent(getApplicationContext(), ViewScreen.class);
- intent.putExtra(CATEGORY, item.getCategory().getName());
- intent.putExtra(INDEX, item.getId());
+ intent.putExtra(CATEGORY, mItem.getCategory().getName());
+ intent.putExtra(INDEX, mItem.getId());
startActivityForResult(intent, ActivityKey.VIEW_ITEM.ordinal());
break;
case R.id.edit:
intent = new Intent(getApplicationContext(), EditScreen.class);
- intent.putExtra(CATEGORY, item.getCategory().getName());
- intent.putExtra(INDEX, item.getId());
+ intent.putExtra(CATEGORY, mItem.getCategory().getName());
+ intent.putExtra(INDEX, mItem.getId());
startActivityForResult(intent, ActivityKey.EDIT_ITEM.ordinal());
break;
case R.id.delete:
- mAdapter.remove(item);
- item.delete();
+ new AlertDialog.Builder(this)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setTitle(R.string.delete_item)
+ .setMessage(R.string.delete_item_confirm)
+ .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
+
+ public void onClick(DialogInterface dialog, int which) {
+ mAdapter.remove(mItem);
+ mItem.delete();
+ updateTabs();
+ }
+
+ })
+ .setNegativeButton(R.string.no, null)
+ .show();
break;
default:
return super.onContextItemSelected(menuItem);
@@ -387,8 +414,9 @@ public void onLocationChanged(Location location) {
//we do nothing when user change the location of the map
}
- //We will handle this later.
- public void onProviderDisabled(String provider) {
+ //Do nothing when the provider of the location listener(GPS or internet)
+ //disable or enable or statuschanged.
+ public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
@@ -424,27 +452,60 @@ public View createTabContent(String tag) {
// click to view item & current location in map
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,
- View view, int position, long id) {
-
+ View view, int position, long id) {
Item item = itemsList.get(position);
- Set<Address> addrs = item.getAddresses();
-
+ Set<Address> addrs = item.getAddresses();
for(Address addr : addrs) {
if(addr.hasLatitude() && addr.hasLongitude()) {
int locX = (int) (addr.getLatitude() * 1E6);
int locY = (int) (addr.getLongitude() * 1E6);
GeoPoint placeLocation = new GeoPoint(locX, locY);
GeoPoint myLoc = getDeviceLocation();
-
+ //Loop through the pins, remove the normal pin and add yellow pin.
+ //and replace any yellow pin back to normal pin.
if(myLoc == null) {
zoomLocation(placeLocation);
} else {
zoomToTwoPoint(placeLocation, myLoc);
- }
+ }
+ updateYellowPin(placeLocation);
break;
}
}
}
+
+ //updating the yellowPin when item is click.
+ private void updateYellowPin(GeoPoint placeLocation) {
+ CustomPinPoint replaceToColorPin = null;
+ CustomPinPoint replaceToYellowPin = null;
+ for(CustomPinPoint customPin : lstPinPoints) {
+ if(customPin.contains(placeLocation)) {
+ replaceToYellowPin = customPin;
+ }
+ if(customPin.isSelected()) {
+ replaceToColorPin = customPin;
+ }
+ if(replaceToColorPin != null && replaceToYellowPin != null) {
+ break;
+ }
+ }
+
+ if(replaceToColorPin != null) {
+ overlayList.remove(replaceToColorPin);
+ lstPinPoints.remove(replaceToColorPin);
+ addPin(replaceToColorPin.getPoint(),
+ replaceToColorPin.getColor(),
+ replaceToColorPin.getItem(), false);
+ }
+
+ if(replaceToYellowPin != null) {
+ overlayList.remove(replaceToYellowPin);
+ lstPinPoints.remove(replaceToYellowPin);
+ addPin(replaceToYellowPin.getPoint(),
+ replaceToYellowPin.getColor(),
+ replaceToYellowPin.getItem(), true);
+ }
+ }
});
return lv;
}
@@ -500,10 +561,29 @@ public void onItemClick(AdapterView<?> parent,
return lv;
}
+ }
+
+ private void addPin(GeoPoint point, String color, Item item, boolean isSelected) {
+ if(point == null || color == null || item == null) {
+ throw new IllegalArgumentException("input to addPin is null");
+ }
+
+ double distance = distanceBetween(getDeviceLocation(), point);
+ Drawable drawable;
+ if(isSelected) {
+ drawable = getDrawable("yellow");
+ } else {
+ drawable = getDrawable(color);
+ }
+ CustomPinPoint custom = new CustomPinPoint(drawable, this, item, distance, isSelected, color);
+ OverlayItem overlay = new OverlayItem(point, item.getName(), item.getName());
+ custom.addOverlay(overlay);
+ lstPinPoints.add(custom);
+ overlayList.add(custom);
}
- /*
+ /**
* @return the location of the device
*/
private GeoPoint getDeviceLocation() {
@@ -522,20 +602,49 @@ private GeoPoint getDeviceLocation() {
}
}
+ /**
+ * @param zoom to a point that capture the two points.
+ */
private void zoomToTwoPoint(GeoPoint point, GeoPoint point2) {
int maxX = Math.max(point.getLatitudeE6(), point2.getLatitudeE6());
int minX = Math.min(point.getLatitudeE6(), point2.getLatitudeE6());
int maxY = Math.max(point.getLongitudeE6(), point2.getLongitudeE6());
int minY = Math.min(point.getLongitudeE6(), point2.getLongitudeE6());
controller.zoomToSpan(maxX - minX, maxY - minY);
- controller.animateTo(new GeoPoint((minX + maxX) / 2, (minY + maxY) / 2));
+ controller.animateTo(new GeoPoint((minX + maxX) / 2, (minY + maxY) / 2));
}
- /*
+
+ /**
* if location is valid, make a pint and zoom user to that location.
* if the location isn't valid, it display error message with toast.
*/
private void zoomLocation(GeoPoint location) {
controller.animateTo(location);
controller.setZoom(17);
}
+
+ public static double DISTANCETOMILES = 0.000621371192;
+ private double distanceBetween(GeoPoint p1, GeoPoint p2) {
+ if(p1 == null || p2 == null) {
+ throw new IllegalArgumentException("GeoPoint are null");
+ }
+ Location loc1 = new Location("");
+ Location loc2 = new Location("");
+ loc1.setLatitude(p1.getLatitudeE6() / 1E6);
+ loc1.setLongitude(p1.getLongitudeE6() / 1E6);
+ loc2.setLatitude(p2.getLatitudeE6() / 1E6);
+ loc2.setLongitude(p2.getLongitudeE6() / 1E6);
+ DecimalFormat twoDForm = new DecimalFormat("#.##");
+ return Double.valueOf(twoDForm.format(loc1.distanceTo(loc2) * DISTANCETOMILES));
+ }
+
+
+ private Drawable getDrawable(String color) {
+ if(color.equals("yellow")) {//TODO: suppose to be hex , just for the special case of highlighting.
+ return getResources().getDrawable(R.drawable.yellow);
+ }
+ return getResources().getDrawable(R.drawable.red);
+ }
+
+
}
View
1 src/we/should/list/Category.java
@@ -55,6 +55,7 @@ protected Category(String name, Context ctx){
this.id = 0;
items = new LinkedList<Item>();
}
+
protected Category(String name, List<Field> fields, Context ctx){
this(name, ctx);
if (fields == null) this.fields = Field.getDefaultFields();
View
64 src/we/should/list/Field.java
@@ -1,27 +1,42 @@
package we.should.list;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
/**
*
* @author Davis Shepherd
* This is a helper class that is used to inform the UI how to render different fields
* in each item/category. It contains simply a name and a field type.
*
*/
-public class Field {
+public class Field implements Comparable{
+
+ public static final Field NAME = new Field("name", FieldType.TextField, 0);
+ public static final Field WEBSITE = new Field("website", FieldType.TextField, 1);
+ public static final Field PHONENUMBER = new Field("phone number", FieldType.PhoneNumber, 2);
+ public static final Field ADDRESS = new Field("address", FieldType.MultilineTextField, 3);
+ public static final Field RATING = new Field("rating", FieldType.Rating, 4);
+ public static final Field COMMENT = new Field("comment", FieldType.MultilineTextField, 5);
+ public static final Field TAGS = new Field("tags", FieldType.MultilineTextField, 6);
+
+ private static Map<String, Field> fieldMap;
+ static {
+ Map<String, Field> map = new HashMap<String, Field>();
+ List<Field> fields = getAllFields();
+ for(Field f : fields){
+ map.put(f.name, f);
+ }
+ fieldMap = Collections.unmodifiableMap(map);
+ }
+ private static final int DEFAULT_ORDER = -1;
- public static final Field NAME = new Field("name", FieldType.TextField);
- public static final Field WEBSITE = new Field("website", FieldType.TextField);
- public static final Field PHONENUMBER = new Field("phone number", FieldType.PhoneNumber);
- public static final Field ADDRESS = new Field("address", FieldType.MultilineTextField);
- public static final Field RATING = new Field("rating", FieldType.Rating);
- public static final Field COMMENT = new Field("comment", FieldType.MultilineTextField);
- public static final Field TAGS = new Field("tags", FieldType.MultilineTextField);
-
private FieldType type;
private String name;
+ private int order;
/**
* Creates a new field object with the given name and fieldType
@@ -31,6 +46,11 @@
public Field(String name, FieldType f){
this.type = f;
this.name = name;
+ this.order = DEFAULT_ORDER;
+ }
+ private Field(String name, FieldType f, int order){
+ this(name, f);
+ this.order = order;
}
/**
* Creates a new field object matching the string desc
@@ -41,8 +61,13 @@ protected Field(String desc) throws IllegalArgumentException{
String[] sp = desc.split(":");
try{
this.type = FieldType.values()[Integer.parseInt(sp[1])];
+ this.order = Integer.parseInt(sp[2]);
} catch(NumberFormatException e) {
throw new IllegalArgumentException("The input string: " + desc + " is improperly formatted!");
+ } catch(IndexOutOfBoundsException e){
+ Field def = fieldMap.get(this.type);
+ if(def != null) this.order = def.order;
+ else this.order = DEFAULT_ORDER;
}
this.name = sp[0];
}
@@ -70,7 +95,18 @@ public String getName() {
*/
protected String toDB(){
int fieldType = this.type.ordinal();
- return this.name + ":" + fieldType;
+ return this.name + ":" + fieldType + ":" + order;
+ }
+ public static List<Field> getAllFields(){
+ List<Field> out = new LinkedList<Field>();
+ out.add(NAME);
+ out.add(WEBSITE);
+ out.add(PHONENUMBER);
+ out.add(ADDRESS);
+ out.add(RATING);
+ out.add(COMMENT);
+ out.add(TAGS);
+ return out;
}
/**
* Returns a list of the static default variables.
@@ -132,4 +168,12 @@ public boolean equals(Object other){
public int hashCode(){
return this.name.hashCode()*10 + this.type.ordinal();
}
+ public int compareTo(Object another) {
+ if (this == another) return 0;
+ Field o = (Field) another;
+ if(o.order == this.order) return this.name.compareTo(o.name);
+ if(o.order == DEFAULT_ORDER) return -1;
+ if(this.order == DEFAULT_ORDER) return 1;
+ return this.order - o.order;
+ }
}
View
2 src/we/should/list/GenericCategory.java
@@ -95,7 +95,7 @@ public Item getItem(int index) {
Log.e("GenericCategory.getItems()", "Database data string improperly formatted");
}
}
- cur.close(); // T.S.
+ cur.close();
db.close();
return out;
}
View
4 src/we/should/list/GenericItem.java
@@ -42,7 +42,6 @@
protected GenericItem(Category c, Context ctx) {
super(ctx);
this.c = c;
- values = new LinkedHashMap<Field, String>();
List<Field> fields = this.getFields();
for(Field i : fields){
if (i.getType().equals(FieldType.CheckBox)) {
@@ -114,7 +113,8 @@ public void delete() {
WSdb db = new WSdb(ctx);
db.open();
db.deleteItem(this.id);
- Set<Tag> tags = getTags();
+ Set<Tag> tags = getTags();
+ //TODO: database deletes all item-tags on item delete. Should I change? -- Troy
for(Tag t: tags){
db.deleteItemTagRel(this.id, t.getId());
}
View
8 src/we/should/list/Item.java
@@ -24,10 +24,12 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
+import java.util.TreeMap;
import org.json.JSONArray;
import org.json.JSONException;
@@ -49,6 +51,7 @@
protected Item(Context ctx){
this.ctx = ctx;
this.id = 0;
+ this.values = new TreeMap<Field, String>();
}
/**
* @return a set of Address objects corresponding to the location(s) of this.
@@ -175,7 +178,7 @@ protected Item(Context ctx){
cat.id = catId;
cat.color = color;
cats.put(catId, cat);
- c.close(); // TS
+ c.close();
} else {
cat = cats.get(catId);
}
@@ -243,7 +246,8 @@ public int getId() {
*/
public JSONObject dataToDB(){
JSONObject out = new JSONObject();
- for(Entry<Field, String> e : values.entrySet()){
+ Set<Entry<Field, String>> entries = values.entrySet();
+ for(Entry<Field, String> e : entries){
try {
out.put(e.getKey().toDB(), e.getValue());
} catch (JSONException err) {
View
16 src/we/should/list/ReferralItem.java
@@ -1,5 +1,6 @@
package we.should.list;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -18,7 +19,9 @@
public class ReferralItem extends GenericItem {
-
+
+ private List<Field> fields;
+
/**
* Creates a new Referral Item from the JSON object passed to it
@@ -43,6 +46,17 @@ protected ReferralItem(Category c, JSONObject values, Context ctx) {
out.remove(Field.TAGS); //Remove special field
return out;
}
+ protected void DBtoData(JSONObject d) throws JSONException{
+ this.fields = new LinkedList<Field>();
+ super.DBtoData(d);
+ @SuppressWarnings("unchecked")
+ Iterator<String> keys = d.keys();
+ String k;
+ while(keys.hasNext()){
+ k = keys.next();
+ fields.add(new Field(k));
+ }
+ }
}
View
1 src/we/should/list/Tag.java
@@ -32,6 +32,7 @@
* Creates a new tag object with the given name and DB id
* @param id
* @param tag
+ * @param color
*/
public Tag(int id, String tag, String color){
this.id = id;
View
168 src/we/should/search/CustomPinPoint.java
@@ -1,94 +1,132 @@
package we.should.search;
-
+import java.util.ArrayList;
+import java.util.List;
import we.should.CustomDialog;
import we.should.list.Item;
-
import android.app.Dialog;
import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Point;
-import android.util.Log;
-
+import android.graphics.drawable.Drawable;
import com.google.android.maps.GeoPoint;
-import com.google.android.maps.MapView;
-import com.google.android.maps.Overlay;
-import com.google.android.maps.Projection;
+import com.google.android.maps.ItemizedOverlay;
+import com.google.android.maps.OverlayItem;
/**
* A CustomPinPoint on the map.
* @author Lawrence
*/
-public class CustomPinPoint extends Overlay {
+public class CustomPinPoint extends ItemizedOverlay<OverlayItem> {
private Item item;
- private GeoPoint point;
- private Projection projection;
- private int color;
private Context context;
+ private List<OverlayItem> mapOverlays;
+ private double distance;
+ private boolean isSelected;
+ private String color;
- public CustomPinPoint(Context c, Item item, GeoPoint p, Projection projection, int color) {
- Log.v("customPinPoint","color="+color);
- this.context = c;
+ //Here if the color indicate the color of the pin, but if select is true, the pin is yellow color.
+ //It is useful when we need to revert back to the original color.
+ public CustomPinPoint(Drawable pin, Context context, Item item, double distance, boolean isSelected, String color) {
+ super(boundCenterBottom(pin));
+ this.context = context;
this.item = item;
- this.point = p;
- this.projection = projection;
+ this.distance = distance;
+ mapOverlays = new ArrayList<OverlayItem>();
+ this.isSelected = isSelected;
this.color = color;
}
/**
- * Draw a Pin.
+ * this method is call when user click on the item
+ */
+ @Override
+ protected boolean onTap(int index) {
+ Dialog popup = new CustomDialog(context, item, this.distance, 0);
+ popup.show();
+ return true;
+ }
+
+ /**
+ * getting the overlayItem given an index
*/
@Override
- public void draw(Canvas canvas, MapView mapView, boolean shadow) {
- super.draw(canvas, mapView, shadow);
- Paint mPaint = new Paint();
- mPaint.setStrokeWidth(2);
- mPaint.setColor(color);
- mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
- mPaint.setAntiAlias(true);
- Point p = new Point();
- projection.toPixels(point,p);
- Point p1 = new Point(p.x - 5, p.y -15);
- Point p2 = new Point(p.x, p.y);
- Point p3 = new Point(p.x + 5, p.y -15);
- canvas.drawCircle(p.x, p.y - 15, 5, mPaint);
- Path path = new Path();
- path.setFillType(Path.FillType.EVEN_ODD);
- path.moveTo(p1.x,p1.y);
- path.lineTo(p2.x, p2.y);
- path.lineTo(p3.x,p3.y);
- path.lineTo(p1.x, p1.y);
- path.close();
- canvas.drawPath(path, mPaint);
- Paint textPaint = new Paint();
- textPaint.setStrokeWidth(3);
- textPaint.setColor(Color.BLACK);
- canvas.drawText(item.getName(), p.x, p.y, textPaint);
+ protected OverlayItem createItem(int index) {
+ if(index < 0 || index >= mapOverlays.size()) {
+ throw new IllegalArgumentException("index out of bound when getting OverlayItem");
+ }
+ return mapOverlays.get(index);
}
/**
- * Detect the tap on the image.
+ * @param overlay - add the overlay
+ */
+ public void addOverlay(OverlayItem overlay) {
+ if(overlay == null) {
+ throw new IllegalArgumentException("overlay is null");
+ }
+ mapOverlays.add(overlay);
+ populate();
+ }
+
+ /**
+ * Remove the overlay item.
+ * @param overlay
+ */
+ public void removeOverlay(int index) {
+ if(index < 0 || index >= mapOverlays.size()) {
+ throw new IllegalArgumentException("index out of bound when getting OverlayItem");
+ }
+ mapOverlays.remove(index);
+ }
+
+ /**
+ * return the size of the mapOverlays.
*/
@Override
- public boolean onTap(GeoPoint clickpoint, MapView mapView) {
- // This can be used to find the distance.
- // float[] results = new float[1];
- // Location.distanceBetween(myLoc.getLatitudeE6(),myLoc.getLongitudeE6()
- // ,placeLocation.getLatitudeE6(), placeLocation.getLongitudeE6()
- // ,results);
- Point p1 = new Point();
- Point p2 = new Point();
- projection.toPixels(clickpoint, p1);
- projection.toPixels(point, p2);
- if(p1.x > p2.x - 10 && p1.x < p2.x + 10 &&
- p1.y > p2.y - 15 && p1.y < p2.y + 5) {
- Dialog dialog = new CustomDialog(context, item, 0, 0);
- dialog.show();
- return true;
- } else {
- return super.onTap(clickpoint, mapView);
+ public int size() {
+ return mapOverlays.size();
+ }
+
+ /**
+ * @param p - to see if the CustomPinPoints contains that point
+ * @return true if it contains, false otherwise.
+ */
+ public boolean contains(GeoPoint p) {
+ for(OverlayItem overlay : mapOverlays) {
+ if(overlay.getPoint().equals(p)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return String - the original color of the pin, yellow pin may return red,
+ * because yellow is the special pin, allow us to make a pin with the original color.
+ */
+ public String getColor() {
+ return color;
+ }
+
+ /**
+ * @return true if the pin is yellow, the user selecting it, false otherwise.
+ */
+ public boolean isSelected() {
+ return isSelected;
+ }
+
+ /**
+ * @return getting the GeoPoint, so that we can build a pin in that location.
+ */
+ public GeoPoint getPoint() {
+ for(OverlayItem overlay : mapOverlays) {
+ return overlay.getPoint();
}
+ return null;
+ }
+
+ /**
+ * @return Item, the item in the pinpoint, useful for rebuilding a new pin with different drawable.
+ */
+ public Item getItem() {
+ return item;
}
}
View
47 src/we/should/search/DetailPlace.java
@@ -9,20 +9,28 @@
/**
- * Detail place is an extension to place. It has more information about a place.
- * including phoneNumber, website, url, address, international_phoneNumber.
+ * DetailPlace is immutable.
*
- * Before using the DetailPlace, be sure to check whether or not the DetailPlace is valid.
- * When there is error in parsing the JSONObject, call the isValid() method to determine that
+ * Detail place is an extension to place. It has more information
+ * about a place including phoneNumber, website, url, address,
+ * international_phoneNumber.
*
- * To construct a Detailplace, you need a JSONObject from a DetailPlaceQuery on Google API.
+ * Before using the DetailPlace, be sure to check whether or not the
+ * DetailPlace is valid. When there is error in parsing the JSONObject,
+ * call the isValid() method to determine that
*
- * @thorws JSONException - if the JSONObject pass through the constructor fail.
* @author Lawrence
*/
public class DetailPlace extends Place{
- private String phoneNumber, website, url, address, international_phoneNumber;
+ private String phoneNumber, website, url, address,
+ international_phoneNumber;
+ /**
+ * To construct a Detailplace, you need a
+ *
+ * @param obj JSONObject from a DetailPlaceQuery on Google API.
+ * @thorws JSONException - if obj fails.
+ */
public DetailPlace(JSONObject obj) throws JSONException {
super(obj);
phoneNumber = obj.optString("formatted_phone_number", null);
@@ -33,16 +41,14 @@ public DetailPlace(JSONObject obj) throws JSONException {
}
/**
- * To get the Local Phone Number
* @return String - local phone number
*/
public String getLocalPhoneNumber() {
return phoneNumber;
}
/**
- * To get the international Phone Number
- * @return String - the internation phone number
+ * @return String - the international phone number
*/
public String getInternational_phoneNumber() {
return international_phoneNumber;
@@ -70,8 +76,7 @@ public String getAddress() {
}
/**
- * Returns the fields of this DetailPlace as a field map.
- * @return see above you loony
+ * @return the fields of this DetailPlace as a field map.
*/
public Map<Field, String> asFieldMap() {
Map<Field, String> map = new HashMap<Field, String>();
@@ -80,4 +85,22 @@ public String getAddress() {
map.put(Field.PHONENUMBER, getLocalPhoneNumber());
return map;
}
+
+ /**
+ * they are the same, if their reference is the same
+ */
+ @Override
+ public boolean equals(Object o) {
+ if(o != null && getClass() == o.getClass()) {
+ DetailPlace p = (DetailPlace) o;
+ return super.equals(p) && p.phoneNumber.equals(this.phoneNumber)
+ && p.website.equals(this.website)
+ && p.url.equals(this.url)
+ && p.address.equals(this.address)
+ && p.international_phoneNumber.equals(this.international_phoneNumber);
+
+ } else {
+ return false;
+ }
+ }
}
View
20 src/we/should/search/Place.java
@@ -3,12 +3,15 @@
import org.json.JSONObject;
/**
+ * Place is immutable.
+ *
* To construct a Place, you need to pass in a JSONObject
* come back from querying google place search by location and name.
* It will parse the JSONObject and provide method to address information.
*
* Before using the Place, be sure to check whether or not the Place is valid.
- * When there is error in parsing the JSONObject. call the isValid() method to determine if Place is valid.
+ * When there is error in parsing the JSONObject. call the isValid() method to
+ * determine if Place is valid.
*
* @throws JSONException - if the JSONObject pass through the constructor fail.
* @author Lawrence
@@ -102,4 +105,19 @@ public String toString() {
return getName();
}
+ /**
+ * they are the same, if their reference is the same
+ */
+ @Override
+ public boolean equals(Object o) {
+ if(o != null && getClass() == o.getClass()) {
+ Place p = (Place) o;
+ return p != null && p.reference.equals(this.reference);
+ } else {
+ return false;
+ }
+ }
+
+
+
}
View
36 src/we/should/search/PlaceRequest.java
@@ -51,11 +51,13 @@ public PlaceRequest() {
//Possible feature:
//Note that Location can be get by getting the Device Location, on when user click on the map, we can get the location.
public List<Place> searchByLocation(Location l, String searchname) throws Exception{
- if(l == null) {
- throw new IllegalArgumentException("Location is null");
+ if(l == null || searchname == null) {
+ throw new IllegalArgumentException("input is null");
}
- Log.v(LOG_KEY, "Start SearchByLocation");
+
+ Log.v(LOG_KEY, "Start SearchByLocation: " + searchname +".");
try {
+ searchname = searchname.trim();
URI url = buildURLForGooglePlaces(l, searchname);
JSONObject obj = executeQuery(url);
//make sure status is okay before we get the results
@@ -68,6 +70,9 @@ public PlaceRequest() {
places.add(new Place(place));
}
return places;
+ } else if(obj.getString("status").equals("ZERO_RESULTS")){
+ Log.v(LOG_KEY, "zero results");
+ return null;
} else {
Log.v(LOG_KEY, obj.getString("status"));
}
@@ -88,6 +93,10 @@ public PlaceRequest() {
* @return DetailPlace if success, null if fail
*/
public DetailPlace searchPlaceDetail(String reference) {
+ if(reference == null) {
+ throw new IllegalArgumentException("reference string is null");
+ }
+
try {
URI url = buildURLForDetailPlace(reference);
JSONObject obj = executeQuery(url);
@@ -99,7 +108,7 @@ public DetailPlace searchPlaceDetail(String reference) {
Log.v(LOG_KEY, "query status fail");
}
} catch (Exception e) {
- Log.v(LOG_KEY, e.getMessage());
+ Log.e(LOG_KEY, e.getMessage());
}
return null;
}
@@ -112,7 +121,9 @@ public DetailPlace searchPlaceDetail(String reference) {
* @throws ClientProtocolException
* @throws IOException
*/
- private JSONObject executeQuery(URI url) throws JSONException, ClientProtocolException, IOException, URISyntaxException {
+ private JSONObject executeQuery(URI url)
+ throws JSONException, ClientProtocolException,
+ IOException, URISyntaxException {
HttpClient httpclient = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
ResponseHandler<String> handler = new BasicResponseHandler();
@@ -125,25 +136,28 @@ private JSONObject executeQuery(URI url) throws JSONException, ClientProtocolExc
* Build the url for the searchByLocation query
*
* @param myLocation - given the location to search
- * @param searchName - the name to filter the results
- * searchName is filter such that only places contains the exactly searchName in its name will be return
- *
+ * @param searchName - the name to filter the results. searchName
+ * is filter such that only places contains the exactly
+ * searchName in its name will be return
* @return url for the searchByLocation query
* @throws URISyntaxException
*/
- private URI buildURLForGooglePlaces(Location myLocation, String searchName) throws URISyntaxException{
+ private URI buildURLForGooglePlaces(Location myLocation, String searchName)
+ throws URISyntaxException{
String baseUrl = PLACES_SEARCH_URL;
String lat = String.valueOf(myLocation.getLatitude());
String lon = String.valueOf(myLocation.getLongitude());
String url = baseUrl + "location=" + lat + "," + lon + "&" +
- "rankby=distance" + "&" + "sensor=false" +
+ "rankby=distance" + "&" + "sensor=true" +
"&" + "name=" + searchName +
"&" + "key=" + keyString;
+ Log.v(LOG_KEY, "build string url is: " + url);
return new URI(SCHEME, url, null);
}
/**
- * @param referenceString - the reference obtain by Place Object which get it by performing a searchByLocation query
+ * @param referenceString - the reference obtain by Place Object
+ * which get it by performing a searchByLocation query
* @return url for the placeDetail query
*/
private URI buildURLForDetailPlace(String referenceString) throws URISyntaxException {

0 comments on commit fb3b551

Please sign in to comment.
Something went wrong with that request. Please try again.