Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
查询SQL数据库如何获取用户位置附近的最近点?_Sql_Database_Postgresql_Position_Location - Fatal编程技术网

查询SQL数据库如何获取用户位置附近的最近点?

查询SQL数据库如何获取用户位置附近的最近点?,sql,database,postgresql,position,location,Sql,Database,Postgresql,Position,Location,在过去的一个Java项目中,我编写了以下代码,以获取到所提供位置(50公里以内)的最近点: //用户位置 双myLatG=myLat*Math.PI/180; double myLonG=myLon*Math.PI/180; //包含所有点的sqlite数据库上的循环 while(cur.moveToNext()){ double destrang=cur.getDouble(0)*Math.PI/180; double destLonG=cur.getDouble(1)*Math.PI/180

在过去的一个Java项目中,我编写了以下代码,以获取到所提供位置(50公里以内)的最近点:

//用户位置
双myLatG=myLat*Math.PI/180;
double myLonG=myLon*Math.PI/180;
//包含所有点的sqlite数据库上的循环
while(cur.moveToNext()){
double destrang=cur.getDouble(0)*Math.PI/180;
double destLonG=cur.getDouble(1)*Math.PI/180;
双φ=数学绝对值(myLonG-destLonG);
双距离=(Math.acos(Math.cos(phi)*Math.cos(myLatG)*Math.cos(destrat)+Math.sin(myLatG)*Math.sin(destrat))*6387;
如果(距离您可以尝试

SELECT lat, lon 
FROM 
(
   SELECT lat, 
          lon, 
          frml(lat, lon, :mylat, :mylon) AS distance, 
   FROM table_all_points
) distance_table
WHERE distance <= 50
您可以在postgres中使用的数学函数如下所示:


如果您不想使用单行公式,您可以在表之间添加另一行公式,但我不确定是否更有效。

在PostgreSQL中,您可以使用PostGIS扩展。PostGIS提供两种数据类型,其中
地理数据类型正是您需要的。在这种类型的列中,您可以存储(经度、纬度)WGS84球体上的坐标(正是您需要的,查看您的地球半径6387公里)

似乎您有一个特定的位置
(myLon,myLat)
,您希望在表中查找50公里以内的所有点。在PostGIS中,这很容易:

SELECT *
FROM table_with_points t
WHERE ST_DWithin(
         ST_GeogFromText('SRID=4326;POINT(' || myLon || ' ' || myLat || ')'),
         ST_GeogFromText('SRID=4326;POINT(' || t.lon || ' ' || t.lat || ')'),
         50000);
这将以米为单位计算WGS84球体上的大圆弧距离,即乌鸦飞行时的距离

如果选择此选项,您可能希望在表中使用
地理
列,这样您只需输入列名,就可以忘记第二个
ST_GeogFromText()
调用。

我解决了这个问题。它显示了与提供的坐标最近的点(在50公里内)。它工作得非常完美:

SELECT m.name,
    m.lat, m.lon,
    p.distance_unit
             * DEGREES(ACOS(COS(RADIANS(p.latpoint))
             * COS(RADIANS(m.lat))
             * COS(RADIANS(p.longpoint) - RADIANS(m.lon))
             + SIN(RADIANS(p.latpoint))
             * SIN(RADIANS(m.lat)))) AS distance_in_km
FROM <table_name> AS m
JOIN (
      SELECT <userLat> AS latpoint, <userLon> AS longpoint,
             50.0 AS radius, 111.045 AS distance_unit
     ) AS p ON 1=1
WHERE m.lat
BETWEEN p.latpoint  - (p.radius / p.distance_unit)
    AND p.latpoint  + (p.radius / p.distance_unit)
    AND m.lon BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
    AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
ORDER BY distance_in_km
选择m.name,
m、 拉特,m.lon,
p、 距离单位
*度(ACOS(COS)(弧度(p.latpoint))
*COS(弧度(m.lat))
*COS(弧度(p.longpoint)-弧度(m.lon))
+SIN(弧度(p.latpoint))
*SIN(弧度(m.lat)))表示距离(单位:km)
从AS m
加入(
选择作为latpoint,作为longpoint,
50.0为半径,111.045为距离单位
)当p在1=1时
拉特先生在哪里
p.latpoint之间-(p.radius/p.distance_单位)
和p.latpoint+(p.radius/p.distance_单位)
p.longpoint-(p.radius/(p.distance_unit*COS(弧度(p.latpoint)))之间的m.lon
和p.longpoint+(p.radius/(p.distance_unit*COS(弧度(p.latpoint)))
按距离(单位:公里)订购

只需更改

我使用了您的代码,但它不起作用。
需要做什么?另外,什么是
距离表
?它是别名吗?我试图将
添加为
但它无论如何都不起作用距离表应该是表的名称,也许您可以简单地忽略它。@sho谢谢你的解决方案,但我无法安装PostGIS扩展。
SELECT *
FROM table_with_points t
WHERE ST_DWithin(
         ST_GeogFromText('SRID=4326;POINT(' || myLon || ' ' || myLat || ')'),
         ST_GeogFromText('SRID=4326;POINT(' || t.lon || ' ' || t.lat || ')'),
         50000);
SELECT m.name,
    m.lat, m.lon,
    p.distance_unit
             * DEGREES(ACOS(COS(RADIANS(p.latpoint))
             * COS(RADIANS(m.lat))
             * COS(RADIANS(p.longpoint) - RADIANS(m.lon))
             + SIN(RADIANS(p.latpoint))
             * SIN(RADIANS(m.lat)))) AS distance_in_km
FROM <table_name> AS m
JOIN (
      SELECT <userLat> AS latpoint, <userLon> AS longpoint,
             50.0 AS radius, 111.045 AS distance_unit
     ) AS p ON 1=1
WHERE m.lat
BETWEEN p.latpoint  - (p.radius / p.distance_unit)
    AND p.latpoint  + (p.radius / p.distance_unit)
    AND m.lon BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
    AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
ORDER BY distance_in_km