列出用户位置附近的地理位置

发布于 2024-10-13 21:42:57 字数 752 浏览 3 评论 0原文

我有一个 php web 应用程序,允许人们通过 google 地图 api (v3) 插入他们的位置。然后我将纬度/经度坐标存储到我的数据库中。

我做的另一件事是允许人们将某些事件添加到数据库中,然后我使用与用户相同的纬度/经度将事件插入到我的数据库中。例如:

用户表:

ID    U_Name    U_Location_ID
1     test      23

事件表:

ID    E_Name    E_Location_ID
1     testevent 23

位置表:

ID    L_LAT        L_LNG        L_Name
23    40.759139    -73.979723   30 Rockefeller Plaza, New York, NY 10112, USA

我现在想做的是向用户显示靠近他的位置的事件列表。

我不一定有他的确切位置,但通常只有国家和城市(并非所有访问者都是填写其确切位置的注册会员)。

因此,当会员访问时,我使用 ip 来定位 api,为我提供他的国家/地区名称和城市名称。我有另一种获取国家/城市纬度/经度坐标的方法,但现在当我需要显示该城市/国家附近的事件时我陷入困境。

当我说“附近”时,我希望可以设置某种以公里或英里为单位的直径,并列出该直径内的事件。

感谢您的帮助

I have a php webapp that allows people to insert their location via google maps api (v3). I then store the lat/lng coordinates to my db.

Another thing I do is allow people to add certain events to a database, I then insert the event to my db with the same lat/lng of the user. for example:

Users table:

ID    U_Name    U_Location_ID
1     test      23

Events table:

ID    E_Name    E_Location_ID
1     testevent 23

Location table:

ID    L_LAT        L_LNG        L_Name
23    40.759139    -73.979723   30 Rockefeller Plaza, New York, NY 10112, USA

What I'm trying to do now, is to display a user with a list of events that are near his location.

I don't necessarily have his exact location, but usually just the country and city (not all visitors are registered members that filled in their exact location).

So when a member vists, I use an ip to location api that gives me his country name and city name. I have another way of getting the country/city lat/lng coordinates, but now I'm stuck when I need to display the near events to that city/country.

When I say 'near' I hope it's possible to set some sort of diameter in Kilometers or Miles and list the events that are within that diameter.

Thanks for your help

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

裂开嘴轻声笑有多痛 2024-10-20 21:42:57

这是 MySQL 中适用于每个表的完整查询。请记住,纬度/经度字段必须是小数字段,除非您会失去精度:

-- set your vars
SET @lat := $$$;
SET @lon := $$$;
SET @dist := $$$;

-- prepare a square in miles
SET @x1 := @lon - @dist / ABS(COS(RADIANS(@lat))*69);
SET @x2 := @lon + @dist / ABS(COS(RADIANS(@lat))*69);
SET @y1 := @lat - (@dist / 69);
SET @y2 := @lat + (@dist / 69);

SELECT  t.*, 
        3956 * 2 * ASIN(
            SQRT(
                POWER(
                    SIN(
                        (@lat - t.lat) * pi() / 180 / 2
                    ), 2
                ) +
                COS(
                    @lat * pi() / 180
                ) *
                COS(
                    t.lat * pi() / 180
                ) *
                POWER(
                    SIN(
                        (@lon - t.lon) * pi() / 180 / 2
                    ), 2
                )
            )
        ) as distance
FROM    `YourTable` t
WHERE   t.longitude BETWEEN @x1 AND @x2
AND     t.latitude BETWEEN @y1 AND @y2
HAVING  distance < @dist
ORDER BY distance
LIMIT 10;

您只需将 $$$$$ 替换为您的值。
现在,如果您想要完整的解释,请参阅 Alexander Rubin 的幻灯片< /a>

对于公里,只需将 x1, x2 ... 替换为

-- prepare a square or in kilometers
SET @x1 := @lon - @dist / ABS(COS(RADIANS(@lat))*110);
SET @x2 := @lon + @dist / ABS(COS(RADIANS(@lat))*110);
SET @y1 := @lat - (@dist / 110);
SET @y2 := @lat + (@dist / 110);

