扩展PiP算法的MySQL实现?

Mik*_*ike 13 php mysql point-in-polygon raycasting

我需要在多边形 MySQL查询中提出一个观点.

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

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

MySQL实现光线投射算法?

但是这些函数只能检查一个点是否在poly中.我有一个查询,其中PiP部分应该只是查询的一部分,并检查多边形内的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
Run Code Online (Sandbox Code Playgroud)

UPDATE

我尝试使用这样的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);
Run Code Online (Sandbox Code Playgroud)

G2不应该在G1内,但MBR说它是.

sym*_*ean 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))')
 );
Run Code Online (Sandbox Code Playgroud)

或者...

 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))')
      );
Run Code Online (Sandbox Code Playgroud)

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