package com.odc.beachodc.utilities; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import com.google.android.gms.location.LocationClient; import com.google.android.gms.maps.model.LatLng; import com.odc.beachodc.R; import com.odc.beachodc.db.BBDD; import com.odc.beachodc.db.models.Comentario; import com.odc.beachodc.db.models.MensajeBotella; import com.odc.beachodc.db.models.Playa; import org.json.JSONArray; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Comparator; import de.keyboardsurfer.android.widget.crouton.Crouton; import de.keyboardsurfer.android.widget.crouton.Style; /** * Created by Paco on 07/07/2014. */ public class Geo { public static Location myLocation; // Ultima posicion conocida //private static final int DEGREE_DISTANCE_AT_EQUATOR = 111329; /** * the radius of the earth in meters. */ /** * the length of one minute of latitude in meters, i.e. one nautical mile in meters. */ private static final double MINUTES_TO_METERS = 1852d; /** * the amount of minutes in one degree. */ private static final double DEGREE_TO_MINUTES = 60d; /** * This method extrapolates the endpoint of a movement with a given length from a given starting point using a given * course. * * startPointLat the latitude of the starting point in degrees, must not be {@link Double#NaN}. * startPointLon the longitude of the starting point in degrees, must not be {@link Double#NaN}. * course the course to be used for extrapolation in degrees, must not be {@link Double#NaN}. * distance the distance to be extrapolated in meters, must not be {@link Double#NaN}. * * @return the extrapolated point. public static ArrayList<Long> extrapolate(final double startPointLat, final double startPointLon, final double course, final double distance) { // //lat =asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc)) //dlon=atan2(sin(tc)*sin(d)*cos(lat1),cos(d)-sin(lat1)*sin(lat)) //lon=mod( lon1+dlon +pi,2*pi )-pi // // where: // lat1,lon1 -start pointi n radians // d - distance in radians Deg2Rad(nm/60) // tc - course in radians final double crs = Math.toRadians(course); final double d12 = Math.toRadians(distance / MINUTES_TO_METERS / DEGREE_TO_MINUTES); final double lat1 = Math.toRadians(startPointLat); final double lon1 = Math.toRadians(startPointLon); final double lat = Math.asin(Math.sin(lat1) * Math.cos(d12) + Math.cos(lat1) * Math.sin(d12) * Math.cos(crs)); final double dlon = Math.atan2(Math.sin(crs) * Math.sin(d12) * Math.cos(lat1), Math.cos(d12) - Math.sin(lat1) * Math.sin(lat)); final double lon = (lon1 + dlon + Math.PI) % (2 * Math.PI) - Math.PI; ArrayList<Long> ret = new ArrayList<Long>(); ret.add(Long.valueOf((String.format("%.7f", Math.toDegrees(lat)).replace(",", "")))); ret.add(Long.valueOf((String.format("%.7f", Math.toDegrees(lon)).replace(",", "")))); return ret; } public static ArrayList<Long> getXMeterAreaToPoint(long latitud, long longitud, Double meters){ ArrayList<Long> ret = new ArrayList<Long>(); Double lat=Double.valueOf(latitud)/10000000; Double lng=Double.valueOf(longitud)/10000000; // Derecha ArrayList<Long> calc = extrapolate(lat, lng, 0, meters); ret.add(calc.get(0)); //lat //ret.add(calc.get(1)); //lon // Superior calc = extrapolate(lat, lng, 90, meters); //ret.add(calc.get(0)); //lat ret.add(calc.get(1)); //lon // Izquierda calc = extrapolate(lat, lng, 180, meters); ret.add(calc.get(0)); //lat //ret.add(calc.get(1)); //lon // Debajo calc = extrapolate(lat, lng, 270, meters); //ret.add(calc.get(0)); //lat ret.add(calc.get(1)); //lon return ret; } //Radio en Metros public static List<Playa> getPlayasCercanas(Context ctx, long latitud, long longitud, Double radio){ ArrayList<Long> dimensiones = getXMeterAreaToPoint(latitud, longitud, radio); if (dimensiones.size()>0){ List ret = new ArrayList<Playa>(); try { ret = BBDD.getApplicationDataContext(ctx).playasDao.search(false, "longitud > ? and longitud < ? and latitud > ? and latitud < ?", new String[]{dimensiones.get(3).toString(), dimensiones.get(1).toString(), dimensiones.get(2).toString(), dimensiones.get(0).toString()}, null, null, null, null, null); } catch (Exception e){ Log.i("BBDD", "Fallo al intentar buscar Playas cercanas"); } return ret; } else return new ArrayList<Playa>(); }*/ public static float getDistanceInMetersToMe (Double latitud, Double longitud){ if (myLocation != null){ Location destiny = new Location ("destino"); destiny.setLatitude(latitud); destiny.setLongitude(longitud); return Geo.myLocation.distanceTo(destiny); } else { return -1; } } public static float getDistanceInMetersTo (Double latitudD, Double longitudD, Double latitudO, Double longitudO){ Location destiny = new Location ("destino"); destiny.setLatitude(latitudD); destiny.setLongitude(longitudD); Location origin = new Location ("origen"); origin.setLatitude(latitudO); origin.setLongitude(longitudO); return origin.distanceTo(destiny); } public static String getDistanceToPrint (Context ctx, Double latitud, Double longitud){ float distance = Geo.getDistanceInMetersToMe(latitud, longitud); if (distance == -1) return ctx.getString(R.string.question)+" "+ctx.getString(R.string.meters); else { if ((distance / 1000) >= 1) { // Formato en km. DecimalFormat df = new DecimalFormat("#.#"); return df.format((distance/1000))+" "+ctx.getString(R.string.kilometers); } else { // Formato en m. return ((int) distance)+" "+ctx.getString(R.string.meters); } } } public static String getDistanceToPrint (Context ctx, Double latitudO, Double longitudO, Double latitudD, Double longitudD){ float distance = Geo.getDistanceInMetersTo(latitudD, longitudD, latitudO, longitudO); if (distance == -1) return ctx.getString(R.string.question)+" "+ctx.getString(R.string.meters); else { if ((distance / 1000) >= 1) { // Formato en km. DecimalFormat df = new DecimalFormat("#.#"); return df.format((distance/1000))+" "+ctx.getString(R.string.kilometers); } else { // Formato en m. return ((int) distance)+" "+ctx.getString(R.string.meters); } } } public static List<Playa> orderByDistance (List<Playa> playas){ Collections.sort(playas, new PlayasDistanceComparator()); return playas; } public static List<Playa> orderByDistanceTo (List<Playa> playas, LatLng origin){ Collections.sort(playas, new PlayasDistanceComparator(false, origin)); return playas; } public static boolean isNearToMe (Double latitud, Double longitud){ if (Geo.myLocation != null) { float distance = Geo.getDistanceInMetersTo(latitud, longitud, Geo.myLocation.getLatitude(), Geo.myLocation.getLongitude()); if ((distance > -1) && (distance < 501)){ return true; } } return false; } public static void checkGPSandAlert (final Context ctx){ if (!((LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE)).isProviderEnabled(LocationManager.GPS_PROVIDER)) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx); alertDialogBuilder .setMessage(ctx.getString(R.string.no_gps_title)) .setCancelable(true) .setPositiveButton(ctx.getString(R.string.go_to_gps), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { Intent callGPSSettingIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); ctx.startActivity(callGPSSettingIntent); } }); AlertDialog alert = alertDialogBuilder.create(); alert.show(); } } }