Here the full query in MySQL that works on every tables. Keep in mind that the lat / lon fields must be decimal fields, unless you will loose precision :

-- set your vars
SET @lat := $$$;
SET @lon := $$$;
SET @dist := $$$;

-- prepare a square in miles
SET @x1 := @lon - @dist / ABS(COS(RADIANS(@lat))*69);
SET @x2 := @lon + @dist / ABS(COS(RADIANS(@lat))*69);
SET @y1 := @lat - (@dist / 69);
SET @y2 := @lat + (@dist / 69);

SELECT  t.*, 
        3956 * 2 * ASIN(
            SQRT(
                POWER(
                    SIN(
                        (@lat - t.lat) * pi() / 180 / 2
                    ), 2
                ) +
                COS(
                    @lat * pi() / 180
                ) *
                COS(
                    t.lat * pi() / 180
                ) *
                POWER(
                    SIN(
                        (@lon - t.lon) * pi() / 180 / 2
                    ), 2
                )
            )
        ) as distance
FROM    `YourTable` t
WHERE   t.longitude BETWEEN @x1 AND @x2
AND     t.latitude BETWEEN @y1 AND @y2
HAVING  distance < @dist
ORDER BY distance
LIMIT 10;

You just need to replace the $$$$$ with your values.
Now if you want a full explanation, see this slides by Alexander Rubin

And for kilometers, just replace the x1, x2 ... by

-- prepare a square or in kilometers
SET @x1 := @lon - @dist / ABS(COS(RADIANS(@lat))*110);
SET @x2 := @lon + @dist / ABS(COS(RADIANS(@lat))*110);
SET @y1 := @lat - (@dist / 110);
SET @y2 := @lat + (@dist / 110);
丶情人眼里出诗心の 2024-10-20 21:42:57

重要的是要注意,如果您采用 Xavier 的精彩答案 - 并且 - 如果您使用他的公里数更改,您还必须在计算中将 3956 * 2 更改为 6371 * 2 ,否则您只是更改范围,而不是更改产生的距离。

Its important to note that if you go with the wonderful answer by Xavier --and-- if you use his kilometers change you must also change 3956 * 2 to 6371 * 2 in the calculation or you're just changing the range, not the produced distance.

十雾 2024-10-20 21:42:57

我不太明白你的问题。如果您使用像 MaxMind 这样的地理定位数据库,您还可以获得每个城市的纬度/经度。您只需选择一些经度和纬度的增量,运行 SQL 查询并在视图中计算从用户位置到事件位置的距离。其实并不复杂。

I'm not really understanding your problem. If you are using geolocation DB like MaxMind, you also get to every city a latitude/longititude. You just have to choose some delta for longitude and latitude, run the SQL query and calculate in your view the distance from the users location to the event location. It's not really complicated.

旧城空念 2024-10-20 21:42:57

您知道 mysql 空间扩展吗?

Are you aware of mysql spatial extensions?

┊风居住的梦幻卍 2024-10-20 21:42:57

这是一个查询,可以帮助您获取特定直径内的所有位置。 {NUMBER OF KILOMETERS} 将是直径。 $lon AND $lat 将赌注用户位置的坐标。

<代码>
选择
D.*,
度(acos(cos(半径(90-纬度))*cos(半径(90-$lat))+sin(半径(90-纬度))*sin (半径(90-$lat))*cos(半径(经度-$lon))))/360*40074
作为
距离

location_tableD
拥有
距离 <= {NUMBER OF KILOMETERS}

Here is a query wich could help you get all locations within a certain diameter. {NUMBER OF KILOMETERS} will be the diameter. $lon AND $lat will bet the coordinates of the users' location.


SELECT
D.*,
DEGREES(acos(cos(RADIANS(90-latitude))*cos(RADIANS(90-$lat))+sin(RADIANS(90-latitude))*sin(RADIANS(90-$lat))*cos(RADIANS(longitude-$lon))))/360*40074
AS
distance
FROM
location_table as D
HAVING
distance <= {NUMBER OF KILOMETERS}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文