I have an address name and I want to get an accurate latitude & longitude for it. I know we can get this using Geocoder's getFromLocationName(address,maxresult).
The problem is, the result I get is always null - unlike the result that we get with https://maps.google.com/. This always allows me to get some results, unlike Geocoder.
I also tried another way: "http://maps.google.com/maps/api/geocode/json?address=" + address + "&sensor=false" (Here's a link!) It gives better results than geocoder, but often returns the error (java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer). It's boring.
My question is: How can we get the same latlong result we would get by searching on https://maps.google.com/ from within java code?
additional:where is the api document about using "http://maps.google.com/maps/api/geocode/json?address=" + address + "&sensor=false"
Albert, I think your concern is that you code is not working. Here goes, the code below works for me really well. I think you are missing URIUtil.encodeQuery to convert your string to a URI.
I am using gson library, download it and add it to your path.
To get the class's for your gson parsing, you need to goto jsonschema2pojo. Just fire http://maps.googleapis.com/maps/api/geocode/json?address=Sayaji+Hotel+Near+balewadi+stadium+pune&sensor=true on your browser, get the results and paste it on this site. It will generate your pojo's for you. You may need to also add a annotation.jar.
Trust me, it is easy to get working. Don't get frustrated yet.
try {
URL url = new URL(
"http://maps.googleapis.com/maps/api/geocode/json?address="
+ URIUtil.encodeQuery("Sayaji Hotel, Near balewadi stadium, pune") + "&sensor=true");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output = "", full = "";
while ((output = br.readLine()) != null) {
System.out.println(output);
full += output;
}
PincodeVerify gson = new Gson().fromJson(full, PincodeVerify.class);
response = new IsPincodeSupportedResponse(new PincodeVerifyConcrete(
gson.getResults().get(0).getFormatted_address(),
gson.getResults().get(0).getGeometry().getLocation().getLat(),
gson.getResults().get(0).getGeometry().getLocation().getLng())) ;
try {
String address = response.getAddress();
Double latitude = response.getLatitude(), longitude = response.getLongitude();
if (address == null || address.length() <= 0) {
log.error("Address is null");
}
} catch (NullPointerException e) {
log.error("Address, latitude on longitude is null");
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The Geocode http works, I just fired it, results below
{
"results" : [
{
"address_components" : [
{
"long_name" : "Pune",
"short_name" : "Pune",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Pune",
"short_name" : "Pune",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Maharashtra",
"short_name" : "MH",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Pune, Maharashtra, India",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 18.63469650,
"lng" : 73.98948670
},
"southwest" : {
"lat" : 18.41367390,
"lng" : 73.73989109999999
}
},
"location" : {
"lat" : 18.52043030,
"lng" : 73.85674370
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 18.63469650,
"lng" : 73.98948670
},
"southwest" : {
"lat" : 18.41367390,
"lng" : 73.73989109999999
}
}
},
"types" : [ "locality", "political" ]
}
],
"status" : "OK"
}
Edit
On 'answers do not contain enough detail`
From all the research you are expecting that google map have a reference to every combination of locality, area, city. But the fact remains that google map contains geo and reverse-geo in its own context. You cannot expect it to have a combination like Sayaji Hotel, Near balewadi stadium, pune. Web google maps will locate it for you since it uses a more extensive Search rich google backend. The google api's only reverse geo address received from their own api's. To me it seems like a reasonable way to work, considering how complex our Indian address system is, 2nd cross road can be miles away from 1st Cross road :)
Hope this helps you:
public static GeoPoint getGeoPointFromAddress(String locationAddress) {
GeoPoint locationPoint = null;
String locationAddres = locationAddress.replaceAll(" ", "%20");
String str = "http://maps.googleapis.com/maps/api/geocode/json?address="
+ locationAddres + "&sensor=true";
String ss = readWebService(str);
JSONObject json;
try {
String lat, lon;
json = new JSONObject(ss);
JSONObject geoMetryObject = new JSONObject();
JSONObject locations = new JSONObject();
JSONArray jarr = json.getJSONArray("results");
int i;
for (i = 0; i < jarr.length(); i++) {
json = jarr.getJSONObject(i);
geoMetryObject = json.getJSONObject("geometry");
locations = geoMetryObject.getJSONObject("location");
lat = locations.getString("lat");
lon = locations.getString("lng");
locationPoint = Utils.getGeoPoint(Double.parseDouble(lat),
Double.parseDouble(lon));
}
} catch (Exception e) {
e.printStackTrace();
}
return locationPoint;
}
I use, in order:
- Google Geocoding API v3 (in few cases there's a problem described here)
- Geocoder (in some cases there's a problem described here).
If I don't receive results from Google Geocoding API I use the Geocoder.
As far as I noticed Google Maps is using the Google Places API for auto complete and then gets the Details for the Location from which you can get the coordinates.
https://developers.google.com/places/documentation/
https://developers.google.com/places/training/
This method should will give you the expected results.
String locationAddres = anyLocationSpec.replaceAll(" ", "%20");
URL url = new URL("https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address="+locationAddres+"&language=en&key="YourKey");
try(InputStream is = url.openStream(); JsonReader rdr = Json.createReader(is)) {
JsonObject obj = rdr.readObject();
JsonArray results = obj.getJsonArray("results");
JsonObject geoMetryObject, locations;
for (JsonObject result : results.getValuesAs(JsonObject.class)) {
geoMetryObject=result.getJsonObject("geometry");
locations=geoMetryObject.getJsonObject("location");
log.info("Using Gerocode call - lat : lng value for "+ anyLocationSpec +" is - "+locations.get("lat")+" : "+locations.get("lng"));
latLng = locations.get("lat").toString() + "," +locations.get("lng").toString();
}
}
Related
I have an String called inputJson that contains
{"listPruebas": [
{
"nombrePrueba" : "pruebaA",
"id" : 1,
"tipoPrueba" : "PRUEBABASE1",
"elementoBase" : "tipoA",
"listaMarca": [
{
"elemento": "elemento1 ",
"tipo": "ABC",
"cadena": "SFSG34235WF32"
},
{
"elemento":"elemento2",
"tipo":"DEF",
"cadena":"DJRT64353GSDG"
},
{
"elemento" : "elemento3",
"formato ":"JPG"
}
]},
{
"nombrePrueba" : "pruebaB",
"id" : 2,
"tipoPrueba" : "PRUEBABASE2",
"elementoBase" : "imagenPrueba",
"listaMarca2": [
{
"elemento" : "imagen",
"tipo": "tipo5",
"cadena": "iVBORw0KGgoAAAANSUhEUgAAAgAAAA"
}
]
}
],
"listaBuscar":
[
{
"tipoBusqueda":"busqueda1",
"id" : 1,
"operacion" : "operacion1",
"valor" : "12"
},
{
"tipoBusqueda":"binario",
"id" : 2,
"operacion" : "operacion2",
"valor" : "13"
},
{
"tipoFiltro":"numerico",
"id" : 31,
"operacion" : "MENOR_QUE",
"valor" : "1980",
"intervalo" : 1
}
]
}
and I converted the String to JSONObject of this way
JSONObject object = new JSONObject(inputJson);
and I got this
jsonObject::{"listaBuscar":[{"valor":"12","id":1,"operacion":"operacion1","tipoBusqueda":"busqueda1"},{"valor":"13","id":2,"operacion":"operacion2","tipoBusqueda":"binario"},{"tipoFiltro":"numerico","intervalo":1,"valor":"1980","id":31,"operacion":"MENOR_QUE"}],"listPruebas":[{"listaMarca":[{"tipo":"ABC","elemento":"elemento1","cadena":"SFSG34235WF32"},{"tipo":"DEF","elemento":"elemento2","cadena":"DJRT64353GSDG"},{"elemento":"elemento3","formato":"JPG"}],"elementoBase":"tipoA","tipoPrueba":"PRUEBABASE1","nombrePrueba":"pruebaA","id":1},{"elementoBase":"imagenPrueba","tipoPrueba":"PRUEBABASE2","listaMarca2":[{"tipo":"tipo5","elemento":"imagen","cadena":"iVBORw0KGgoAAAANSUhEUgAAAgAAAA"}],"nombrePrueba":"pruebaB","id":2}]}
and now I need to extract information but I dont know how to do, for example I try this
object.getString("elemento1");
but I got this error
Caused by: org.json.JONException: JSONObject["elemento1"] not found
help me please
You can't get a nest JSON object from the top level. It's like a treemap. You need to convert it into a java object or get it level by level.
check this post, a lot of ways.
You json contains two json arrays, fetch them as -
JSONArray listaBuscArray = jsonObj.getJSONArray("listaBuscar");
JSONArray listPruebasArray = jsonObj.getJSONArray("listPruebas");
Now you can process and use them as -
for(int i=0; i<listaBuscArray.length; i++){
JSONObject obj = listaBuscArray.getJSONObject(i);
.... your logic
}
I am having some trouble trying to figure out how to parse a line in a json file so that it only returns part of the line as a string. I will illustrate below:
public String GetDistance(String origin, String destination) throws MalformedURLException, IOException {
//URL url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins" + origin + ",UK+destination=" + destination + ",UK&key=mykey");
URL url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=Cornwall,UK&destinations=London,UK&key=mykey");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
String line, outputString = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null) {
if (line.contains("distance")) {
outputString = reader.readLine().trim();
return outputString;
}
}
return outputString;
}
What this function does is create a json file in my browser using Google Maps API:
{
"destination_addresses" : [ "London, UK" ],
"origin_addresses" : [ "Cornwall, UK" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "284 mi",
"value" : 456443
},
"duration" : {
"text" : "4 hours 52 mins",
"value" : 17530
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
Currently the "outputString" returns the line: "text" : "284 mi". However, the desired output is to just return the miles, "284".
I know this is most likely a re post, however I have been searching around for a solution to this and have been unsuccessful in implementing something that works.
Any help on this would be greatly appreciated, Cheers.
You can have 2 solutions:
Parse the JSON and treat it as an object and then just return the String you're looking for.
Split the line as follows:
outputString = reader.readLine().trim();
That line above returns "text" : "284 mi"
Then you need to split the line by ::
outputString.split(":")
That should create an array with 2 Strings: "text" and "284 mi"
Then take the second String and split it by a space and take the first String:
outputString.split("\\s")
Now you have: "284
Then just return it from subindex 1 till the end, see docs:
outputString.substring(1)
And then just put it all together:
return outputString.split(":")[1].split("\\s")[0].substring(1)
I haven't tried above code but it should work.
BTW follow Java Naming Conventions
firstWordLowerCaseVariable
firstWordLowerCaseMethod()
FirstWordUpperCaseClass
ALL_WORDS_UPPER_CASE_CONSTANT
And use them consistently
i want to create gmaps on my website.
I found, how to get coordinates.
{
"results" : [
{
// body
"formatted_address" : "PuĊawska, Piaseczno, Polska",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 52.0979041,
"lng" : 21.0293984
},
"southwest" : {
"lat" : 52.0749265,
"lng" : 21.0145743
}
},
"location" : {
"lat" : 52.0860667,
"lng" : 21.0205308
},
"location_type" : "GEOMETRIC_CENTER",
"viewport" : {
"northeast" : {
"lat" : 52.0979041,
"lng" : 21.0293984
},
"southwest" : {
"lat" : 52.0749265,
"lng" : 21.0145743
}
}
},
"partial_match" : true,
"types" : [ "route" ]
}
],
"status" : "OK"
}
I want to get:
"location" : {
"lat" : 52.0860667,
"lng" : 21.0205308
},
From this Json.
I decided to user json-simple
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
My code is:
String coordinates = //JSON from google
JSONObject json = (JSONObject)new JSONParser().parse(coordinates);
And i can get the first children: "results"
String json2 = json.get("results").toString();
json2 display correct body of "results"
But i cannot get "location" children.
How to do it ?
Thanks
I think you need to cast the call to json.get("results") to a JSONArray.
I.e.
String coordinates = //JSON from google
JSONObject json = (JSONObject)new JSONParser().parse(coordinates);
JSONArray results = (JSONArray) json.get("results");
JSONObject resultObject = (JSONObject) results.get(0);
JSONObject location = (JSONObject) resultObject.get("location");
String lat = location.get("lat").toString();
String lng = location.get("lng").toString()
The trick is to look at what type the part of the json you're deserializing is and cast it to the appropriate type.
about this link
com.google.gson.JsonParser#parse(java.lang.String) is now deprecated
so use com.google.gson.JsonParser#parseString, it works pretty well
Kotlin Example:
val mJsonObject = JsonParser.parseString(myStringJsonbject).asJsonObject
Java Example:
JsonObject mJsonObject = JsonParser.parseString(myStringJsonbject).getAsJsonObject();
Hello guys i'm reading a page that contain JSON objects with JAVA (Android)
Here is what the page contains :
{
"destination_addresses" : [ "Safi, Maroc" ],
"origin_addresses" : [ "Avenue Hassan II, Safi, Maroc" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "1,0 km",
"value" : 966
},
"duration" : {
"text" : "2 minutes",
"value" : 129
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
I know how to read from the page doing this
JSONObject jArray = new JSONObject(result);
String elements = jArray.getString("rows");
the elements string contain that :
[{"elements" : [{"distance" : {"text" : "1,0 km","value" : 966},"duration" : {"text" : "2 minutes","value" : 129},"status" : "OK"}]}]
But im trying to get the distance value which is "966"
Thx guys
So you are trying to access an entry from the array. See Tutorials or examples. This is basic stuff:
http://www.mkyong.com/java/json-simple-example-read-and-write-json/
You need to actually use a JSONArray (which subclasses JSONObject)
You might want to take a look at this link:
How to parse JSON in Android
But for your particular problem you want to call something like:
int value = jArray.getJSONObject("rows").getJSONObject("elements").getJSONArray("distance").getInteger("value");
Try this..
JSONObject jObj = new JSONObject(result);
JSONArray rows = jObj.getJSONArray("rows");
for(int i = 0; i < rows.length; i++){
JSONObject obj = rows.getJSONObject(i);
JSONArray elements = jObj.getJSONArray("elements");
for(int j = 0; j < elements.length; j++){
JSONObject Jobj = elements.getJSONObject(j);
JSONObject distance = Jobj.getJSONObject("distance");
int distance_value = distance.getInteger("value");
JSONObject duration = Jobj.getJSONObject("duration");
int duration_value = duration.getInteger("value");
}
}
I'm trying to parse this stock info at:
http://www.google.com/finance/info?client=ig&q=csco
that's in JSON format to a map, essentially following this tutorial I saw using the quick-json jar but it keeps giving me an exception and I can't figure out why. Here's the code, any help is greatly appreciated
Tutorial link: https://code.google.com/p/quick-json/
public static void main(String args[]) throws IOException
{
String value="";
URL uri = new URL("http://www.google.com/finance/info?client=ig&q=csco");
BufferedReader input = new BufferedReader(new InputStreamReader(uri.openStream(), "UTF-8"));
while(input.readLine()!=null)
{
value+=input.readLine();
}
JsonParserFactory factory = JsonParserFactory.getInstance();
JSONParser parse = factory.newJsonParser();
Map jsonData =parse.parseJson(value);
System.out.println((String)jsonData.get("e"));
}
Here's the exception I get:
Exception in thread "main" com.json.exceptions.JSONParsingException: #Key-Heirarchy::root[0]/ #Key:: COMMA or ] is expected. but found :...#Position::5
at com.json.utils.JSONUtility.handleFailure(JSONUtility.java:124)
at com.json.parsers.JSONParser.stringLiteralTemplate(JSONParser.java:574)
at com.json.parsers.JSONParser.nonValidatingValueTemplate(JSONParser.java:698)
at com.json.parsers.JSONParser.jsonArrayTemplate(JSONParser.java:454)
at com.json.parsers.JSONParser.parseJson(JSONParser.java:170)
at parser.Scratch.main(Scratch.java:27)
EDIT: I also tried Map jsonData =parse.parseJson(value.substring(3) to start at [ but it still gives me an error
In addition to removing the leading // fix your loop as well. Change
while(input.readLine()!=null) // skipping odd lines
{
value+=input.readLine(); // reading even lines
}
to
String line = null;
while((line = input.readLine()) !=null)
{
value +=line;
}
or, better use a StringBuilder like
String line = null;
StringBuilder json = new StringBuilder();
while((line = input.readLine()) !=null)
{
json.append(line);
}
value = json.substring(3); // removes the leading "// "
EDIT:
I'm not familiar with your JSON parser. With the org.json. Java parser you could do it this way.
JSONArray jsonRoot = new JSONArray(value);
JSONObject quote = jsonRoot.get(0);
System.out.println ("e = " + quote.getString("e"));
But, as a workaround you could strip the [] from StringBuilder as
// removes the leading "// [" and trailing "]"
value = json.substring(4, json.length() - 1);
This json is not a valid, have two "//".
Use http://jsonlint.com/ to validate this
The response from that URL starts with //, which isn't valid JSON:
// [ { "id": "99624" ,"t" : "CSCO" ,"e" : "NASDAQ" ,"l" : "24.00" ,"l_cur" : "24.00" ,"s": "2" ,"ltt":"4:00PM EDT" ,"lt" : "Jun 25, 4:00PM EDT" ,"c" : "-0.05" ,"cp" : "-0.21" ,"ccol" : "chr" ,"el": "24.00" ,"el_cur": "24.00" ,"elt" : "Jun 25, 5:54PM EDT" ,"ec" : "0.00" ,"ecp" : "0.00" ,"eccol" : "chb" ,"div" : "0.17" ,"yld" : "2.83" } ]
According to this and this, the Google Finance API is deprecated anyway, so you may want to find something else.
Following blog has enough number of very good examples on quick-json parser
It has got other competitive parsers examples as well
http://codesnippets4all.com/html/parsers/json/quick-json.htm
Add this to your code:
String line = null;
while((line = input.readLine()) !=null)
{
value += line;
}
value = value.replace("// ", "");
You need to replace the // at the beginning to "clean" the JSON before you can parse it.
It seems you are using old quick-json parser version. Use the latest version for parsing
quick-json-1.0.2.3.jar
I could see that the json is coming as follows,
// [
{
"id": "99624"
,"t" : "CSCO"
,"e" : "NASDAQ"
,"l" : "25.41"
,"l_cur" : "25.41"
,"s": "2"
,"ltt":"3:59PM EDT"
,"lt" : "Jul 10, 3:59PM EDT"
,"c" : "+0.25"
,"cp" : "1.01"
,"ccol" : "chg"
,"el": "25.55"
,"el_cur": "25.55"
,"elt" : "Jul 10, 7:07PM EDT"
,"ec" : "+0.14"
,"ecp" : "0.55"
,"eccol" : "chg"
,"div" : "0.17"
,"yld" : "2.68"
}
]
This is not valid JSON, it should not be preceded by //
// [
remove // and just use from [ till end of the json string
i was able to parse successfully the below json string without //
[
{
"id": "99624"
,"t" : "CSCO"
,"e" : "NASDAQ"
,"l" : "25.41"
,"l_cur" : "25.41"
,"s": "2"
,"ltt":"3:59PM EDT"
,"lt" : "Jul 10, 3:59PM EDT"
,"c" : "+0.25"
,"cp" : "1.01"
,"ccol" : "chg"
,"el": "25.55"
,"el_cur": "25.55"
,"elt" : "Jul 10, 7:07PM EDT"
,"ec" : "+0.14"
,"ecp" : "0.55"
,"eccol" : "chg"
,"div" : "0.17"
,"yld" : "2.68"
}
]
Below is the output i've got with version quick-json-1.0.2.3.jar
{root=[{e=NASDAQ, c=+0.25, div=0.17, l=25.41, lt=Jul 10, 3:59PM EDT, ec=+0.14, ltt=3:59PM EDT, elt=Jul 10, 7:07PM EDT, id=99624, yld=2.68, el_cur=25.55, t=CSCO, cp=1.01, s=2, el=25.55, l_cur=25.41, eccol=chg, ccol=chg, ecp=0.55}]}