Mysql 我上面提到的ZipData class ZipData(models.Model): zipcode = ZipCodeField(null=False, blank=False, verbose_name="ZipCode", primary_key=True) city = models.CharField(max_length=32, null=False, blank=False) state = models.CharField(max_length=2) lat = models.FloatField(null=False, blank=False) lng = models.FloatField(null=False, blank=False)

Mysql 我上面提到的ZipData class ZipData(models.Model): zipcode = ZipCodeField(null=False, blank=False, verbose_name="ZipCode", primary_key=True) city = models.CharField(max_length=32, null=False, blank=False) state = models.CharField(max_length=2) lat = models.FloatField(null=False, blank=False) lng = models.FloatField(null=False, blank=False),mysql,gis,coordinates,distance,coordinate-systems,Mysql,Gis,Coordinates,Distance,Coordinate Systems,另外一点需要注意的是,您可以在获取大量与邮政编码相关的地理数据,他们甚至还有一些您也可以使用的webservice API。您可以自己派生函数。。。这看起来像是高中水平的微积分,如果你真的简化它,甚至可能是三角积分……你会这么认为,但地球并不是一个完美的球体,赤道1度经度和其他地方1度经度之间的差异惊人地大。这绝对不是人们希望的那么简单!(见下面我的答案:)@Mike,你不能仅仅添加一个标量距离来获得一个新的经度和纬度。由于地球的曲率,您还需要指定角度。你说你想找到X公里的城市,我的解决方案就是

另外一点需要注意的是,您可以在获取大量与邮政编码相关的地理数据,他们甚至还有一些您也可以使用的webservice API。

您可以自己派生函数。。。这看起来像是高中水平的微积分,如果你真的简化它,甚至可能是三角积分……你会这么认为,但地球并不是一个完美的球体,赤道1度经度和其他地方1度经度之间的差异惊人地大。这绝对不是人们希望的那么简单!(见下面我的答案:)@Mike,你不能仅仅添加一个标量距离来获得一个新的经度和纬度。由于地球的曲率,您还需要指定角度。你说你想找到X公里的城市,我的解决方案就是这样。地球的半径不是恒定的——这会让你离得很近,但(至少在我之前的应用中)距离不够近。如果你不担心几英里(最多几百英里)的差异,这将是一个很好的方法:)这基本上就是我建议他导出的函数。我认为地球微小的非球面在任何合理的距离上都无关紧要。。。IIRC,两极之间的距离和穿过赤道的距离相差50英里,这在地球上算不上什么。但是,在计算地表位置时,这会产生很大的差异。如果你不介意我问基思,你在这个查询中的索引设置是为了什么?这很好,但是它使用Lat/LongHey Mike上的键扫描数据库中的每一行。如果性能重要,我在“纬度”上设置了一个索引,在“经度”上设置了一个索引,我通过使用BETWEEN子句来调整上述查询,将查询限制在较小的记录子集上。添加如下内容:其中纬度介于$latitude-($radius/70)和$latitude+($radius/70)之间,经度介于$longitude-($radius/70)和$longitude+($radius/70)之间。。。这允许数据库使用纬度和经度的索引。常数70是因为1度纬度或经度所跨越的最大距离约为70英里。在我们的aging development服务器上,有一个包含全球290万个城市/城镇的表,查询时间从:无纬度/经度索引:10.9秒,有纬度/经度索引:0.52秒使用空间索引快速定位附近的城市。这类工作比普通索引快得多。嘿,基思,我错过了这篇文章(因为看到了我使用的原始答案——非常有效)。我们的数据库现在有大约2.8个mill记录,并且回来添加了这个:$longitude_rectangle1=$longitude-$distance/abs(cos(deg2rad($latitude))*69)$经度矩形2=$经度+$距离/abs(cos(deg2rad($纬度))*69)$纬度\矩形1=$纬度-($距离/69)$纬度\矩形2=$纬度+($距离/69);我在中间层使用了这些功能-它看起来正确吗?对于短距离来说,这会很好,但我们的星球与您链接的页面顶部的距离并不平坦:目前,MySQL没有按照规范实现这些功能。那些被实现的函数返回与相应的基于MBR的函数相同的结果。这包括以下列表中除Distance()和Related()以外的函数。@Mark0978该页面确实包含该免责声明,但在我的回答中,我建议使用
Distance
函数。您在评论中引用的免责声明不适用于距离功能。因此,免责声明与我的回答无关。这是一个伟大的标记0978。你有完整的代码或django应用程序可以作为即插即用模块共享吗?我现在已经包括了模型对象。你可以给我发电子邮件,我的用户名@ gmail网站,我会给你的文件组成的应用程序,但我不认为他们是一个可重复使用的应用程序。
ALTER FUNCTION [dbo].[DistanceBetween] (@Lat1 as real,
                @Long1 as real, @Lat2 as real, @Long2 as real)
RETURNS real
AS
BEGIN

