Hi i want to get place details with placeID and add marker in android maps activity using kotlin. i have done it with latlng but am not getting with placeID . can any pleease help.
my code with latlng .
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
val mdis= LatLng(1.301440, 103.847980)
mMap.addMarker(MarkerOptions().position(mdis).title("MDIS").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)))
mMap.moveCamera(CameraUpdateFactory.newLatLng(mdis))
mMap.animateCamera(CameraUpdateFactory.zoomIn())
mMap.animateCamera(CameraUpdateFactory.zoomTo(15F),2000,null)
mMap.uiSettings.isZoomControlsEnabled=true
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mMap.isMyLocationEnabled = true
}
else {//condition for Marshmello and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), MY_PERMISSION_FINE_LOCATION)
}
}
mMap.setOnMarkerClickListener(this)
}
Tried this and am getting error at placesClient.fetchPlace(request).addOnSuccessListener(response) ->{
Error says Type mismatch Required: OnSuccessListener
found : FetchplaceResponse
This is my updated code :
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
var mdisplaceId = "ChIJRwCirzca2jERhd68E52R_2Q"
//val placesClient = Places.createClient(this)
var placeFields : List<Place.Field>
placeFields = Arrays.asList(Place.Field.ID , Place.Field.NAME)
var request : FetchPlaceRequest
request = FetchPlaceRequest.newInstance(mdisplaceId, placeFields)
lateinit var response : FetchPlaceResponse
lateinit var placesClient : PlacesClient
placesClient.fetchPlace(request).addOnSuccessListener(response) ->{ //error at this line near response
var place : Place
place = response.getPlace()
})
}
Use Geocoding api,
https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=YOUR_API_KEY
which will return the following json response,
{
"results" : [
{
"address_components" : [
{
"long_name" : "277",
"short_name" : "277",
"types" : [ "street_number" ]
},
{
"long_name" : "Bedford Avenue",
"short_name" : "Bedford Ave",
"types" : [ "route" ]
},
{
"long_name" : "Williamsburg",
"short_name" : "Williamsburg",
"types" : [ "neighborhood", "political" ]
},
{
"long_name" : "Brooklyn",
"short_name" : "Brooklyn",
"types" : [ "political", "sublocality", "sublocality_level_1" ]
},
{
"long_name" : "Kings County",
"short_name" : "Kings County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "New York",
"short_name" : "NY",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "11211",
"short_name" : "11211",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "277 Bedford Ave, Brooklyn, NY 11211, USA",
"geometry" : {
"location" : {
"lat" : 40.7142205,
"lng" : -73.9612903
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 40.71556948029149,
"lng" : -73.95994131970849
},
"southwest" : {
"lat" : 40.7128715197085,
"lng" : -73.9626392802915
}
}
},
"place_id" : "ChIJd8BlQ2BZwokRAFUEcm_qrcA",
"types" : [ "street_address" ]
}
],
"status" : "OK"
}
Get the lat long from geometry object and add marker on the google maps.
Consider below JSON response of google map gecoding response.
It consists of an array of address_components with five elements.
Usually developer use its first item (item with index 0) to find address elements such ac route and locality and formatted address. But this is not the best alternative. For example in this case, 2nd item is more descriptive address than others. Sometime there are same address with different localities in same response.
How can I choose the better one (E.g. Google Map API in android selects one among available item but it is not always item with index 0, but it select among alternatives, I want to know how it will do that and select the best match)?
Besides, I was wondering to iterate through all elements of different address_components to extract and bring together finer pieces of information but the problem is information for same type of elements like locality have different information in different address_components which result in inconsistency of address when elements of information gathered from different address_component items.
As an example, In below sample we have two values شهر جدید اندیشه and Karaj in different locality elements which are two different city labels (in the same neighborhood).
https://maps.googleapis.com/maps/api/geocode/json?latlng=35.7163931455472,51.01335000246763&key=xxxxx&language=fa
{
"results" : [
{
"address_components" : [
{
"long_name" : "Unnamed Road",
"short_name" : "Unnamed Road",
"types" : [ "route" ]
},
{
"long_name" : "Karaj",
"short_name" : "Karaj",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Shahriar County",
"short_name" : "Shahriar County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Tehran Province",
"short_name" : "Tehran Province",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "ایران",
"short_name" : "IR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Tehran Province, Karaj, Unnamed Road, ایران",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 35.7221382,
"lng" : 51.0148178
},
"southwest" : {
"lat" : 35.716435,
"lng" : 51.0095103
}
},
"location" : {
"lat" : 35.719286,
"lng" : 51.012165
},
"location_type" : "GEOMETRIC_CENTER",
"viewport" : {
"northeast" : {
"lat" : 35.7221382,
"lng" : 51.0148178
},
"southwest" : {
"lat" : 35.716435,
"lng" : 51.0095103
}
}
},
"place_id" : "ChIJmf7_zEyTjT8RkM8-nK6dTm0",
"types" : [ "route" ]
},
{
"address_components" : [
{
"long_name" : "فاز ۶ شهر جدید اندیشه",
"short_name" : "فاز ۶ شهر جدید اندیشه",
"types" : [ "political", "sublocality", "sublocality_level_1" ]
},
{
"long_name" : "شهر جدید اندیشه",
"short_name" : "شهر جدید اندیشه",
"types" : [ "locality", "political" ]
},
{
"long_name" : "شهرستان شهریار",
"short_name" : "شهرستان شهریار",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "استان تهران",
"short_name" : "استان تهران",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "ایران",
"short_name" : "IR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "فاز ۶ شهر جدید اندیشه، شهر جدید اندیشه، استان تهران، ایران",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 35.7389537,
"lng" : 51.0349971
},
"southwest" : {
"lat" : 35.7039031,
"lng" : 51.0044146
}
},
"location" : {
"lat" : 35.7210753,
"lng" : 51.014934
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 35.7389537,
"lng" : 51.0349971
},
"southwest" : {
"lat" : 35.7039031,
"lng" : 51.0044146
}
}
},
"place_id" : "ChIJiYlwJLHsjT8RruE39U9NMoQ",
"types" : [ "political", "sublocality", "sublocality_level_1" ]
},
{
"address_components" : [
{
"long_name" : "شهر جدید اندیشه",
"short_name" : "شهر جدید اندیشه",
"types" : [ "locality", "political" ]
},
{
"long_name" : "شهرستان شهریار",
"short_name" : "شهرستان شهریار",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "استان تهران",
"short_name" : "استان تهران",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "ایران",
"short_name" : "IR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "شهر جدید اندیشه، استان تهران، ایران",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 35.7388144,
"lng" : 51.04460479999999
},
"southwest" : {
"lat" : 35.6838973,
"lng" : 50.9894371
}
},
"location" : {
"lat" : 35.7078282,
"lng" : 51.0227587
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 35.7388144,
"lng" : 51.04460479999999
},
"southwest" : {
"lat" : 35.6838973,
"lng" : 50.9894371
}
}
},
"place_id" : "ChIJIQwwRcnsjT8RnTJfLJ3QUAg",
"types" : [ "locality", "political" ]
},
{
"address_components" : [
{
"long_name" : "شهرستان شهریار",
"short_name" : "شهرستان شهریار",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "استان تهران",
"short_name" : "استان تهران",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "ایران",
"short_name" : "IR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "شهرستان شهریار، استان تهران، ایران",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 35.7389885,
"lng" : 51.23044970000001
},
"southwest" : {
"lat" : 35.5333437,
"lng" : 50.8859253
}
},
"location" : {
"lat" : 35.6096201,
"lng" : 51.03319330000001
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 35.7389885,
"lng" : 51.23044970000001
},
"southwest" : {
"lat" : 35.5333437,
"lng" : 50.8859253
}
}
},
"place_id" : "ChIJQ6KQjY7xjT8RoYD9gJh8_CY",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"address_components" : [
{
"long_name" : "استان تهران",
"short_name" : "استان تهران",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "ایران",
"short_name" : "IR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "استان تهران، ایران",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 36.07789210000001,
"lng" : 53.216228
},
"southwest" : {
"lat" : 34.909543,
"lng" : 50.3186971
}
},
"location" : {
"lat" : 35.7248416,
"lng" : 51.381653
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 36.07789210000001,
"lng" : 53.216228
},
"southwest" : {
"lat" : 34.909543,
"lng" : 50.3186971
}
}
},
"place_id" : "ChIJf5Us9YQBjj8R0OohvHQms1U",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"address_components" : [
{
"long_name" : "ایران",
"short_name" : "IR",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "ایران",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 39.782056,
"lng" : 63.3333366
},
"southwest" : {
"lat" : 24.8066999,
"lng" : 44.0326949
}
},
"location" : {
"lat" : 32.427908,
"lng" : 53.688046
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 39.782056,
"lng" : 63.3333366
},
"southwest" : {
"lat" : 24.8066999,
"lng" : 44.0326949
}
}
},
"place_id" : "ChIJ8R1rwS7s9z4RzvpRntOVsEA",
"types" : [ "country", "political" ]
}
],
"status" : "OK"
}
It looks like there are two different questions in one, so the scope is a bit broad. I will try to address your doubts.
First, you are using the reverse geocoding request to resolve coordinate 35.7163931455472,51.01335000246763 into street address. Note that reverse geocoding is designed to resolve the given coordinate to the nearest available address. Also the service will suggest different types of results in addition to street address: route, sublocality, locality, administrative areas, country.
Sometimes if there are no street addresses close to the given point (approx. within 50 meters from the point), the result of type street address is not present in the response. In your example the result of type street address is not available, so the response contains different types of results starting from the route level. Have a look at my screenshot that represents first three items from your response.
As you can see the first item has a type route, the second item has a type sublocality and the third one has a type locality.
It is difficult to say what is the "best" criteria to chose the address. You can see that the route item is the closest one, but unfortunately this road is unnamed, so you qualify it as not good enough. Technically this is the closest item, so the service supposes this is the best match. I would suggest checking the type of results, if the item 0 has a type street_address is should be good enough to go, if the item 0 has a type route, check if the road has a name, if this is unnamed road check the item 1 that might be more detailed.
Anyway the unnamed road is the data issue and you can report it to the Google data team following the help center:
https://support.google.com/maps/answer/3094088
Second, if I understand correctly you noticed that item 0 and item 1 have different value of locality address component, although both of them (marker 1 and marker 2 in my screenshot) seem to belong to the Andisheh New Town. The route (place ID ChIJmf7_zEyTjT8RkM8-nK6dTm0) is reported as the part of the Karaj locality. I can see the boundaries of Karaj on Google Maps as in the following screenshot
https://www.google.com/maps/place/Karaj,+Alborz+Province,+Iran/#35.7700272,50.95899,12.41z/data=!4m5!3m4!1s0x3f8dbf95ef45f011:0x722a04e54eba9bcd!8m2!3d35.8400188!4d50.9390906
And I can see the boundaries of Andisheh New Town as shown in the following screenshot
https://www.google.com/maps/place/Andisheh+New+Town,+Tehran+Province,+Iran/#35.6998795,51.0216598,14.08z/data=!4m5!3m4!1s0x3f8decc945300c21:0x850d09d2c5f329d!8m2!3d35.7078282!4d51.0227587
Please note that the route from your response is clearly situated inside the Andisheh New Town polygon, so at this point it looks like we are facing a data issue as well. The place ID ChIJmf7_zEyTjT8RkM8-nK6dTm0 should have locality component of Andisheh New Town, not the Karaj.
Feel free to send feedback to Google using this page:
https://www.google.com/maps/place/Tehran+Province,+Karaj,+Unnamed+Road,+Iran/#35.719286,51.0077876,17z/data=!3m1!4b1!4m5!3m4!1s0x3f8d934cccfffe99:0x6d4e9dae9c3ecf90!8m2!3d35.719286!4d51.012165!10m2!1e3!2e3
If you would like to play with reverse geocoding, please use Geocoder tool:
https://google-developers.appspot.com/maps/documentation/utils/geocoder/#q%3D35.716393%252C51.01335
I hope my answer clarifies your doubts!
I find that Place class from Android Library for Google Places API misses a lot of data which is available in Web-Service API.
Android class:
https://developers.google.com/android/reference/com/google/android/gms/location/places/Place
Web-Service reply:
https://developers.google.com/places/web-service/details?hl=en
For example, class definition has nothing about Reviews or Opening Hours. Why it is so? Is it possible to fix it without converting all the app to Web-Service API calls and json-parsing? Perhaps there is an ability to convert Place object to its raw JSON-form to find some additional data?
Places api in android only returns a few details like place name, latitude, longitude etc. if you want more details you have to call webservice api . This is the URl
https://maps.googleapis.com/maps/api/place/details/json?key={API_KEY}&placeid={PLACE_ID}
Here PLACE_ID will get from Place Object in Android Places Api
Sample output:
{
"html_attributions" : [],
"result" : {
"address_components" : [
{
"long_name" : "7167",
"short_name" : "7167",
"types" : [ "street_number" ]
},
{
"long_name" : "Sunset Boulevard",
"short_name" : "Sunset Blvd",
"types" : [ "route" ]
},
{
"long_name" : "Central LA",
"short_name" : "Central LA",
"types" : [ "neighborhood", "political" ]
},
{
"long_name" : "Los Angeles",
"short_name" : "Los Angeles",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Los Angeles County",
"short_name" : "Los Angeles County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "California",
"short_name" : "CA",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "90046",
"short_name" : "90046",
"types" : [ "postal_code" ]
}
],
"adr_address" : "\u003cspan class=\"street-address\"\u003e7167 Sunset Blvd\u003c/span\u003e, \u003cspan class=\"locality\"\u003eLos Angeles\u003c/span\u003e, \u003cspan class=\"region\"\u003eCA\u003c/span\u003e \u003cspan class=\"postal-code\"\u003e90046\u003c/span\u003e, \u003cspan class=\"country-name\"\u003eUSA\u003c/span\u003e",
"formatted_address" : "7167 Sunset Blvd, Los Angeles, CA 90046, USA",
"geometry" : {
"location" : {
"lat" : 34.098341,
"lng" : -118.346263
},
"viewport" : {
"northeast" : {
"lat" : 34.0995122302915,
"lng" : -118.3449154697085
},
"southwest" : {
"lat" : 34.0968142697085,
"lng" : -118.3476134302915
}
}
},
"icon" : "https://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png",
"id" : "7143e0743707f66cfa1cda945779f18e8350060e",
"name" : "7167 Sunset Blvd",
"place_id" : "ChIJn_0bqti-woARRtpNvG7kuq4",
"reference" : "CmRbAAAAuU6CDhPuLqrS9F4XCZIV61wveIeU44RMua7FSCZHtwJeC58_OJksQvLI9Nudb9-N8RhfJDUECkxvdB-llxe6WIqrkDQMBs2vz3mBky0DH70jIcFS7f0_7yivdsxmmLzaEhAtwgzDs0va2soGuFyzuNTGGhR-xVrIvyeZwY0OGDmEp3FJmrbbeQ",
"scope" : "GOOGLE",
"types" : [ "street_address" ],
"url" : "https://maps.google.com/?q=7167+Sunset+Blvd,+Los+Angeles,+CA+90046,+USA&ftid=0x80c2bed8aa1bfd9f:0xaebae46ebc4dda46",
"utc_offset" : -420,
"vicinity" : "Los Angeles"
},
"status" : "OK"
}
Sample JSON Parsing in android
String postalCode="";
String city="";
String state="";
String address="";
JSONObject jsonObj=new JSONObject(rs);
JSONArray addressComponents = jsonObj.getJSONObject("result").getJSONArray("address_components");
for(int i = 0; i < addressComponents.length(); i++) {
JSONArray typesArray = addressComponents.getJSONObject(i).getJSONArray("types");
for (int j = 0; j < typesArray.length(); j++) {
if (typesArray.get(j).toString().equalsIgnoreCase("postal_code")) {
postalCode = addressComponents.getJSONObject(i).getString("long_name");
}else if (typesArray.get(j).toString().equalsIgnoreCase("locality")) {
city = addressComponents.getJSONObject(i).getString("long_name");
}else if (typesArray.get(j).toString().equalsIgnoreCase("administrative_area_level_1")) {
state = addressComponents.getJSONObject(i).getString("long_name");
}else {
String types=typesArray.get(j).toString();
if(types.equalsIgnoreCase("street_number")
||types.equalsIgnoreCase("route")
||types.equalsIgnoreCase("neighborhood")
||types.equalsIgnoreCase("sublocality_level_1")
)
address+=addressComponents.getJSONObject(i).getString("long_name")+", ";
}
}
}
I have to store longitude and latitude of all cities of a country in android application
when user will select a city i have to return the longitude and latitude of selected city.
what will be the most efficient way to do this?
or is there any resources where i enter a country and it will show all cities with their longitude and latitude..?
You can use Google Geocoding API : https://developers.google.com/maps/documentation/geocoding/
For example :
https://maps.googleapis.com/maps/api/geocode/json?address=Berlin&sensor=true
And parse output using GSON
{
"results" : [
{
"address_components" : [
{
"long_name" : "Berlin",
"short_name" : "Berlin",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Berlin",
"short_name" : "Berlin",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "Niemcy",
"short_name" : "DE",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Berlin, Niemcy",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 52.6754542,
"lng" : 13.7611176
},
"southwest" : {
"lat" : 52.33962959999999,
"lng" : 13.0911663
}
},
"location" : {
"lat" : 52.52000659999999,
"lng" : 13.404954
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 52.6754542,
"lng" : 13.7611176
},
"southwest" : {
"lat" : 52.33962959999999,
"lng" : 13.0911663
}
}
},
"types" : [ "locality", "political" ]
}
],
"status" : "OK"
}
I am working on an android app that makes a request to google places (details) and gets a json object in return. Here is the object https://developers.google.com/places/documentation/details#PlaceDetailsResponses
`{
"html_attributions" : [],
"result" : {
"address_components" : [
{
"long_name" : "48",
"short_name" : "48",
"types" : [ "street_number" ]
},
{
"long_name" : "Pirrama Road",
"short_name" : "Pirrama Road",
"types" : [ "route" ]
},
{
"long_name" : "Pyrmont",
"short_name" : "Pyrmont",
"types" : [ "locality", "political" ]
},
{
"long_name" : "NSW",
"short_name" : "NSW",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "AU",
"short_name" : "AU",
"types" : [ "country", "political" ]
},
{
"long_name" : "2009",
"short_name" : "2009",
"types" : [ "postal_code" ]
}
],
"events" : [
{
"event_id" : "9lJ_jK1GfhX",
"start_time" : 1293865200,
"summary" : "<p>A visit from author John Doe, who will read from his latest book.</p>
<p>A limited number of signed copies will be available.</p>",
"url" : "http://www.example.com/john_doe_visit.html"
}
], ETC`
How can I get a specific detail from that json. If I try json.getJSONArray("result") it is telling me json is not from that type or if I try json.getString("results") it says no value for results. So how could I extract the information for example for short_name, etc?
Thanks in advance
You should try like
json.getJSONObject("result");
How to get short_name
JSONObject json=new JSONObject("json");
JSONObject result=json.getJSONObject("result");
JSONArray array=result.getJSONArray("address_components");
for(int i=0;i<array.length();i++)
{
JSONObject obj = array.getJSONObject(i);
String short_name=obj.getString("short_name");
System.out.println("Short Name:"+short_name);
}