扩展MySQL实现PiP算法?

13

我需要制作一个点在多边形内的MySQL查询。

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

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

MySQL实现光线投射算法?

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

类似于这样:

$points = 使用所选语言的列表/数组/任何内容的点

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说它在。


1
MBRContains() 函数有什么问题? - eggyal
1
你有检查 @eggyal 提供的链接中的所有函数吗? - inhan
MBR 不适用于使用边界框的情况。检测多边形内部的点将不够准确。 - Mike
1
你最终会使用过程化 SQL,那么为什么不使用命令式语言来查询数据库和执行所需的计算?我不明白为什么 SQL 应该做所有的事情......只是问一下。 - gd1
我一开始就这样做了,它可以工作,但是我最终会在太多的位置插入“结果过滤”。如果我能通过SQL来完成它,那么只需要一个操作就可以在任何地方工作。 - Mike
显示剩余2条评论
3个回答

2

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

如果是我,我会将点(和可选的多边形-在示例中未显示)放入表中,然后编写一个MySQL函数来对每个点应用射线投射方法-如果任何一个迭代返回false,则返回false,然后返回true。在下面的示例中,我假设多边形从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))')
      );

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


回顾一下,这个可以进行很多优化 - 但是时间不允许。 - symcbean

1
如果你这么做会怎样?
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内而不在多边形内)。


0
我认为你需要测试多个点是否在一个多边形内。如果是的话,它们的凸包也在其中。找出它们的凸包(基本上是按顺时针或逆时针排序),这将创建一个多边形。现在测试新的多边形是否在d.polygon内。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接