Ver Mensaje Individual
  #1 (permalink)  
Antiguo 12/07/2021, 04:54
Avatar de zerpico_01
zerpico_01
 
Fecha de Ingreso: enero-2008
Ubicación: Wilde - Avellaneda -
Mensajes: 421
Antigüedad: 16 años, 3 meses
Puntos: 13
Problema con distancias lineal por coordenandas!!

Faaaa ni idea de como plantear el tema

a ver...

Le cuento estoy realizando un proyecto, en el cual debo obtener distancias entre coordenadas, utilizo dos funciones para ajustar las distancias, pues son lineales, no precisas, o sea evito usar
deformaciones de proyecciones Gauss-Krüger y UTM, puesto que no es relevante la topografía ni alturas del territorio, en el que se aplique, o sea siempre tendrá una diferencia en km o ppm.
En fin, lo que hice es crear una class que recibe cuatro coordenadas y calcula la distancia en km, millas, esto funciona perfecto.
Lo que me sucede es que hice otra class, que ejecuta timezone de php, genero las latitudes y longitudes de las timezones y luego paso esos valores a la class dicha arriba, y quiero conseguir la distancia mas próxima a la latitud y longitud del usuario, esto lo logro, pero sucede que obtengo lo inverso usano min y max de php, por ejemplo:
coloco mi coordenada de mi ciudad y debería darme como próxima tieme zona buenos aires, pero me arroja ushuia, y si coloco al array max me entrega buenos aires que debería ser con MIN pero funciona al revés o que sucedeeeee :(

funcion usando Geodésico class GeoTools

Código PHP:
    /** @see https://www.ngs.noaa.gov/cgi-bin/Inv_Fwd/inverse2.prl
     * Geodésico
     * $tyepe = 1 kilometros, 2 miles
     * corrección arco-cuerda puede calcularse mediante la siguiente expresión: Cac = D3 / 24 RM2
     * radio medio aproximado a incluir en la fórmula es 6.371.000 metros
     */
     
public static function distanceGeodesico($lat1$long1$lat2$long2$type 1$round true)
     {
        
$deg_to_rad 0.01745329;
        
$rad_to_deg 57.29577951;
        
$distance_long = ($long1 $long2);
        
$value 0;
        
$distance_value = (
            (
sin($lat1 $deg_to_rad) * sin($lat2 $deg_to_rad)) +
            (
cos($lat1 $deg_to_rad) * cos($lat2 $deg_to_rad) * cos($distance_long $deg_to_rad))
        );
        
$fc acos($distance_value) * $rad_to_deg;
        if (
$type == 1) {
            
$value = ($fc 111.302);
        } else {
            
$value = ($fc 69.16);
        }
        return (
$round ceil($value) : $value);
    } 
funcion distancia lineal simle class GeoTools

Código PHP:
    /**
     * @$unit value = 1 Kilometros, value 2 millas, value 3 millas nauticas.
     * default Kilometro value = 1
     * @$round redondea hacia arriba el resultado a un entero.
     * lat1 y long1 desde coordenandas
     * lat2 y long2 hasta coordenadas
     * @note no contempla deformaciones de proyecciones Gauss-Krüger y UTM.
     *
     */
    
public static function linealDistance($lat1$lon1$lat2$lon2$unit 1$round true)
    {
        
$radius_earth 6378.137;
        
$distance_lon $lon1 $lon2;
        
$lineal_distance 0;
        
$distance acos(
            
sin(deg2rad($lat1)) *
            
sin(deg2rad($lat2)) +
            
cos(deg2rad($lat1)) *
            
cos(deg2rad($lat2)) *
            
cos(deg2rad($distance_lon))
        ) * 
$radius_earth;

        if (
$unit == 1) {
            
$lineal_distance = ($round ceil($distance) : $distance);
        } elseif (
$unit == 2) {
            
$lineal_distance $round ceil($distance 0.621371192) : $distance 0.621371192;
        } else {
            
$lineal_distance $round ceil($distance 0.539956803) : $distance 0.539956803;
        }
        return 
$lineal_distance;
    } 
ahora la función para pasar tiemezones class class TimeZoneTools

Código PHP:

    
/**
     * @see https://www.php.net/manual/en/datetimezone.listidentifiers.php
     * @note POO DateTimeZone::listIdentifiers(int $what = DateTimeZone::ALL, string $country = null): array
     * @note Procedural style
     * timezone_identifiers_list(int $timezoneGroup = DateTimeZone::ALL, string|null $countryCode = null): array
     * @NOTE 8.0.0 Returns the array OR false was returned on failure.
     */
    
public static function loadByCountry() : ? array
    {
        
/** el valor AR es para ejemplo, se obtiene de otra forma */
        
return DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY'AR');

    }

    public static function 
establishByProximity()
    {
        
$listed self::loadByCountry();
        
$data = [];
        
$one = [];
        
$lat1 = -34.818039/* esto para ejemplo */
        
$long1 = -58.3507293/* esto para ejemplo */
        
foreach ($listed as $key => $zone) {
            
$tz = new DateTimeZone($zone);
            
$loc $tz->getLocation();
            
$data [] = ['lat2' => $loc['latitude'], 'long2' => $loc['longitude']] ;
        foreach (
$data as $set) {
            
$one [] = [$zone => GeoTools::linealDistance($lat1$long1$set['lat2'], $set['long2'], 1false)];
        }
        }
        return 
print_r(min($one));
    } 
esto return print_r(min($one)); deberia darme la zona mas proxima pero me arroja la mas lejana :(
si cambio a return print_r(max($one)); funciona me da la mas proxima...

que diablos pasa??? jajajaja
__________________
Es duro fracasar en algo, pero es mucho peor no haberlo intentado. - Si crees todo lo que lees, mejor no leas -