/*
* Copyright 2012 the original author or authors.
*
* 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 com.github.carlomicieli.nerdmovies.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import static java.net.URLEncoder.encode;
/**
* A location service that using Google geocoding API return the location coordinates.
*
* @author Carlo Micieli
*/
@Service("locationService")
public class LocationService {
public static final String STATUS_OK = "OK";
public static final String STATUS_ZERO_RESULTS = "ZERO_RESULTS";
public static final String STATUS_OVER_QUERY_LIMIT = "OVER_QUERY_LIMIT";
public static final String STATUS_REQUEST_DENIED = "REQUEST_DENIED";
public static final String STATUS_INVALID_REQUEST = "INVALID_REQUEST";
// google maps api endpoint
public static final String GOOGLE_MAPS_API_ENDPOINT = "http://maps.googleapis.com/maps/api/geocode/json?address={address}&sensor=false";
private RestTemplate restTemplate;
@Autowired
public LocationService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
private String buildMessage(String status) {
if (status == STATUS_ZERO_RESULTS)
return "No result is found";
else if (status == STATUS_OVER_QUERY_LIMIT)
return "You are over your quota";
else if (status == STATUS_REQUEST_DENIED)
return "Your request was denied";
else if (status == STATUS_INVALID_REQUEST)
return "The query is missing";
return "";
}
/**
* Perform a geocode request to find the coordinates for a valid address.
*
* @param address the address that you want to geocode.
* @return the coordinates.
* @throws RestClientException
* @throws UnsupportedEncodingException
*/
public double[] findLocation(String address) throws RestClientException, UnsupportedEncodingException {
Map<?, ?> obj = restTemplate.getForObject(GOOGLE_MAPS_API_ENDPOINT, Map.class, encode(address, "UTF-8"));
// check the response status
String status = (String) obj.get("status");
if (!status.equals(STATUS_OK)) {
throw new RuntimeException(buildMessage(status));
}
List<?> results = (List<?>) obj.get("results");
Map<?, ?> result = (Map<?, ?>) results.get(0);
Map<?, ?> geometry = (Map<?, ?>) result.get("geometry");
Map<?, ?> location = (Map<?, ?>) geometry.get("location");
return new double[]{
(Double) location.get("lat"),
(Double) location.get("lng")
};
}
}