/*
 * Copyright 2012 - 2015 Anton Tananaev (anton.tananaev@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.traccar.geocode;

import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

import org.traccar.helper.Log;

import javax.json.*;

public class GoogleReverseGeocoder implements ReverseGeocoder {

    private final String url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f";

    @Override
    public String getAddress(AddressFormat format, double latitude, double longitude) {

        try {
            Address address = new Address();
            URLConnection conn = new URL(String.format(url, latitude, longitude)).openConnection();

            JsonObject json = Json.createReader(new InputStreamReader(conn.getInputStream())).readObject();
            JsonObject result = (JsonObject) json.getJsonArray("results").get(0);
            JsonArray components = result.getJsonArray("address_components");

            for (JsonObject component : components.getValuesAs(JsonObject.class)) {

                String value = component.getString("short_name");

                for (JsonString type : component.getJsonArray("types").getValuesAs(JsonString.class)) {
                    if (type.getString().equals("street_number")) {
                        address.setHouse(value);
                        break;
                    } else if (type.getString().equals("route")) {
                        address.setStreet(value);
                        break;
                    } else if (type.getString().equals("locality")) {
                        address.setSettlement(value);
                        break;
                    } else if (type.getString().equals("administrative_area_level_2")) {
                        address.setDistrict(value);
                        break;
                    } else if (type.getString().equals("administrative_area_level_1")) {
                        address.setState(value);
                        break;
                    } else if (type.getString().equals("country")) {
                        address.setCountry(value);
                        break;
                    } else if (type.getString().equals("postal_code")) {
                        address.setPostcode(value);
                        break;
                    }
                }
            }

            return format.format(address);

        } catch(Exception error) {
            Log.warning(error);
        }

        return null;
    }

}

@@ -741,16 +741,128 @@
 ection;%0A
+import javax.json.Json;%0Aimport javax.json.JsonArray;%0Aimport javax.json.JsonObject;%0Aimport javax.json.JsonString;
 %0Aimport 
@@ -890,30 +890,8 @@
 g;%0A%0A
-import javax.json.*;%0A%0A
 publ
@@ -1439,36 +1439,23 @@
 Json
-Object
+Array
  result
+s
  =
- (JsonObject)
  jso
@@ -1479,16 +1479,114 @@
 esults%22)
+;%0A%0A            if (!results.isEmpty()) %7B%0A%0A                JsonObject result = (JsonObject) results
 .get(0);
@@ -1586,16 +1586,20 @@
 get(0);%0A
+    
         
@@ -1673,32 +1673,36 @@
 );%0A%0A            
+    
 for (JsonObject 
@@ -1754,24 +1754,28 @@
 .class)) %7B%0A%0A
+    
             
@@ -1837,32 +1837,36 @@
                 
+    
 for (JsonString 
@@ -1933,24 +1933,28 @@
 g.class)) %7B%0A
+    
             
@@ -2025,32 +2025,36 @@
                 
+    
 address.setHouse
@@ -2054,32 +2054,36 @@
 etHouse(value);%0A
+    
                 
@@ -2109,32 +2109,36 @@
                 
+    
 %7D else if (type.
@@ -2164,24 +2164,28 @@
 %22route%22)) %7B%0A
+    
             
@@ -2238,39 +2238,47 @@
                 
+    
 break;%0A
+    
                 
@@ -2347,32 +2347,36 @@
                 
+    
 address.setSettl
@@ -2381,32 +2381,36 @@
 tlement(value);%0A
+    
                 
@@ -2436,32 +2436,36 @@
                 
+    
 %7D else if (type.
@@ -2533,32 +2533,36 @@
                 
+    
 address.setDistr
@@ -2589,32 +2589,36 @@
                 
+    
 break;%0A         
@@ -2620,32 +2620,36 @@
                 
+   
+ 
 %7D else if (type.
@@ -2717,32 +2717,36 @@
                 
+    
 address.setState
@@ -2770,39 +2770,47 @@
                 
+   
+ 
 break;%0A
+    
                 
@@ -2878,32 +2878,36 @@
                 
+   
+ 
 address.setCount
@@ -2933,32 +2933,36 @@
                 
+    
 break;%0A         
@@ -2964,32 +2964,36 @@
                 
+   
+ 
 %7D else if (type.
@@ -3045,32 +3045,36 @@
                 
+    
 address.setPostc
@@ -3101,39 +3101,69 @@
                 
+   
+ 
 break;%0A
+                        %7D%0A
                 
@@ -3190,23 +3190,12 @@
   %7D%0A
+%0A
    
-         %7D%0A%0A
     
@@ -3198,24 +3198,25 @@
             
+ 
 return forma
@@ -3233,16 +3233,30 @@
 ddress);
+%0A            %7D
 %0A%0A      

Handle empty geocoding response