我正在尝试在android中的谷歌地图上搜索附近的地方,例如银行,餐馆,自动取款机

Posted

技术标签:

【中文标题】我正在尝试在android中的谷歌地图上搜索附近的地方,例如银行,餐馆,自动取款机【英文标题】:I'm trying to search nearby places such as banks, restaurants, ATMs inside the drawn area on google maps in android 【发布时间】:2015-07-21 14:05:22 【问题描述】:

我正在尝试在安卓的谷歌地图上搜索附近的地方,如银行、餐馆、自动取款机。我在数组中获得坐标(纬度和经度),但我无法通过该数组找到附近的地方。 有人可以帮助我吗?我试图搜索但没有找到结果。 我们将不胜感激!

这是我绘制的区号:

public class MainActivity extends FragmentActivity implements OnTouchListener 

    private static final String TAG = "polygon";
    private GoogleMap mGoogleMap;
    private View mMapShelterView;
    private GestureDetector mGestureDetector;
    private ArrayList<LatLng> mLatlngs = new ArrayList<LatLng>();
    private PolylineOptions mPolylineOptions;
    private PolygonOptions mPolygonOptions;
    // flag to differentiate whether user is touching to draw or not
    private boolean mDrawFinished = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mMapShelterView = (View) findViewById(R.id.drawer_view);
        mGestureDetector = new GestureDetector(this, new GestureListener());
        mMapShelterView.setOnTouchListener(this);
        initilizeMap();
        //Contains(null);
    

    private final class GestureListener extends SimpleOnGestureListener 
        @Override
        public boolean onDown(MotionEvent e) 
            return true;
        

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) 
            return false;
        
    

    /**
     * Ontouch event will draw poly line along the touch points
     * 
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) 
        int X1 = (int) event.getX();
        int Y1 = (int) event.getY();
        Point point = new Point();
        point.x = X1;
        point.y = Y1;
        LatLng firstGeoPoint = mGoogleMap.getProjection().fromScreenLocation(
                point);
        switch (event.getAction()) 

        case MotionEvent.ACTION_DOWN:
            break;

        case MotionEvent.ACTION_MOVE:
            if (mDrawFinished) 
                X1 = (int) event.getX();
                Y1 = (int) event.getY();
                point = new Point();
                point.x = X1;
                point.y = Y1;
                LatLng geoPoint = mGoogleMap.getProjection()
                        .fromScreenLocation(point);
                mLatlngs.add(geoPoint);
                mPolylineOptions = new PolylineOptions();
                mPolylineOptions.color(Color.RED);
                mPolylineOptions.width(3);
                mPolylineOptions.addAll(mLatlngs);
                mGoogleMap.addPolyline(mPolylineOptions);
                **Log.d(TAG, "Latitude and longitude: " + mLatlngs);**

            
            break;
        case MotionEvent.ACTION_UP:
            Log.d(TAG, "Poinnts array size " + mLatlngs.size());
            mLatlngs.add(firstGeoPoint);
            mGoogleMap.clear();
            mPolylineOptions = null;
            mMapShelterView.setVisibility(View.GONE);
            mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
            mGoogleMap.getUiSettings().setAllGesturesEnabled(true);
            mPolygonOptions = new PolygonOptions();
            mPolygonOptions.fillColor(0x5500ff00);
           // mPolygonOptions.fillColor(Color.LTGRAY);
            mPolygonOptions.strokeColor(Color.RED);
            mPolygonOptions.strokeWidth(5);
            mPolygonOptions.addAll(mLatlngs);
            mGoogleMap.addPolygon(mPolygonOptions);
            mDrawFinished = false;
            break;
        
        return mGestureDetector.onTouchEvent(event);
    

    /**
     * Setting up map
     * 
     */

    private void initilizeMap() 
        int status = GooglePlayServicesUtil
                .isGooglePlayServicesAvailable(getApplicationContext());
        if (status == ConnectionResult.SUCCESS) 
            if (mGoogleMap == null) 
                mGoogleMap = ((SupportMapFragment) getSupportFragmentManager()
                        .findFragmentById(R.id.map)).getMap();
                mGoogleMap.setMyLocationEnabled(true);

            

         else if (GooglePlayServicesUtil.isUserRecoverableError(status)) 
            // showErrorDialog(status);
         else 
            Toast.makeText(this, "No Support for Google Play Service",
                    Toast.LENGTH_LONG).show();
        
    

    /**
     * Method gets called on tap of draw button, It prepares the screen to draw
     * the polygon
     * 
     * @param view
     */

    public void drawZone(View view) 
        mGoogleMap.clear();
        mLatlngs.clear();
        mPolylineOptions = null;
        mPolygonOptions = null;
        mDrawFinished = true;
        mMapShelterView.setVisibility(View.VISIBLE);
        mGoogleMap.getUiSettings().setScrollGesturesEnabled(false);
    

    public synchronized boolean Contains(Location location) 
        boolean isInside = false;

        if (mLatlngs.size() > 0) 
            LatLng lastPoint = mLatlngs.get(mLatlngs.size() - 1);

            double x = location.getLongitude();

            for (LatLng point : mLatlngs) 
                double x1 = lastPoint.longitude;
                double x2 = point.longitude;
                double dx = x2 - x1;

                if (Math.abs(dx) > 180.0) 
                    if (x > 0) 
                        while (x1 < 0)
                            x1 += 360;
                        while (x2 < 0)
                            x2 += 360;
                     else 
                        while (x1 > 0)
                            x1 -= 360;
                        while (x2 > 0)
                            x2 -= 360;
                    
                    dx = x2 - x1;
                

                if ((x1 <= x && x2 > x) || (x1 >= x && x2 < x)) 
                    double grad = (point.latitude - lastPoint.latitude) / dx;
                    double intersectAtLat = lastPoint.latitude
                            + ((x - x1) * grad);

                    if (intersectAtLat > location.getLatitude())
                        isInside = !isInside;
                
                lastPoint = point;
            
        

        return isInside;
    

