php / mysql posta kodu yakınlık arama

7 Cevap php

Ben sadece bunu yapmak için en iyi yolu önerileri arıyorum ...

Ben bir posta kodu 50 kilometre yarıçapı içinde "kullanıcılar" için arama yapan bir arama işlevi oluşturmak gerekir. Ben onların enlem / boylam ile tüm ABD posta kodları içeren bir posta kodu tablo var ama sadece benim veri yapısı ve sorgulamak için en iyi şekilde anlamaya çalışıyorum ...

Ben Kullanıcıların tabloya enlem / boylam sütunları ekleme ve verilen posta kodu yarıçapı içindeki tüm kullanıcılar için bunu sorgulamak gerekir? Ya sonra sonuçlar (zip kodları) ile tüm kullanıcılar için kullanıcılar tablosunu sorgulamak yarıçap içinde kalan tüm zip kodları için zip kodları tablosunu sorgulamak gerekir? Ya da ...?? Ben bu noktada herhangi bir önerileri açık!

Teşekkürler!

7 Cevap

Burada özellikli yakınlık arama check out:

Using PHP/MySQL with Google Maps

Veri (yani ne olursa olsun denir) aynı notasyonu / projeksiyon / biçimi ise, sizin için çalışabilir.

Burada bulunan en iyi yoldur. Tabii ki sizin zipcodes tüm enlem / boylam veritabanında kodlanmış olması gerekir.

// get all the zipcodes within the specified radius - default 20
function zipcodeRadius($lat, $lon, $radius)
{
    $radius = $radius ? $radius : 20;
    $sql = 'SELECT distinct(ZipCode) FROM zipcode  WHERE (3958*3.1415926*sqrt((Latitude-'.$lat.')*(Latitude-'.$lat.') + cos(Latitude/57.29578)*cos('.$lat.'/57.29578)*(Longitude-'.$lon.')*(Longitude-'.$lon.'))/180) <= '.$radius.';';
    $result = $this->db->query($sql);
    // get each result
    $zipcodeList = array();
    while($row = $this->db->fetch_array($result))
    {
        array_push($zipcodeList, $row['ZipCode']);
    }
    return $zipcodeList;
}

Sadece bu işlev düşmesi gerekir. , O $ lat ve sizin için yarıçapı istediğiniz posta kodu dolarlık boylam geçmek isteğe yarıçapı içerir ve geri zipcodes bir listesini almak.

Zipcode IN (radius_sql) ve geri liste kullanıcıların nereden çok kolay bir şekilde tüm kullanıcıları almak için bu değiştirebilir.

Mutlu Kodlama!

http://www.micahcarrick.com/04-19-2005/php-zip-code-range-and-distance-calculation.html

Ben bu çok müthiş bulundu.

"Sonra sonuçları (zip kodları) ile tüm kullanıcılar için kullanıcılar tablosunu sorgulamak yarıçap içinde kalan tüm zip kodları için zip kodları tablosunu sorgulamak"

Ben bu bir google harita üzerinde kullanıcıların koymak gerekir sürece bunu yapmak için en iyi yoldur bulundu. Sadece kilometre aralığındaki kullanıcılara listeleyen ediyorsanız o zaman bu zipcodes tüm kullanıcıları seçmek fermuarlar listesi için (sınıfını kullanarak) veritabanını sorgulamak için oldukça kolay olmalıdır.

Select * from Users where zip_code IN (19125,19081,19107.........);

İşte bunu yapmak gerekir.

Buradan başlayın ama çözüm çok hızlı olmadığını unutmayın:

PHP Zip Code Range and Distance Calculation

