Goku
Goku

Reputation: 1663

Geocode results based on current location

In one of my activities i need to be able to do a geocoding (find a location by address String search). The problem is that my results are much too broad. When i search for "mcdonalds" i get results that are in different parts of the USA. How can i make it so a user can search for nearby restaurants (or any location) and the results will be within a certain distance? I basically need more precise results for my application. Here is a screenshot of whats happening: enter image description here

public class MainActivity extends MapActivity {
HelloItemizedOverlay itemizedOverlay;
List<Overlay> mapOverlays;
Drawable drawable;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    MapView myMap = (MapView) findViewById(R.id.mapview);
    myMap.setBuiltInZoomControls(true);

    MapController mc = myMap.getController();

    mapOverlays = myMap.getOverlays();
    drawable = this.getResources().getDrawable(R.drawable.androidmarker);
    itemizedOverlay = new HelloItemizedOverlay(drawable, this);

    //geopoints are cordinates in microdegrees or degrees * E6
    GeoPoint point = new GeoPoint(34730300, -86586100);
    //GeoPoint point2 = locatePlace("texas", mc); //HelloItemizedOverlay.locatePlace("Texas", mc, myMap);

    //overlayitems are items that show the point of location to the user
    OverlayItem overlayitem = new OverlayItem(point, "Hola, Mundo!", "im in huntsville");
    //OverlayItem overlayitem2 = new OverlayItem(point2, "Texas", "hi");

    //itemizedoverlay is used here to add a drawable to each of the points
    itemizedOverlay.addOverlay(overlayitem);
    //itemizedOverlay.addOverlay(overlayitem2);

    //this adds the drawable to the map

    //this method converts the search address to locations on the map and then finds however many you wish to see.
    locatePlace("mcdonalds", mc, 5);
    mapOverlays.add(itemizedOverlay);

    //this animates to the point desired (i plan on having "point" = current location of the user)
    mc.animateTo(point);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

@Override
protected boolean isRouteDisplayed(){
    return false;
}

public void locatePlace(String locName, MapController mc, int numberToDisplay)
{   // code to make the google search via string work

    // i use the Geocoder class is used to handle geocoding and reverse-geocoding. So make an instance of this class to work with the methods included
    Geocoder geoCoder1 = new Geocoder(this, Locale.getDefault());
    try {
        List<Address> searchAddresses = geoCoder1.getFromLocationName(locName, numberToDisplay);  // gets a max of 5 locations
        if (searchAddresses.size() > 0)
            {
            //iterate through using an iterator loop (for loop would have been fine too)
            //Iterator<Address> iterator1 = searchAddresses.iterator();
            for (int i=0; i < searchAddresses.size(); i++){
            //while (iterator1.hasNext()){
                //step1 get a geopoint
                GeoPoint tempGeoP = new GeoPoint( (int) (searchAddresses.get(i).getLatitude()*1E6), (int) (searchAddresses.get(i).getLongitude()*1E6) );
                //step2 add the geopoint to the Overlay item 
                OverlayItem tempOverlayItm = new OverlayItem(tempGeoP, locName, "this is " + locName);
                //step3 add the overlay item to the itemized overlay
                HelloItemizedOverlay tempItemizedOverlay = new HelloItemizedOverlay(drawable, this);  // its breakking here.........
                tempItemizedOverlay.addOverlay(tempOverlayItm);
                //the itemized overlay is added to the map Overlay
                mapOverlays.add(tempItemizedOverlay);
            }

            }
        } catch (IOException e)
        {
            e.printStackTrace();
            // Log.e("the error", "something went wrong: "+ e);
        }//finally   {}
    }
}

// here is the important code from the Itemized overlay class

public HelloItemizedOverlay(Drawable defaultMarker, Context context)
    {
        super(boundCenter(defaultMarker));
        myContext = context;
    }

    public void addOverlay(OverlayItem overlay){
        mOverlays.add(overlay);
        populate();
    }

Thanks, Adam

Here is some code after adjusting to Vishwa's comments:

 // these 2 variables are my current location
    latitudeCurrent  = 34730300;   // make this dynamic later
    longitudeCurrent = -86586100;  // make this dynamic later


LLlatitude  = (latitudeCurrent - 100000)/(1E6); //lowerleft latitude = original lat - (1)*degree/10
LLlongitude = (longitudeCurrent+ 100000)/(1E6);//lowerleft longitude = original longitude - (1)*degree/10
URlatitude  = (latitudeCurrent + 100000)/(1E6); //upperright latitude = original + (1)*degree/10
URlongitude = (longitudeCurrent+ 100000)/(1E6); //upperright longitude = original longitude + (1)*degree/10

        try {
            List<Address> searchAddresses = geoCoder1.getFromLocationName(locName, numberToDisplay, LLlatitude, LLlongitude, URlatitude, URlongitude); 

after creating a square of allowable results from the getfromlocationname()

Upvotes: 0

Views: 1106

Answers (1)

A Random Android Dev
A Random Android Dev

Reputation: 2691

Here's what you need to do:

1.) Obtain the user's current location using GPS, here's an answer that'll help you do that.

2.) Next, figure out in what radius do you wish to display your results, i.e do you need results that are within 2 miles of the user's location or 5 miles or so on.

3.) Figure out what this (refers to point 2) translates into in terms of latitude and longitude values, so basically you will have to define a bounding-box with a lowerLeftLatitude, lowerLeftLongitude, lowerRightLatitude, lowerRightLongitude. These calculations can be done by figuring out how much one longitude translates into in terms of miles (again, this calculation will probably be approximate because the distance between longitude changes from places to place due to the very nature of how longitudes work (read this: http://en.wikipedia.org/wiki/Longitude if you wish to make adjustments based on each person's location)

4.) Use the following method (it's a variant of getFromLocationName) instead of using the version that you are using right now: http://developer.android.com/reference/android/location/Geocoder.html#getFromLocationName(java.lang.String, int, double, double, double, double). Read how this method works, basically you will be specifying the bounding box values as well now apart from the name (i.e McDonalds). So now, you will get more user-location-specific results.

Let me know how it goes/ if you need more help

Here's the code for getting the JSON response from the Places API: Once again DON'T forget to replace the "AddYourOwnKeyHere" with your Places API key

try
{
HttpPost httppost = new HttpPost("https://maps.googleapis.com/maps/api/place/search/json?location=34.730300,-86.586100&radius=19308&types=food&name=mcdonalds&sensor=false&key=AddYourOwnKeyHere");
HttpClient httpclient = new DefaultHttpClient();
response = httpclient.execute(httppost);
String data = EntityUtils.toString(response.getEntity());
JSONObject json = new JSONObject(data);
//Parse the JSONObject now
} catch (Exception e) {
e.printStackTrace();
}

Upvotes: 1

Related Questions