我在 mLatlang 上得到了数组,现在我想根据该坐标而不是我当前的位置靠近地点

【问题讨论】:

试试 google places api。 developers.google.com/places 附近的搜索使用以下链接。 developers.google.com/places/webservice/search 【参考方案1】:

这里有一些使用 Places Web Service API 的工作代码,这应该可以帮助您获得所需的功能。

一般文档可以在here找到。

可以在here找到支持的地点类型。

下面是一个简单的例子。首先,为 API 生成查询字符串:

public StringBuilder sbMethod() 

    //use your current location here
    double mLatitude = 37.77657;
    double mLongitude = -122.417506;

    StringBuilder sb = new StringBuilder("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
    sb.append("location=" + mLatitude + "," + mLongitude);
    sb.append("&radius=5000");
    sb.append("&types=" + "restaurant");
    sb.append("&sensor=true");
    sb.append("&key=******* YOUR API KEY****************");

    Log.d("Map", "api: " + sb.toString());

    return sb;

这是用于查询 Places API 的AsyncTask

private class PlacesTask extends AsyncTask<String, Integer, String> 

    String data = null;

    // Invoked by execute() method of this object
    @Override
    protected String doInBackground(String... url) 
        try 
            data = downloadUrl(url[0]);
         catch (Exception e) 
            Log.d("Background Task", e.toString());
        
        return data;
    

    // Executed after the complete execution of doInBackground() method
    @Override
    protected void onPostExecute(String result) 
        ParserTask parserTask = new ParserTask();

        // Start parsing the Google places in JSON format
        // Invokes the "doInBackground()" method of the class ParserTask
        parserTask.execute(result);
    

这里是downloadURL() 方法:

private String downloadUrl(String strUrl) throws IOException 
    String data = "";
    InputStream iStream = null;
    HttpURLConnection urlConnection = null;
    try 
        URL url = new URL(strUrl);

        // Creating an http connection to communicate with url
        urlConnection = (HttpURLConnection) url.openConnection();

        // Connecting to url
        urlConnection.connect();

        // Reading data from url
        iStream = urlConnection.getInputStream();

        BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

        StringBuffer sb = new StringBuffer();

        String line = "";
        while ((line = br.readLine()) != null) 
            sb.append(line);
        

        data = sb.toString();

        br.close();

     catch (Exception e) 
        Log.d("Exception while downloading url", e.toString());
     finally 
        iStream.close();
        urlConnection.disconnect();
    
    return data;

ParserTask 用于解析 JSON 结果:

private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String, String>>> 

    JSONObject jObject;

    // Invoked by execute() method of this object
    @Override
    protected List<HashMap<String, String>> doInBackground(String... jsonData) 

        List<HashMap<String, String>> places = null;
        Place_JSON placeJson = new Place_JSON();

        try 
            jObject = new JSONObject(jsonData[0]);

            places = placeJson.parse(jObject);

         catch (Exception e) 
            Log.d("Exception", e.toString());
        
        return places;
    

    // Executed after the complete execution of doInBackground() method
    @Override
    protected void onPostExecute(List<HashMap<String, String>> list) 

        Log.d("Map", "list size: " + list.size());
        // Clears all the existing markers;
        mGoogleMap.clear();

        for (int i = 0; i < list.size(); i++) 

            // Creating a marker
            MarkerOptions markerOptions = new MarkerOptions();

            // Getting a place from the places list
            HashMap<String, String> hmPlace = list.get(i);


            // Getting latitude of the place
            double lat = Double.parseDouble(hmPlace.get("lat"));

            // Getting longitude of the place
            double lng = Double.parseDouble(hmPlace.get("lng"));

            // Getting name
            String name = hmPlace.get("place_name");

            Log.d("Map", "place: " + name);

            // Getting vicinity
            String vicinity = hmPlace.get("vicinity");

            LatLng latLng = new LatLng(lat, lng);

            // Setting the position for the marker
            markerOptions.position(latLng);

            markerOptions.title(name + " : " + vicinity);

            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));

            // Placing a marker on the touched position
            Marker m = mGoogleMap.addMarker(markerOptions);

        
    

