从Google Maps .getBounds中获取MySQL数据库中的所有记录?

问题描述 投票:17回答:10

好吧我有一个大约1800行的数据库,每个都有一个列latlong,我正在尝试做什么,它查询谷歌地图V3 .getBounds结果是像((33.564398518424134, -79.38014701875002), (35.375726155241175, -76.08424858125002))我想做什么,是得到每个记录的lat &lng在数据库中是在这些范围内。有什么建议?

我想我将不得不推断地图的其他两个角,因为.getBounds只包含2个点(我想的地图的两个角),我想要在4个点内。如果我这样做,我会得到一个类似的数组...现在纠正我,如果我错了,但这应该是地图的NW,NE,SW,SE角落,在lat-lng。

33.564398518424134, -79.38014701875002
33.564398518424134, -76.08424858125002
35.375726155241175, -79.38014701875002
35.375726155241175, -76.08424858125002

好的,那么如果我有这些数据,我将如何构建查询以获取这些坐标内的行?表名为tilistings - 列是latlng ...如果有更简单的方法,或者我对我的方法感到疯狂,请随时告诉我。

谢谢

php mysql google-maps
10个回答
16
投票

如果来自谷歌:((a,b),(c,d))

SELECT * FROM tilistings WHERE lat > a AND lat < c AND lng > b AND lng < d


0
投票

从我的要点https://gist.github.com/jesuGMZ/0d7f38d80e2f67d0bc4b7fb620345344

让MySQL> 5.7的表格包含一个名为location的列类型POINT以及以下Google地图响应:

"geometry": {
    "bounds": {
        "northeast": {
            "lat": 40.5638447,
            "lng": -3.5249115
        },
        "southwest": {
            "lat": 40.3120639,
            "lng": -3.8341618
        }
    },
    //....

您可以执行SQL查询以检索包含在该边界中的所有位置,如下所示:

SELECT * FROM my_table
WHERE Contains(
  ST_MakeEnvelope(
    ST_GeomFromText('POINT(40.5638447 -3.5249115)'),
    ST_GeomFromText('POINT(40.3120639 -3.8341618)')
  ),
  location
);

如果适用,请考虑索引位置以提高查询的性能。此外,可以使用Within而不是Contains来改变参数的顺序。

有用的链接:


31
投票

以前的所有答案仅适用于1/4的世界!

W3t Tr3y的答案很接近,但它有一个错误(额外的“<”)。

所有这些只适用于美国,因为它位于北半球。它们不适用于南半球,也不适用于东部国家(格林威治权)。

这是一个没有功能或复杂内容的简单解决方案。

字母是从map.getBounds()获得它们的顺序的结果,即swlat,swlng,nelat,nelng = a,b,c,d。

SELECT * FROM tilistings WHERE
(CASE WHEN a < c
        THEN lat BETWEEN a AND c
        ELSE lat BETWEEN c AND a
END) 
AND
(CASE WHEN b < d
        THEN lng BETWEEN b AND d
        ELSE lng BETWEEN d AND b
END) 

或其他解决方案和/或(你可以测试它的速度,我不知道如何在WorkBench中多次运行它)

SELECT * FROM tilistings WHERE
(a < c AND lat BETWEEN a AND c) OR (c < a AND lat BETWEEN c AND a)
AND 
(b < d AND lng BETWEEN b AND d) OR (d < b AND lng BETWEEN d AND b)

现在你可以映射整个世界:)我希望有人可以将上述答案标记为不正确,因为它们让我们失去了很多像我一样的数百万学习者的时间。我不知道当他们真的不工作时他们会得到这么多的选票!

PS:你的地图像素边缘与坐标的精确15位小数值匹配的几率是错过整个3/4世界的几率的几万亿倍!


4
投票

我没有使用谷歌的API,但我的理解是,如果你从getBounds调用中获得((33.564398518424134, -79.38014701875002), (35.375726155241175, -76.08424858125002)),那么(33.564398518424134,-79.38014701875002)是西南角,(35.375726155241175,-76.08424858125002)是东北。我说,因为我认为他们返回东北角和西南角,我假设这些点是纬度,经度。