DECLARE @dLat1InRad as float(53);
SET @dLat1InRad = @Lat1 * (PI()/180.0);
DECLARE @dLong1InRad as float(53);
SET @dLong1InRad = @Long1 * (PI()/180.0);
DECLARE @dLat2InRad as float(53);
SET @dLat2InRad = @Lat2 * (PI()/180.0);
DECLARE @dLong2InRad as float(53);
SET @dLong2InRad = @Long2 * (PI()/180.0);

DECLARE @dLongitude as float(53);
SET @dLongitude = @dLong2InRad - @dLong1InRad;
DECLARE @dLatitude as float(53);
SET @dLatitude = @dLat2InRad - @dLat1InRad;
/* Intermediate result a. */
DECLARE @a as float(53);
SET @a = SQUARE (SIN (@dLatitude / 2.0)) + COS (@dLat1InRad)
                 * COS (@dLat2InRad)
                 * SQUARE(SIN (@dLongitude / 2.0));
/* Intermediate result c (great circle distance in Radians). */
DECLARE @c as real;
SET @c = 2.0 * ATN2 (SQRT (@a), SQRT (1.0 - @a));
DECLARE @kEarthRadius as real;
/* SET kEarthRadius = 3956.0 miles */
SET @kEarthRadius = 6376.5;        /* kms */

DECLARE @dDistance as real;
SET @dDistance = @kEarthRadius * @c;
return (@dDistance);
END
SQRT( POW(Alpha_lat - Beta_lat,2) + POW(Alpha_lon - Beta_lon,2) )
$res = mysql_query("SELECT
    * 
FROM
    your_table
WHERE
    (
        (69.1 * (latitude - " . $latitude . ")) * 
        (69.1 * (latitude - " . $latitude . "))
    ) + ( 
        (69.1 * (longitude - " . $longitude . ") * COS(" . $latitude . " / 57.3)) * 
        (69.1 * (longitude - " . $longitude . ") * COS(" . $latitude . " / 57.3))
    ) < " . pow($radius, 2) . " 
ORDER BY 
    (
        (69.1 * (latitude - " . $latitude . ")) * 
        (69.1 * (latitude - " . $latitude . "))
    ) + ( 
        (69.1 * (longitude - " . $longitude . ") * COS(" . $latitude . " / 57.3)) * 
        (69.1 * (longitude - " . $longitude . ") * COS(" . $latitude . " / 57.3))
    ) ASC");
function getRadius($point="POINT(-29.8368 30.9096)", $radius=2)
{
    $km = 0.009;
    $center = "GeomFromText('$point')";
    $radius = $radius*$km;
    $bbox = "CONCAT('POLYGON((',
        X($center) - $radius, ' ', Y($center) - $radius, ',',
        X($center) + $radius, ' ', Y($center) - $radius, ',',
        X($center) + $radius, ' ', Y($center) + $radius, ',',
        X($center) - $radius, ' ', Y($center) + $radius, ',',
        X($center) - $radius, ' ', Y($center) - $radius, '
    ))')";

    $query = $this->db->query("
    SELECT id, AsText(latLng) AS latLng, (SQRT(POW( ABS( X(latLng) - X({$center})), 2) + POW( ABS(Y(latLng) - Y({$center})), 2 )))/0.009 AS distance
    FROM crime_listing
    WHERE Intersects( latLng, GeomFromText($bbox) )
    AND SQRT(POW( ABS( X(latLng) - X({$center})), 2) + POW( ABS(Y(latLng) - Y({$center})), 2 )) < $radius
    ORDER BY distance
        ");

    if($query->num_rows()>0){
        return($query->result());
    }else{
        return false;
    }
}
ra = 3963.1906 # radius @ equator in miles, change to km  if you want distance in km
rb = 3949.90275  # radius @ poles in miles, change to km  if you want distance in km
ra2 = ra * ra
rb2 = rb * rb

phi = self.lat

big_ol_constant = (math.pow(ra2*math.cos(phi), 2) + pow(rb2*math.sin(phi), 2))/ (pow(ra*math.cos(phi), 2) + pow(rb*math.sin(phi), 2))

sqlWhere = "%(distance)g > sqrt((power(lat - %(lat)g,2) + power(lng-%(lng)g,2)) * %(big_ol_constant)g)" % {
    'big_ol_constant': big_ol_constant, 'lat': self.lat, 'lng': self.lng, 'distance': distance}

# This is the Django portion of it, where the ORM kicks in.  sqlWhere is what you would put after the WHERE part of your SQL Query.
qs = ZipData.objects.extra(where=[sqlWhere]);
class ZipData(models.Model):
    zipcode = ZipCodeField(null=False, blank=False, verbose_name="ZipCode", primary_key=True)
    city = models.CharField(max_length=32, null=False, blank=False)
    state = models.CharField(max_length=2)
    lat = models.FloatField(null=False, blank=False)
    lng = models.FloatField(null=False, blank=False)