Place_JSONParserTask中使用的类:

public class Place_JSON 

    /**
     * Receives a JSONObject and returns a list
     */
    public List<HashMap<String, String>> parse(JSONObject jObject) 

        JSONArray jPlaces = null;
        try 
            /** Retrieves all the elements in the 'places' array */
            jPlaces = jObject.getJSONArray("results");
         catch (JSONException e) 
            e.printStackTrace();
        
        /** Invoking getPlaces with the array of json object
         * where each json object represent a place
         */
        return getPlaces(jPlaces);
    

    private List<HashMap<String, String>> getPlaces(JSONArray jPlaces) 
        int placesCount = jPlaces.length();
        List<HashMap<String, String>> placesList = new ArrayList<HashMap<String, String>>();
        HashMap<String, String> place = null;

        /** Taking each place, parses and adds to list object */
        for (int i = 0; i < placesCount; i++) 
            try 
                /** Call getPlace with place JSON object to parse the place */
                place = getPlace((JSONObject) jPlaces.get(i));
                placesList.add(place);
             catch (JSONException e) 
                e.printStackTrace();
            
        
        return placesList;
    

    /**
     * Parsing the Place JSON object
     */
    private HashMap<String, String> getPlace(JSONObject jPlace) 

        HashMap<String, String> place = new HashMap<String, String>();
        String placeName = "-NA-";
        String vicinity = "-NA-";
        String latitude = "";
        String longitude = "";
        String reference = "";

        try 
            // Extracting Place name, if available
            if (!jPlace.isNull("name")) 
                placeName = jPlace.getString("name");
            

            // Extracting Place Vicinity, if available
            if (!jPlace.isNull("vicinity")) 
                vicinity = jPlace.getString("vicinity");
            

            latitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lat");
            longitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lng");
            reference = jPlace.getString("reference");

            place.put("place_name", placeName);
            place.put("vicinity", vicinity);
            place.put("lat", latitude);
            place.put("lng", longitude);
            place.put("reference", reference);

         catch (JSONException e) 
            e.printStackTrace();
        
        return place;
    

最后,像这样调用这个过程:

    StringBuilder sbValue = new StringBuilder(sbMethod());
    PlacesTask placesTask = new PlacesTask();
    placesTask.execute(sbValue.toString());

结果:

【讨论】:

感谢您提供此代码,我已经在处理它,但您能否提供代码以在印度任何地方(银行、自动取款机、restra 等)附近查找 @shivanibajpai 您只需要修改用于查询字符串的纬度/经度和半径。 @DanielNugent 我想实现与 Shivani 相同的功能。只是我想将附近的搜索仅限于医院。你能帮我吗?现在我能够获取用户的当前位置。现在我想获取附近医院的详细信息。 @user 只需将餐厅替换为医院作为网址中的地点类型。 @DanielNugent 我尝试过同样的方法,但它不起作用。每当我尝试运行该应用时,该应用就会崩溃。【参考方案2】:

