通过MySQL获取半径拉链时出现问题


9

我有一个邮政编码表,其中包括每个邮政编码的中心纬度,经度。我用它来获取从任意点到给定英里半径内的邮政编码列表。

在我看来,仅仅是因为拉链的中心点不在给定的半径内,并不意味着拉链本身不在半径内。

我用自己的超高级艺术技巧来说明这一点:

在此处输入图片说明

  • 绿色条纹斑点表示邮政编码A,B和C。

  • 红色污点是每个邮政编码的地理中心

  • 紫红色的点是目标位置,并且..

  • 块状蓝色圆圈距离目标位置1英里半径

如果我查询距离粉红色污迹1英里半径内的所有邮政编码,则将返回邮政编码B和C,因为邮政编码A的中心点不在1英里半径内,即使粉红色污迹本身显然在邮政编码A中。

SELECT *,
        p.distance_unit
                 * DEGREES(ACOS(COS(RADIANS(p.latpoint))
                 * COS(RADIANS(z.y))
                 * COS(RADIANS(p.longpoint) - RADIANS(z.x))
                 + SIN(RADIANS(p.latpoint))
                 * SIN(RADIANS(z.y)))) AS dist
  FROM standard_zip AS z
  JOIN (   /* these are the query parameters */
        SELECT  $lat  AS latpoint,  $lng AS longpoint,
                $miles AS radius,      69 AS distance_unit
    ) AS p ON 1=1
  WHERE z.y
     BETWEEN p.latpoint  - (p.radius / p.distance_unit)
         AND p.latpoint  + (p.radius / p.distance_unit)
    AND z.x
     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 dist

如何编写一个在结果中包含zip A的查询?

我可以访问需要添加到表中的每个邮政编码的空间/几何,但是我不知道如何在MySQL中将其用于此目的。


编辑:我花了一天的时间阅读Oracle和MySQL文档中的空间数据,并成功地将空间数据转换为MySQL。如何编写类似的查询,该查询使用geometry列而不是lat和long?我正在使用2D数据..几何仅是多边形和多多边形。

我想我已经解决了。

select
  *
from
  (
    select
      MIN(st_distance(geom, POINT(-82.765136, 28.0914015))) * 69 as miles,
      zip
    from
      zip_spatial
    group by
      zip
    order by
      miles asc
  ) d
where
  d.miles < 5

如果有人有更好,更有效的解决方案,我现在将悬赏金打开。

Answers:


7

从《Oracle®Spatial开发人员指南11g第2版(11.2)》中的Oracle中的空间数据索引和查询中

查询空间数据

Spatial使用具有主要和辅助过滤器操作的两层查询模型来解析空间查询和空间联接。术语两层表示执行两个不同的操作来解析查询。如果执行了两个操作,则返回精确的结果集。

如果在表中定义了空间索引,则不能在查询中的空间表名称后附加数据库链接(dblink)名称。

空间查询

在空间R树索引中,每个几何图形均由其最小边界矩形(MBR)表示。考虑图1中包含几个对象的下一层。每个对象都用其几何名称标记(线串为geom_1,四边形多边形为geom_2,三角形多边形为geom_3,椭圆为geom_4),每个对象周围的MBR用虚线表示。

图1具有MBR的几何

“图1具有MBR的几何”的描述

典型的空间查询是请求位于查询窗口(即定义的围栏或窗口)内的所有对象。动态查询窗口是指未在数据库中定义但必须在使用前定义的矩形区域。图2显示了与图1相同的几何形状,但是添加了一个由粗虚线框表示的查询窗口。

图2带有查询窗口的图层

“带有查询窗口的Figure2层”的描述

在图2中,查询窗口涵盖了几何geom_1和geom_2的部分,以及geom_3的MBR的一部分,但没有实际的geom_3几何。查询窗口不覆盖geom_4几何图形或其MBR的任何部分。

主过滤器运算符

SDO_FILTER运算符实现Oracle Spatial查询处理模型中涉及的两步过程的主要过滤器部分。主过滤器使用索引数据来确定仅一组候选对象对是否可以交互。具体来说,主过滤器检查候选对象的MBR是否交互,而不是对象本身是否交互。SDO_FILTER运算符的语法如下:

SDO_FILTER(geometry1 SDO_GEOMETRY, geometry2 SDO_GEOMETRY, param VARCHAR2)

在上述语法中:

  • geometry1是表中SDO_GEOMETRY类型的列。该列必须在空间上建立索引。

  • geometry2是SDO_GEOMETRY类型的对象。该对象可能来自表,也可能不来自表。如果来自表,则可能会或可能不会在空间上建立索引。

  • param是类型为VARCHAR2的可选字符串。它可以指定min_resolution和max_resolution关键字之一或全部。

