我正在尝试在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_JSON
ParserTask
中使用的类:
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,type
和key.
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的谷歌地图V2上添加谷歌素材图标“我的位置”?