【问题标题】:Extend MySQL implementation of PiP Algorithm?扩展 PiP 算法的 MySQL 实现?
【发布时间】:2013-11-10 11:51:04
【问题描述】:

我需要在多边形中创建一个点 MySQL 查询。

我已经找到了这两个很好的解决方案:

http://forums.mysql.com/read.php?23,286574,286574

MySQL implementation of ray-casting Algorithm?

但是这些函数只能检查一个点是否在多边形内。我有一个查询,画中画部分应该只是查询的一部分,并检查多边形内的 x 点。

类似这样的:

$points = list/array/whatever of points in language of favour

SELECT d.name
FROM data AS d
WHERE d.name LIKE %red%
// just bla bla

// how to do this ?
AND $points INSIDE d.polygon
AND myWithin( $points, d.polygo ) // or

更新

我尝试了这样的 MBR 函数:

SET @g1 = GeomFromText('Polygon((13.43971 52.55757,13.41293 52.49825,13.53378 52.49574, 13.43971 52.55757))');
SET @g2 = GeomFromText('Point(13.497834 52.540489)');
SELECT MBRContains(@g1,@g2);

G2 不应该在 G1 中,但 MBR 说是。

【问题讨论】:

  • MBRContains() 有什么问题?
  • 你检查了@eggyal提供的链接中的所有功能吗?
  • 我读到 MBR 不够准确,但现在深入挖掘。
  • MBR 无法使用,因为它适用于边界框。检测多边形内的点将不准确。
  • 您最终将使用过程 SQL,那么为什么不使用命令式语言来查询数据库并执行所需的计算呢?我不明白为什么 SQL 应该做所有事情......只是问问。

标签: php mysql raycasting point-in-polygon


【解决方案1】:

所以实际上,您的问题是如何将相同的函数应用于多个值,并且仅当对函数的所有调用都返回 true 时才返回 true。这不是很难。

如果是我,我会将点(以及可选的多边形 - 示例中未显示)放入表中,然后编写一个 MySQL 函数以将光线投射方法应用于每个点 - 如果任何一个交互返回 false,则返回 false,然后返回真。在下面的示例中,我假设多边形是从 yourpolygon 中获取并由主键标识,而点由外键标识(使用 zarun 的 mywithin 函数):

 DECLARE FUNCTION allwithin(
     pointSetKey INT) 
 RETURNS INT(1)  
 BEGIN 

 DECLARE current POINT;

 DECLARE check CURSOR FOR SELECT p.point
     FROM yourpoints p
     WHERE p.set=pointSetKey;

 OPEN check;

 nextPoint: LOOP

    FETCH check INTO current;

    IF (0=mywithin(current, yourpolygon)) THEN
         RETURN 0;
    END IF;

 END LOOP;

 RETURN 1;

 END;

 INSERT INTO yourpoints (pointsetkey, point)
 VALUES (
      128,
      GeomFromText('Point(13.497834 52.540489)')
 ),
 (
      128,
      GeomFromText('Point(13.6 52.1)')
 ),
 ....
 ;

 SELECT allwithin(128
 , GeomFromText('Polygon((13.43971 52.55757,13.41293 52.49825,13.53378 52.49574, 13.43971 52.55757))')
 );

或者...

 SELECT COUNT(*)
 FROM yourpoints p
 WHERE p.set=128
 AND mywithin(p.point
      , GeomFromText('Polygon((13.43971 52.55757,13.41293 52.49825,13.53378 52.49574, 13.43971 52.55757))')
      );

将为您提供不在多边形内的点数(当您只想知道是否没有点在外面时,这是相当昂贵的)。

【讨论】:

  • 在erflection这可以优化很多 - 但时间禁止。
【解决方案2】:

如果你这样做了会怎样

SET @g1 = GEOMFROMTEXT('Polygon((13.43971 52.55757,13.41293 52.49825,13.53378 52.49574, 13.43971 52.55757))');
SET @g2 = GEOMFROMTEXT('Point(13.497834 52.540489)');
SELECT  ST_Contains(@g1,@g2);

而不是 MBRContains?据我了解 MySQL 空间文档。 MBR* 函数是最小边界矩形函数,因此它会显示您的点是否在几何体上的最小矩形内,但不在几何体本身内(如果它是不规则多边形并且点在 MBR 内而不是在多边形)

【讨论】:

    【解决方案3】:

    在我看来如下:您需要测试多个点是否在多边形中。如果都是,那么它们的凸包也是如此。找出它们的凸包(基本上:顺时针或逆时针排列它们),这将创建一个多边形。现在测试新多边形是否在 d.polygon 内。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      • 1970-01-01
      相关资源
      最近更新 更多