以下示例仅执行一次过滤操作(不执行二次过滤操作)。它们将返回图2所示的所有具有与查询窗口交互的MBR的几何。以下示例的结果是几何geom_1,geom_2和geom_3。

Example1在不将查询窗口插入表的情况下执行主过滤器操作。该窗口将在内存中建立索引,性能将非常好。

示例1带有临时查询窗口的主过滤器

SELECT A.Feature_ID FROM TARGET A  WHERE sdo_filter(A.shape, SDO_geometry(2003,NULL,NULL,
                                       SDO_elem_info_array(1,1003,3),
                                       SDO_ordinate_array(x1,y1, x2,y2))
                           ) = 'TRUE';   

在示例1中,(x1,y1)和(x2,y2)是查询窗口的左下角和右上角。


1
酷..因此,我应该创建表示半径的圆形几何图形,然后仅查看哪些多边形相交..有趣的..谢谢
我摔跤过一次熊。

是的..继续...希望它对您有用。
l.lijith'5

5

包括A在内的任何尝试都可能包括D,E,F,G。如果没有确切的路径定义每个邮政编码区域,就无法解决该问题。

找到这样的数据库,然后SPATIAL使用这样的任意多边形建立索引。


我知道我需要空间数据(而且我有空间数据,但是它在Oracle表中,并且我找不到关于如何转换它的太多信息)..问题正在弄清楚如何查询数据。
我曾经摔过一只熊。

如果您对新代码的性能感到满意,那可能是最好的。注意:查询列出了到每个拉链的距离,因此可能没有优化的潜力。(如果您获得更好的代码,我会感到惊喜。)
Rick James

这也是我在想的。我会给您赏金,直到它超时为止,您还是得到了一半。
我曾经摔过一只熊。

3

你这样做是错的。首先,如果可能的话,使用PostGIS-这是领先的带有空间解决方案的RDMBS。

然后,您要执行以下步骤。

  1. 从人口普查的TIGER数据集中下拉ZCTA(邮政编码列表区域)。邮政编码实际上并不确定。正式地,邮政编码仅供USPS内部使用。因为包括政府在内的所有人都在使用它们,所以第二大权威来源已成为ZCTA shapefile。
  2. 将这些shapefile导入数据库,使用PostgreSQL即可轻松使用 shp2pgsql
  3. 索引您导入的几何。

    CREATE INDEX ON census_zcta USING gist (geog);
    ANALYZE census_zcta;
  4. 对shapefile运行一个兴趣点(POI)查询。您所关注的是输入线,它看起来像这样,

    SELECT *
    FROM census_zcta AS zcta
      WHERE ST_Intersects( zcta, ST_MakePoint(long,lat)::geog );

9.3 1609.344米= 1英里

的MySQL

使用MySQL,您将拥有

  1. 使用ogr2​​ogr为人口普查Shapefile输出MySQL插入语句。
  2. 使用MBRIntersects利用空间索引。结束查询应类似于

    SELECT *
    FROM zcta
    WHERE MBRIntersects( geom, Point(long,lat) )
      AND ST_Intersects ( geom, Point(long,lat) );

3
1)我知道我做错了。这就是为什么我问。2)我工作的公司已支付访问usps内部邮政编码边界的权限。我们为此项目直接与usps合作,并且3)通常,这表明OP使用完全不同的工具集不是一个正确的答案。
我曾经摔过一只熊。

1
@iwrestledabearonce您也可以使用MySQL 8来做所有这些事情,只需ST_DWithinMBRIntersects
Evan Carroll

1
“有偿获得USPS内部邮政编码边界”你碰巧知道该产品的名称?AFAIK没有这种东西。(尽管USPS确实提供2种数据产品和一些用于解码地址的API)
Evan Carroll

1
感谢您添加有关mysql的信息。+1。该api不是公开的,也没有在任何网站上列出,实际上端点url甚至没有域名,我们直接从ip地址请求它。然而,恰恰证明了API存在,它是该文件(即参考EDDM 3是那些我指的是)中列出usps.com/business/web-tools-apis/archive/...
我按倒熊一旦。

1
如果您要退出EDDM / SelectZIP端点,那实际上似乎是合法的。这样做并不是为了广告,而是为找到那个终点而感到荣幸。
埃文·卡罗尔

1

GreatData.com签出此数据集(请注意,这不是开源的,而是付费服务)。

他们使用人口密度而不是邮政编码中心。

以及如何使用sql server空间数据类型来获得快速正确的结果。

希望这可以帮助。


此数据集可用于MySQL还是仅可用于SQL Server?
ypercubeᵀᴹ
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.