package pt.spm.cliente.map;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import pt.spm.ReceivedMsgActivity;
/**
*
* @author ICM
*/
public class GMapController {
private Context context;
private MapView mapView;
private MapController mapController;
private MyItemizedOverlay itemizedOverlay;
private final List<Overlay> mapOverlay;
//Options
//To show only one pin if true
private boolean singleItem = false;
private boolean showDialog = true;
private class MyItemizedOverlay extends ItemizedOverlay {
private ArrayList<OverlayItem> overlays = new ArrayList<OverlayItem>();
private ArrayList<Integer> indexes = new ArrayList<Integer>();
public MyItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
public void addOverlay(OverlayItem overlay, int index) {
if (singleItem) {
overlays.clear();
indexes.clear();
}
overlays.add(overlay);
indexes.add(index);
populate();
}
@Override
protected OverlayItem createItem(int i) {
return overlays.get(i);
}
@Override
public int size() {
return overlays.size();
}
@Override
protected boolean onTap(int index) {
final int id = indexes.get(index);
if (showDialog) {
OverlayItem item = overlays.get(index);
Builder dialog = new Builder(context);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.setPositiveButton("Ver mensagem", new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
//TODO: Criar Intent para abrir mensagem completa
Intent itt = new Intent(context, ReceivedMsgActivity.class);
itt.putExtra("idMsg", id);
context.startActivity(itt);
}
});
dialog.show();
}
return true;
}
public void clear() {
overlays.clear();
}
}
public GMapController(Context context) {
this.context = context;
mapOverlay = null;
}
/*
* Construtor
* @param context Contexto de execuo
* @param mapView Objecto MapView onde vo ser feitas as operaes do mapa
* @param pin Imagem a colocar no mapa
* @param singleItem Se verdadeiro, o mapa apenas ter um pin de cada vez
*/
public GMapController(Context context, MapView mapView, Drawable pin, boolean singleItem) {
this.context = context;
this.singleItem = singleItem;
this.mapView = mapView;
this.mapController = mapView.getController();
this.mapOverlay = mapView.getOverlays();
this.itemizedOverlay = new MyItemizedOverlay(pin);
//Set built in zoom controls to be shown
this.mapView.setBuiltInZoomControls(true);
this.mapView.setTraffic(true);
}
public void changePin(Drawable pin) {
this.itemizedOverlay = new MyItemizedOverlay(pin);
}
/*
* Usado para definir se aparece dialogo ao clicar ou no
* @param value Se true, aparece o dilogo ao clicar
*/
public void setShowDialog(boolean value) {
showDialog = value;
}
/*
* Ampliar o mapa
* @param value Nvel de ampliao do mapa
*/
public void setZoom(int value) {
mapController.setZoom(value);
}
/*
* Ir para localizao. Move o mapa para a localizao indicada
* @param location Localizao para onde o mapa ser movido
*/
public void goToLocation(GeoPoint location) {
mapController.animateTo(location);
setZoom(15);
}
/*
* Recebe endereo a partir de coordenadas geogrficas
* @param location Coordenadas geogrficas
* @return Endereo da localizao
*/
public String getAddressFromLocation(GeoPoint location) {
Geocoder geoCoder = new Geocoder(context, Locale.getDefault());
String address = "";
try {
List<Address> addresses = geoCoder.getFromLocation(
location.getLatitudeE6() / 1E6,
location.getLongitudeE6() / 1E6, 1);
if (addresses.size() > 0) {
for (int i = 0; i < addresses.get(0).getMaxAddressLineIndex();
i++) {
address += addresses.get(0).getAddressLine(i) + "\n";
}
}
} catch (IOException e) {
e.printStackTrace();
}
return address;
}
/*
* Recebe coordenadas geogrficas de um dado endereo
* @param address Endereo
* @return Coordenadas geogrficas do endereo
*/
public GeoPoint getLocationFromAddress(String address) {
Geocoder geoCoder = new Geocoder(context, Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocationName(address, 1);
if (addresses.size() > 0) {
return new GeoPoint(
(int) (addresses.get(0).getLatitude() * 1E6),
(int) (addresses.get(0).getLongitude() * 1E6));
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/*
* Desenha ponto com imagem no mapa.
* @param idPonto identificao do ponto
* @param location localizao a colocar o ponto
* @param title Ttulo a definir para o Dialog ao clicar no ponto
* @param description Descrio a definir para o Dialog ao clicar no ponto
* @param goToLocation Se verdadeiro, desloca o mapa depois de desenhar o ponto
*/
public void drawPin(int idPonto, GeoPoint location, String title, String description, Boolean goToLocation) {
OverlayItem oi = new OverlayItem(location, title, description);
itemizedOverlay.addOverlay(oi, idPonto);
mapOverlay.add(itemizedOverlay);
if (goToLocation) {
goToLocation(location);
}
}
/*
* Apaga todos os pontos do mapa
*/
public void clearPins() {
itemizedOverlay.clear();
}
/*
* Veness, C. (Janeiro de 2010). Calculate distance, bearing and more between Latitude/Longitude points. Obtido em 26 de Maio de 2010, de Movable Type Scripts: http://www.movable-type.co.uk/scripts/latlong.html
*/
public static Double distancia(Double lat1, Double lat2, Double lon1, Double lon2) {
double raio = 3958.75;
double dlat = ToRadians(lat2 - lat1);
double dlon = ToRadians(lon2 - lon1);
double a = Math.sin(dlat / 2) * Math.sin(dlat / 2)
+ Math.cos(ToRadians(lat1)) * Math.cos(ToRadians(lat2))
* Math.sin(dlon / 2) * Math.sin(dlon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
Double d = raio * c;
double meterConversion = 1609.00;
System.out.println("Teste: " + d * meterConversion);
return d * meterConversion;
}
private static double ToRadians(double degrees) {
double radians = degrees * 3.1415926535897932385 / 180;
return radians;
}
//Verifica se (lat1, lon1) est dentro do (lat2, lon2)+raio
public static boolean verificarProximidade(Double lat1, Double lat2, Double lon1, Double lon2, int raio) {
if (distancia(lat1, lat2, lon1, lon2) > raio) {
return false;
}
//Se estiver dentro do raio*/
return true;
}
}
|