如果这是正确的,那么Bensiu的查询将起作用。通常使用BETWEEN更有效。

SELECT * FROM tilistings WHERE lat BETWEEN a AND c AND lng between b AND  d

3
投票

我现在要评论迟到,但也许对某人有用。 sergio unswer不太正确,对于整个世界的查询必须看起来有点不同,如果我没有弄错像这样的东西:

SELECT * FROM tilistings WHERE (sw_lat < ne_lat AND lat BETWEEN sw_lat AND ne_lat) OR (sw_lat > ne_lat AND (lat BETWEEN sw_lat AND 180 OR lat BETWEEN -180 AND ne_lat)) (sw_lon < ne_lon AND lon BETWEEN sw_lon AND ne_lon) OR (sw_lon > ne_lon AND (lon BETWEEN sw_lon AND 180 OR lon BETWEEN -180 AND ne_lon))


2
投票

弗拉基米尔答案的略微简化版本对我来说非常合适。

采取由南边(南),西边(西边),北边(北边)和东边(东边)的方框区域。这些可以从提供西南角和东北角的Google Map .getBounds派生 - 您只需要两个角,因为它们完全描述了方形边界框。

在此示例中,我们的数据库表称为位置,包含纬度和经度列。

SELECT * FROM locations WHERE
(latitude BETWEEN south AND north) AND
((west < east AND longitude BETWEEN west AND east) OR
 (west > east AND (longitude BETWEEN west AND 180 OR longitude BETWEEN -180 AND east)))

这是基于这样一个事实,即我们只需考虑穿越180 / -180经度线作为一种特殊情况 - 即西经的价值高于东经。在任何我们不跨越该线的情况下,西经将总是小于东经。

关于纬度,南边缘将总是比北纬度更低的值,因为没有围绕杆子缠绕的概念。为了覆盖北极上方的区域,例如我们只有所有经度(即从-180到180)和从南边界到+90的纬度。


1
投票

这对我有用:

$condition1 = $a < $c ? "lat > $a AND lat < $c" : "lat > $a OR lat < $c";
$condition2 = $b < $d ? "lon > $b AND lon < $d" : "lon > $d OR lon < $b";
$q = "SELECT * FROM tilistings WHERE ( $condition1 ) AND ( $condition2 )";

1
投票

我们可以使用下面的查询在Maps.getBounds northEast和southWest纬度以及northEast和southWest经度之间找到结果。

搜索查询应该在northEast.latitude和southWest.latitude之间以及northEast.longitude和southWest.longitude之间

$nelat=$_GET['nelat']-0.5;
$nelng=$_GET['nelng']-0.5;
$swlat=$_GET['swlat']-0.5;
$swlng=$_GET['swlng']-0.5;

$sql ="SELECT * FROM tablename where (CASE WHEN ".$nelat." < ".$swlat."
    THEN s.latitude BETWEEN ".$nelat." AND ".$swlat."
    ELSE s.latitude BETWEEN ".$swlat." AND ".$nelat."
END) 
AND
(CASE WHEN ".$nelng." < ".$swlng."
        THEN s.longitude BETWEEN ".$nelng." AND ".$swlng."
        ELSE s.longitude BETWEEN ".$swlng." AND ".$nelng."
END)";

1
投票

看看MySQL 5.7中现有的新空间数据和功能,现在也用于InnoDB。

使用上面的示例,对于具有1 mio记录的表,获取某个边界框内的位置需要大约1秒。

使用ST_Within()和ST_MakeEnvelope()以及正确的空间索引,我得到的结果少于0.01s。


0
投票

我不确定上述说法是否正确。首先,我认为角落是nelat,nelng,swlat,swlng,而不是如上所述“swlat,swlng,nwlat,nwlng”。其次我相信nelat总是高于窗口的swlat(除非窗口覆盖了一个地理极点,我不确定甚至可以用谷歌地图)。

最后,如果窗口覆盖国际日期线(约+/- 180lng),即d <b,那么它肯定应该是“不在b和d之间”。也许拥有更多专业知识的人可以证实?

© www.soinside.com 2019 - 2024. All rights reserved.