使用这个nearbysearch api:

提供lat,lng,typekey.

https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=22.5849923,88.4016579&radius=10000&types=bar&key=YOUR_KEY

【讨论】:

您是否正确阅读了这个问题,这个问题本身已经使用了 AsyncTask doInBackground 方法中附近的 api,而您只是提供了 api url 作为答案【参考方案3】:

首先在你的 manifest.xml 文件中使用它

 <uses-permission android:name="in.wptrafficanalyzer.locationgeocodingv2.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />
<meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="your API Key" />

此代码放入您的活动中..

package in.wptrafficanalyzer.locationgeocodingv2;

import java.io.IOException;
import java.util.List;

import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends FragmentActivity 

GoogleMap googleMap;
MarkerOptions markerOptions;
LatLng latLng;
private AutoCompleteTextView actv_Serch;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    SupportMapFragment supportMapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);

    // Getting a reference to the map
    googleMap = supportMapFragment.getMap();

    // Getting reference to btn_find of the layout activity_main
    Button btn_find = (Button) findViewById(R.id.btn_find);

    // Defining button click event listener for the find button
    OnClickListener findClickListener = new OnClickListener() 
        @Override
        public void onClick(View v) 
            // Getting reference to EditText to get the user input location
            // EditText etLocation = (EditText)
            // findViewById(R.id.et_location);
            actv_Serch = (AutoCompleteTextView) findViewById(R.id.actv_Search);

            // Getting user input location
            String location = actv_Serch.getText().toString();

            if (location != null && !location.equals("")) 
                new GeocoderTask().execute(location);
            
        
    ;

    // Setting button click event listener for the find button
    btn_find.setOnClickListener(findClickListener);



@Override
public boolean onCreateOptionsMenu(Menu menu) 
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;


// An AsyncTask class for accessing the GeoCoding Web Service
private class GeocoderTask extends AsyncTask<String, Void, List<Address>> 

    @Override
    protected List<Address> doInBackground(String... locationName) 
        // Creating an instance of Geocoder class
        Geocoder geocoder = new Geocoder(getBaseContext());
        List<Address> addresses = null;

        try 
            // Getting a maximum of 3 Address that matches the input text
            addresses = geocoder.getFromLocationName(locationName[0], 3);
         catch (IOException e) 
            e.printStackTrace();
        
        return addresses;
    

    @Override
    protected void onPostExecute(List<Address> addresses) 

        if (addresses == null || addresses.size() == 0) 
            Toast.makeText(getBaseContext(), "No Location found",
                    Toast.LENGTH_SHORT).show();
        

        // Clears all the existing markers on the map
        googleMap.clear();

        // Adding Markers on Google Map for each matching address
        for (int i = 0; i < addresses.size(); i++) 

            Address address = (Address) addresses.get(i);

            // Creating an instance of GeoPoint, to display in Google Map
            latLng = new LatLng(address.getLatitude(),
                    address.getLongitude());

            String addressText = String.format(
                    "%s, %s",
                    address.getMaxAddressLineIndex() > 0 ? address
                            .getAddressLine(0) : "", address
                            .getCountryName());

            markerOptions = new MarkerOptions();
            markerOptions.position(latLng);
            markerOptions.title(addressText);

            googleMap.addMarker(markerOptions);

            // Locate the first location
            if (i == 0)
                googleMap.animateCamera(CameraUpdateFactory
                        .newLatLng(latLng));
        
    


【讨论】:

它的工作方式就像您搜索谷歌地图和相关地点以在谷歌地图中放置标记。它的工作喜欢 GecoCoder。谢谢

以上是关于我正在尝试在android中的谷歌地图上搜索附近的地方,例如银行,餐馆,自动取款机的主要内容,如果未能解决你的问题,请参考以下文章

移动相机方法上的谷歌地图空对象引用[关闭]

无法从android中的谷歌地图获取地点数据

在android中的谷歌地图上绘制点

如何在android的谷歌地图V2上添加谷歌素材图标“我的位置”?

如何在 android 的谷歌地图 v2 上用我的图标替换蓝点?

生成与附近餐馆的谷歌地图链接