mySQL select zipcodes within x km/miles within range of y

前端 未结 3 712
名媛妹妹
名媛妹妹 2020-12-17 07:11

Note: Although I use a zipcode database with Dutch zipcodes, this question is country independent.

I have a database with every zipcode in the Netherlands +

相关标签:
3条回答
  • 2020-12-17 07:46

    You want to do something like this:

    SELECT zipcode FROM zipcodes WHERE DistanceFormula(lat, long, 4.808855, 52.406332) < $range

    It may be slow if your table of zip codes is large. You may also want to check out the geospatial extensions for MySQL.

    0 讨论(0)
  • 2020-12-17 07:46

    You have to use something called the Haversine formula:

    $sql = "
        SELECT zipcode
        FROM zipcodes
        WHERE ".mysqlHaversine($lat, $lon, $distance)."
    ";
    

    And the formula:

    function mysqlHaversine($lat = 0, $lon = 0, $distance = 0)
    {
        if($distance > 0)
        {
            return ('
            ((6372.797 * (2 *
            ATAN2(
                SQRT(
                    SIN(('.($lat*1).' * (PI()/180)-latitude*(PI()/180))/2) *
                    SIN(('.($lat*1).' * (PI()/180)-latitude*(PI()/180))/2) +
                    COS(latitude * (PI()/180)) *
                    COS('.($lat*1).' * (PI()/180)) *
                    SIN(('.($lon*1).' * (PI()/180)-longitude*(PI()/180))/2) *
                    SIN(('.($lon*1).' * (PI()/180)-longitude*(PI()/180))/2)
                    ),
                SQRT(1-(
                    SIN(('.($lat*1).' * (PI()/180)-latitude*(PI()/180))/2) *
                    SIN(('.($lat*1).' * (PI()/180)-latitude*(PI()/180))/2) +
                    COS(latitude * (PI()/180)) *
                    COS('.($lat*1).' * (PI()/180)) *
                    SIN(('.($lon*1).' * (PI()/180)-longitude*(PI()/180))/2) *
                    SIN(('.($lon*1).' * (PI()/180)-longitude*(PI()/180))/2)
                ))
            )
            )) <= '.($distance/1000). ')');
        }
    
        return '';
    }
    

    Usually I do not use code without understanding the way it works first, but I must confess this function is a little bit over my head...

    0 讨论(0)
  • 2020-12-17 07:54

    While Captaintokyo's method is accurate, it's also fairly slow. I can't help but think it'd be more advantageous to use a temporary table of all zipcodes whose boundaries are within the range, then to refine those results by distance.

    0 讨论(0)
提交回复
热议问题