Escola Superior de Tecnologia e Gestão
Instituto Politécnico da Guarda
Seminário I
Google Maps API
Aluno: Ricardo Almeida n.º 1010694
Curso: Mestrado em Computação Móvel
Ano Letivo: 2016/2017
Conteúdo
Resumo.......................................................................................................................................... 1
1 Introdução ............................................................................................................................. 2
2 Plataforma Android ............................................................................................................... 3
2.1 Android Studio .............................................................................................................. 3
2.2 Google Maps API ........................................................................................................... 3
3 Projeto com Google Maps..................................................................................................... 4
3.1 Criação chave da API Google Maps ............................................................................... 4
3.2 Criação do Projeto no Android Studio........................................................................... 5
4 Desenvolvimento .................................................................................................................. 8
4.1 Vistas ............................................................................................................................. 8
4.2 Direções....................................................................................................................... 11
5 Exemplos de utilização da API Google Maps....................................................................... 19
5.1 OpenSignal .................................................................................................................. 19
5.2 RunStatic ..................................................................................................................... 19
5.3 myTaxy ........................................................................................................................ 20
6 Conclusões........................................................................................................................... 21
7 Referências .......................................................................................................................... 22
Figuras
Figura 1 - Criação de projeto na consola de desenvolvedores da Google. ................................... 4
Figura 2 - Enable da Google Maps Directions API ......................................................................... 4
Figura 3 - Criação de credenciais................................................................................................... 5
Figura 4 - Dashboard com a Google Maps Directions API............................................................. 5
Figura 5 - Criação de um novo projeto no Android Studio. .......................................................... 6
Figura 6 - Atividade Google Maps na criação do projeto. ............................................................. 6
Figura 7 - Substituição da chave da API no projeto criado. .......................................................... 7
Figura 8 - Código inicial do projeto. .............................................................................................. 7
Figura 9 - Execução da aplicação com o código inicial. ................................................................. 7
Figura 10 - Layout do exemplo prático. ...................................................................................... 10
Figura 11 – Mudança das vistas. ................................................................................................. 11
Figura 12 - Resposta JSON dada pela API. ................................................................................... 14
Figura 13 - Aplicação final. .......................................................................................................... 18
Figura 14 - Aplicação OpenSignal. ............................................................................................... 19
Figura 15 - Aplicação RunStatic. .................................................................................................. 19
Figura 16 - Aplicação myTaxy. ..................................................................................................... 20
Resumo
Neste workshop será abordada a utilização da API Google Maps numa aplicação Android, onde
serão demonstradas duas funcionalidades: as diferentes vistas de um mapa e as direções de um
ponto A para o ponto B.
Será um dos objetivos deste workshop demonstrar estas funcionalidades assim como explicar a
estrutura da API e de como fazer uso dela.
1
1 Introdução
O objetivo deste seminário é o de apresentar a plataforma Google Maps e a sua API. Google
Maps é uma plataforma de mapeamento e localização lançada em fevereiro de 2005. Dois meses
depois, estavam disponíveis a vista satélite e direções. Em junho desse ano foi disponibilizada
ao público a API Google Maps. Em fevereiro de 2007 foram adicionadas informações de trânsito
em tempo real e em março do mesmo ano é lançado o Street View no Google Maps.
Neste seminário é proposto a implementação de alguns recursos que a API Google Maps nos
fornece, desde a visualização do mapa, as suas diferentes vistas e as direções entre dois pontos
no mapa.
2
2 Plataforma Android
O Android é um sistema operativo móvel baseado em Linux. Foi lançado publicamente em 2008
e desde então já está na versão 7, com o nome Nougat.
2.1 Android Studio
Android Studio é um IDE baseado no IntelliJ IDEA. Este IDE oferece integração com os serviços
da Google, como a Google Cloud Platform, com o GitHub e ferramentas de programador, como
o Android SDK. Atualmente este IDE vai na versão 2.2.3.
2.2 Google Maps API
A Google Maps API vai atualmente na versão 3. Está dividida em quatro categorias: Android, iOS,
Web e Web Services. Nas categorias Android e iOS estão disponíveis duas APIs, Google Maps e
Google Places, enquanto que na Web está disponível também a API da Google Street View.
Relativamente aos Web Services APIs, estão disponíveis APIs que vêm completar as restantes
com funções de elevação, localização e direções por exemplo, tendo de ser requisitadas via
HTTP, sendo a resposta recebida em JSON.
Google Maps API
Android iOS Web APIs Web Service APIs
Google Maps Android API Google Maps SDK for iOS Google Maps Embed API Google Maps Directions API
Google Places API for Android Google Places API for iOS Google Maps JavaScript API Google Maps Distance Matrix API
Places Library in the Google Maps Google Maps Elevation API
JavaScript API
Google Static Maps API Google Maps Geocoding API
Google Street View Image API Google Maps Geolocation API
Google Places API Web Service
Google Maps Roads API
Google Maps Time Zona API
Tabela 1 - Estrutura da Google Maps API
No exemplo prático deste seminário vão ser utilizadas a Google Maps Android API e a Google
Maps Directions API.
3
3 Projeto com Google Maps
3.1 Criação chave da API Google Maps
Para o exemplo prático deste seminário vão ser necessárias duas APIs, a Google Maps e a Google
Maps Directions. Para se obter uma chave de utilização das APIs têm de se ter uma conta Google.
Na consola dos developers, seguir os seguintes passos:
1. Criar um projeto.
Figura 1 - Criação de projeto na consola de desenvolvedores da Google.
2. Ativar a API Google Maps Directions. Na aba lateral, na opção Library, pesquisar por
Google Maps Directions. Selecionada a API, tem de se ativar fazendo o enable.
Figura 2 - Enable da Google Maps Directions API
3. Criar credenciais. Depois de feito o enable da API pode ser necessário criar credenciais
de utilização, a chave. Para isso seleciona-se no diálogo da Figura 3. A opção “Create
Credentials”. O passo seguinte será selecionar a opção “What credentials do I need?”,
que vai criar a chave necessária. Depois deste passo, na Dashboard aparecerá a API do
Google Maps Directions como mostra a Figura 4.
4
Figura 3 - Criação de credenciais.
Figura 4 - Dashboard com a Google Maps Directions API.
4. Para a utilização dos mapas, é preciso ativar a API Google Maps, e para isso faz-se o
mesmo processo feito no passo 2, desta vez na Google Maps Android API. Não vai ser
necessário criar credenciais pois vão ser utilizadas as credenciais do Google Maps
Directions API.
Concluídos estes passos já se pode criar uma aplicação Android que utilize a API Google Maps.
3.2 Criação do Projeto no Android Studio
No desenvolvimento de exemplos práticos neste seminário é utilizado o Android Studio. Para a
criação de um projeto que utilize mapas, e por consequente a API Google Maps, seguir os
seguintes passos:
1. Criar novo projeto.
5
Figura 5 - Criação de um novo projeto no Android Studio.
2. Selecionar atividade Google Maps.
Figura 6 - Atividade Google Maps na criação do projeto.
6
3. Criado o projeto, reparamos que foi criado um ficheiro XML chamado
google_maps_api.xml. Neste ficheiro é onde vai ser especificada a chave que foi obtida
para a utilização da API substituindo YOUR_KEY_HERE pela nossa chave.
Figura 7 - Substituição da chave da API no projeto criado.
4. No [Link] está já um código inicial, onde especifica a latitude e longitude da
cidade de Sydney. Vai ser adicionado um marcador nessa posição e o mapa vai ser
redirecionado para essa posição.
Figura 8 - Código inicial do projeto.
5. Tendo colocado a chave da API obtida na nossa aplicação, esta está pronta a ser
instalada no dispositivo ou emulador. Esta vai mostrar um marcador na posição da
cidade de Sydney por defeito como ilustrado na Figura 9.
Figura 9 - Execução da aplicação com o código inicial.
7
Seguidos estes passos, a aplicação já acede à API Google Maps.
4 Desenvolvimento
No exemplo prático são propostos dois objetivos: mudar as várias vistas do mapa e
conseguirmos obter direções de um ponto A para um ponto B.
4.1 Vistas
A API Google Maps tem várias vistas que podem ser utilizadas, desde satélite a topográfica. Na
aplicação vamos utilizar um spinner para selecionarmos as diferentes vistas que temos ao dispor.
O layout geral da aplicação vai ser o mostrado na Figura 10. Para isso o ficheiro de layout da
atividade principal, activity_maps.xml vai ter o seguinte código:
<LinearLayout
xmlns:android="[Link]
xmlns:map="[Link]
xmlns:tools="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/etOrigin"
android:hint="Enter origin address" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter destination address"
android:id="@+id/etDestination" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Find path"
android:id="@+id/btnFindPath" />
<TextView
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0 km"
8
android:id="@+id/tvDistance" />
<TextView
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0 min"
android:id="@+id/tvDuration" />
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/spinnerMode"
android:layout_weight="1" />
</LinearLayout>
<ProgressBar
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar"
android:layout_gravity="center"
android:visibility="invisible" />
<fragment
xmlns:android="[Link]
xmlns:map="[Link]
xmlns:tools="[Link]
android:id="@+id/map"
android:name="[Link]"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="[Link]" />
</LinearLayout>
No fragmento é onde vai estar presente o mapa. Depois vão estar duas EditText onde vão ser
inseridos os endereços que se quer saber as direções, um botão para validar e enviar pedido de
direções e o spinner com as diferentes vistas.
No ficheiro [Link], presente na pasta values dos resources, vão estar especificados os IDs
das strings que vão estar dentro do spinner, assim como os itens presentes nesse spinner.
<string-array name="layers_array">
<item>@string/normal</item>
<item>@string/hybrid</item>
<item>@string/satellite</item>
<item>@string/terrain</item>
<item>@string/none_map</item>
</string-array>
<string name="normal">Normal</string>
<string name="hybrid">Hybrid</string>
<string name="satellite">Satellite</string>
<string name="terrain">Terrain</string>
<string name="none_map">None Map</string>
9
No ficheiro MainActivity tem de se indicar que o spinner é identificado pelo ID spinnerMode e
também tem de se atribuir valores a um array que vai ser associado ao spinner.
mSpinner = (Spinner) findViewById([Link]);
ArrayAdapter<CharSequence> adapter = [Link](
this, [Link].layers_array,
[Link].simple_spinner_item);
[Link]([Link].simple_spinner_dropdo
wn_item);
[Link](adapter);
[Link](this);
Para se poder selecionar um item presente no spinner a aplicação tem de implementar o
[Link], para poder haver ação aquando da seleção do item.
Se executarmos a aplicação, o resultado é o representado pela Figura 10.
Figura 10 - Layout do exemplo prático.
Quando se seleciona o spinner, este mostra as várias opções disponíveis na API Google Maps.
Para serem implementadas as vistas, tem de se estabelecer uma relação entre a seleção do item
do spinner com o método onItemSelected(). Com essa intenção cria-se o método
updateMapType() com o seguinte código:
private void updateMapType() {
if(mMap == null){
return;
}
String layerName = ((String) [Link]());
if([Link](getString([Link]))){
10
[Link](GoogleMap.MAP_TYPE_NORMAL);
} else if([Link](getString([Link]))){
[Link](GoogleMap.MAP_TYPE_HYBRID);
} else if([Link](getString([Link]))){
[Link](GoogleMap.MAP_TYPE_SATELLITE);
} else if([Link](getString([Link]))){
[Link](GoogleMap.MAP_TYPE_TERRAIN);
} else if([Link](getString([Link].none_map))){
[Link](GoogleMap.MAP_TYPE_NONE);
}
}
O que o código acima vai fazer é ler o valor do item selecionado e conforme o seu valor, mudar
o tipo de vista apresentado ao utilizador utilizando o método setMapType(). Para chamar o
método:
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int
i, long l) {
updateMapType();
}
Ao executarmos a aplicação e selecionarmos uma vista, esta já vai alterar a visualização do mapa
como mostra a Figura 11.
Figura 11 – Mudança das vistas.
4.2 Direções
Nesta secção do exemplo prático vai ser necessário enviar um pedido de direções entre um
ponto A e um ponto B à API Google Maps Directions. Esse pedido vai ser feito através do
11
protocolo HTTP e executado quando é carregado o botão “Find Path” presente na nossa
aplicação. Para isso é necessário seguir os próximos passos:
1. Quando o botão é pressionado é chamada uma função que vai enviar um pedido à API.
Este código está presente no método onCreate(Bundle savedInstance) do ficheiro
[Link].
[Link](new [Link](){
@Override
public void onClick(View view) {
sendRequest();
}
});
2. A função chamada pelo botão vai ser a sendRequest(). Esta função vai apanhar os dados
introduzidos pelo utilizador e depois de validados chama uma função assíncrona,
FetchData(), que vai construir um URL com os dados (origem e destino) e a chave API
obtida anteriormente. De seguida vai fazer um pedido à API e receber os dados.
private void sendRequest() {
origin = [Link]().toString();
destination = [Link]().toString();
if([Link]()){
[Link](this, "Falta endereço de origem!",
Toast.LENGTH_SHORT).show();
}
if([Link]()){
[Link](this, "Falta endereço de destino!",
Toast.LENGTH_SHORT).show();
}
new FetchData().execute();
}
A função FetchData vai chamar a função builtURL presente na classe [Link].
que vai fazer a construção do URL necessário à chamada da API. Depois de retornado o
valor do URL, é feito o pedido e é guardada a resposta numa string. Essa string vai ser
passada por parâmetro para a função parseJson() para serem retirados os valores
relevantes à nossa aplicação.
public class FetchData extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
[Link]();
[Link]([Link]);
}
@Override
protected String doInBackground(String... strings) {
12
URL url = [Link](origin, destination);
try{
HttpURLConnection urlConnection = (HttpURLConnection)
[Link]();
InputStream in = [Link]();
Scanner scanner = new Scanner(in);
[Link]("\\A");
if([Link]()){
return [Link]();
}else{
return null;
}
} catch (IOException e) {
[Link]();
}
return null;
}
@Override
protected void onPostExecute(String strings) {
[Link](strings);
[Link]([Link]);
try{
parseJSon(strings);
} catch (JSONException e) {
[Link]();
}
}
}
public class NetworkUtils {
private static final String API_KEY = "A_CHAVE_API_AQUI";
private static final String BASE_URL =
"[Link]
//private String origin;
//private String destination;
public static URL buildUrl(String origem, String destino){
[Link] uriBuilder = [Link](BASE_URL).buildUpon();
[Link]("origin", origem);
[Link]("destination", destino);
[Link]("key", API_KEY);
[Link]();
URL url = null;
try{
url = new URL([Link]());
}catch(MalformedURLException e){
[Link]();
}
return url;
}
}
13
3. Feito o pedido, tem de se tratar os dados recebidos. Os dados são recebidos em JSON
como mostra a Figura 12, e tem de se filtrar os dados que se quer mostrar ao utilizador
e que se pretende utilizar na construção do mapa.
Figura 12 - Resposta JSON dada pela API.
Um dos pontos que interessa guardar é o overview_polyline. Este valor tem agregados
todos os pontos polyline e é através desses pontos que vai ser desenhada uma linha
orientadora no mapa para ilustrar ao utilizador as direções. A API Google Maps
disponibiliza na sua estrutura alguns métodos para desenhar no mapa. É possível
desenhar linhas, polígonos, círculos e quadrados. Neste exemplo prático vão ser
utilizadas linhas, através das polylines. A polyline vai desenhar uma linha entre dois
pontos de coordenadas (latitude e longitude) e visto os valores dessas coordenadas
chegarem codificados, é necessário fazer-se uma descodificação e para isso é chamada
a função decodePolyline() que vai retornar valores de coordenadas prontas a serem
desenhadas no mapa. Estes valores são codificados com o propósito de comprimir os
valores da string. Os valores de coordenadas são convertidos em binário, agrupados em
grupos de cinco, convertidos de novo para decimal e soma-se 63 ao número obtido.
Depois disso os valores são convertidos em código ASCII, que é o que vem na resposta
da API.
14
private void parseJSon(String data) throws JSONException {
if (data == null){
return;
}
List<Route> routes = new ArrayList<Route>();
JSONObject jsonData = new JSONObject(data);
JSONArray jsonRoutes = [Link]("routes");
for (int i = 0; i < [Link](); i++) {
JSONObject jsonRoute = [Link](i);
Route route = new Route();
JSONObject overview_polylineJson =
[Link]("overview_polyline");
JSONArray jsonLegs = [Link]("legs");
JSONObject jsonLeg = [Link](0);
JSONObject jsonDistance =
[Link]("distance");
JSONObject jsonDuration =
[Link]("duration");
JSONObject jsonEndLocation =
[Link]("end_location");
JSONObject jsonStartLocation =
[Link]("start_location");
[Link] = new
Distance([Link]("text"),
[Link]("value"));
[Link] = new
Duration([Link]("text"),
[Link]("value"));
[Link] = [Link]("end_address");
[Link] = [Link]("start_address");
[Link] = new
LatLng([Link]("lat"),
[Link]("lng"));
[Link] = new
LatLng([Link]("lat"),
[Link]("lng"));
[Link] =
decodePolyLine(overview_polylineJson.getString("points"));
[Link](route);
}
onDirectionSuccess(routes);
}
private List<LatLng> decodePolyLine(final String poly) {
int len = [Link]();
int index = 0;
List<LatLng> decoded = new ArrayList<LatLng>();
int lat = 0;
int lng = 0;
while (index < len) {
int b;
int shift = 0;
int result = 0;
15
do {
b = [Link](index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result
>> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = [Link](index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result
>> 1));
lng += dlng;
[Link](new LatLng(
lat / 100000d, lng / 100000d
));
}
return decoded;
}
O que o código acima faz é o processo inverso utilizado na conversão.
4. Concluído o processo de descodificação dos valores do overview_polyline, a função
onDirectionSucess() é chamada, com o parâmetro routes onde estão guardados os
valores do endereço inicial e as suas coordenadas, valores do endereço final e as suas
coordenadas assim como a distância e a duração da viagem entre os dois pontos, e é
ela que vai desenhar no mapa as linhas através dos diversos pontos entre o Ponto A e
o Ponto B.
public void onDirectionSuccess(List<Route> routes) {
polylinePaths = new ArrayList<>();
originMarkers = new ArrayList<>();
destinationMarkers = new ArrayList<>();
for (Route route : routes) {
[Link]([Link]([Link]
ation, 16));
((TextView)
findViewById([Link])).setText([Link]);
((TextView)
findViewById([Link])).setText([Link]);
[Link]([Link](new MarkerOptions()
.title([Link])
.position([Link])
16
.icon([Link](BitmapDescriptorFact
ory.HUE_AZURE))));
[Link]([Link](new
MarkerOptions()
.title([Link])
.position([Link])));
PolylineOptions polylineOptions = new PolylineOptions().
geodesic(true).
color([Link]).
width(10);
for (int i = 0; i < [Link](); i++)
[Link]([Link](i));
[Link]([Link](polylineOptions));
}
}
As Polyline têm como opções:
Points: são os vértices da linha;
Width: representa a largura da linha, e esta é independente do nível de zoom
da câmara.
Color: cor da linha
Z-Index: ordem em que as polyline são desenhadas em relação a outros overlays
( GroundOverlay, TileOverlay, Circle e Polygon)
Visibility: indica se a linha é visível ou não. Uma linha invisível não é desenhada
no mapa mas mantêm as suas propriedades
Geodesic status: estando este valor a true, tem em conta o caminho mais curto
entre os dois endereços e a curva geodésica tem em conta a curvatura da terra,
ao contrário da projeção do Mercador.
Clickability: se o utilizador quiser interagir com a linha esta propriedade tem de
estar a true.
O resultado final da aplicação está representado na Figura 13. Dados os endereços pretendidos
é desenhado no mapa uma linha que liga o endereço inicial e final, e é indicada a distância entre
os dois pontos, assim como a duração da viagem. É importante referir que a API Google Maps
Directions tem em conta o modo de transporte. Neste exemplo prático não foi especificado
nenhum, e a API assumiu que o modo de transporte era DRIVING. Este modo indica direções
para a rede de estradas presentes no mapa. Existem os modos WALKING (indica direções por
caminhos pedestres e passeios), BICYCLING (indica direções por ciclovias ou ruas preferidas) e o
modo TRANSIT (direções através de rotas dos transportes públicos, onde é possível especificar
a hora de partida ou hora de chegada).
17
Figura 13 - Aplicação final.
18
5 Exemplos de utilização da API Google Maps
Existe um grande número de aplicações que utilizam a API Google Maps. Três desses exemplos
são o OpenSignal, o RunStatic e o myTaxi.
5.1 OpenSignal
O OpenSignal é uma aplicação para diagnóstico de rede móvel. Na sua aplicação este mostra ao
utilizador que antenas é que têm melhor sinal e a que distância estas estão.
Figura 14 - Aplicação OpenSignal.
5.2 RunStatic
O RunStatic é uma aplicação de desporto. Esta aplicação recolhe dados da sessão de treino,
corrida por exemplo, e desenha o percurso feito pelo utilizador com os dados associados do
treino.
Figura 15 - Aplicação RunStatic.
19
5.3 myTaxy
O myTaxy é uma aplicação para chamar táxis que faz uso da API para obter a nossa localização
e mostrar a localização de táxis ao redor da nossa aplicação.
Figura 16 - Aplicação myTaxy.
20
6 Conclusões
Com este trabalho foi possível verificar como funciona num nível básico a API Google Maps.
Foi demonstrado a mudança de vistas no mapa e a obtenção de direções entre dois endereços
com relativa facilidade. No enquadramento atual em que muitas aplicações necessitam de
utilizar um sistema de mapeamento é necessário saber fazer uso do que está disponível e a API
Google Maps é um recurso muito válido para essa tarefa, com boa documentação e relativa
facilidade de programação.
21
7 Referências
1. GitHub Google Maps. Repositório online de exemplos relativos ao Google Maps API
[Link]
2. Google Developers. Google Maps Android API.
[Link]
22