Şimdi hızlı yapmak için - bir mekansal dizin kullanmak için arama yerine gidiyorlar :)

  1. MySQL kullanabilirsiniz

  2. Veritabanı denilen yere bir sütun ekleyin ve NOKTASI yazın yapmak

  3. Emin şu anda boş değerlere kabul olun

  4. Aşağıdaki SQL sorgusu çalıştırın

    UPDATE zip_code SET location = PointFromText(CONCAT('POINT(',lon,' ',lat,')'));

  5. Şimdi, sütun boş değerlere kabul etmez olun

  6. Konumu sütuna kayma dizin ekle

  7. Yukarıdaki proje kodu aşağıdaki ile işlevi 'get_zips_in_range' değiştirin:

    function get_zips_in_range($zip, $range, $sort=1, $include_base) 
         {
    
    
        // returns an array of the zip codes within $range of $zip. Returns
        // an array with keys as zip codes and values as the distance from
        // the zipcode defined in $zip.
    
        $this->chronometer();                     // start the clock
    
        $details = $this->get_zip_point($zip);  // base zip details
        if ($details == false) return false;
    
        // This portion of the routine  calculates the minimum and maximum lat and
        // long within a given range.  This portion of the code was written
        // by Jeff Bearer (http://www.jeffbearer.com). This significanly decreases
        // the time it takes to execute a query.  My demo took 3.2 seconds in
        // v1.0.0 and now executes in 0.4 seconds!  Greate job Jeff!
    
        // Find Max - Min Lat / Long for Radius and zero point and query
        // only zips in that range.
        $lat = $details[0];
        $lon = $details[1];
    
        $return = array();    // declared here for scope
    
        $first = true;
        $radius = $range/69.172;
        $boundary = "POLYGON((";
        for($i=0; $i <= 360; $i += 360/24)
        {
            if($first)
            {
                $first = false;
            }
            else
            {
                $boundary .= ', ';
            }
    
            $clon = $radius*cos(deg2rad($i)) + $lon;
            $clat = $radius*sin(deg2rad($i)) + $lat;
            $boundary .= "$clon $clat" ;
        }
    
        $boundary  .= '))';
    
        $sql = "SELECT zip_code, city, county, state_name, state_prefix, area_code, time_zone, lat, lon FROM zip_code WHERE MBRContains(GeomFromText('$boundary'), location);";
    
        //echo $sql;
        $r = mysql_query($sql);
    
        if (!$r) {    // sql error
    
            $this->last_error = mysql_error();
            return false;
    
        } else {
    
            while ($row = mysql_fetch_row($r)) {
    
                // loop through the results to get the milage from src
                $dist = $this->calculate_mileage($details[0],$row[7],$details[1],$row[8]);
                if ($this->units == _UNIT_KILOMETERS) $dist = $dist * _M2KM_FACTOR;
                $return[str_pad($row[0].', '.$row[1], 5, "0", STR_PAD_LEFT)] = round($dist, $this->decimals);
    
            }
            mysql_free_result($r);
        }
    
        // sort array
        switch($sort)
        {
            case _ZIPS_SORT_BY_DISTANCE_ASC:
                asort($return);
                break;
    
            case _ZIPS_SORT_BY_DISTANCE_DESC:
                arsort($return);
                break;
    
            case _ZIPS_SORT_BY_ZIP_ASC:
                ksort($return);
                break;
    
            case _ZIPS_SORT_BY_ZIP_DESC:
                krsort($return);
                break;
        }
    
        $this->last_time = $this->chronometer();
    
        if (empty($return)) return false;
        return $return;
       }
    

Ben ikinci bir adım olarak yarıçapı endişesi sonra, ilk bir sınırlayıcı kare ile adayların sayısını azaltarak düşünecektim. Siz posta kodu koordinatları ile başlamak, sonra basit daha büyük değere / kriterleri daha az kullanarak o kutunun içinde sadece adayları seçin, uzun / 4 yönde 50 kilometre lat hesaplar. Kullanıcı tabanı iyi yayılmış ise bu aday o zaman sadece "köşe" ortadan kaldırmak için vektör mesafe matematik yapmak zorundayız, önemli ölçüde set azaltır.

Enlem / boylam, her posta kodu için doğru, bu zip için bir coğrafi merkezi var? Öncelikle bu zip kodları, daha sonra 50 kilometre mesafede olan coğrafi merkezleri, kullanıcıların zip kodları bulmak Yani, kolayca fazla 50 km uzaklıkta kullanıcıların dönen olabilir. Yani bu şekilde yapıyor bazı doğruluğunu feda ederdim.

Eğer (zip kodları sayısından daha fazla), kullanıcıların bir sürü var ama eğer bu ilk küçük zip kodları tabloya karşı sorgu ediyorum, çünkü daha hızlı olacaktır. Ve bunu belirli bir posta kodu ile kullanıcıların hızlı olacak olan kullanıcıların tabloda indeks zip kodları, bulgu olabilir.

Sadece bazı düşünceler! Kullanıcıların bir çok şey bekliyor ve 50 kilometre yarıçapı tam olması gerekmez Yani, ben bu posta kodları içinde kullanıcılar, daha sonra, 50 kilometre mesafedeki posta kodları bulur.

Ben ilk hedefin yarıçapı tüm zipcodes için bir arama yapardı. Sonra kullanıcı tablo zipcodes tüm döndü zipcodes karşılaştırın. Eşleşen kullanıcıları çekin.

Bu bir yarıçap içinde zipcodes bulmak, bu MySQL çağrı bulundu:

$query = 'SELECT zzip FROM ' . table . 
            ' WHERE (POW((69.1*(zlongitude-"' . 
            $long . '")*cos(' . $long . 
            '/57.3)),"2")+POW((69.1*(zlatitude-"' . 
            $lat . '")),"2"))<(' . $radius . 
            '*' . $radius . ')';

MySQL sizin için tüm matematik yapar.

I found a class that uses this here: http://www.nucleusdevelopment.com/code/do/zipcode

Umut olur.