Подтвердить что ты не робот

Расширить реализацию MySQL алгоритма PiP?

Мне нужно сделать точку в запросе MySQL многоугольника.

Я уже нашел эти два больших решения:

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

MySQL-реализация алгоритма лучевого кастинга?

Но эти функции могут только проверять, находится ли одна точка внутри поля. У меня есть запрос, где часть 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

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);

G2 НЕ должен находиться внутри G1, но MBR говорит, что это.

4b9b3361

Ответ 1

Итак, действительно, ваш вопрос заключается в том, как вы применяете одну и ту же функцию к нескольким значениям и возвращаете true, только если весь вызов функции возвращает true. Это не очень сложно.

Если бы это был я, я бы поместил точки (и, необязательно, многоугольники, не показанные в примере), в таблицу, а затем напишет функцию MySQL, чтобы применить метод raycasting к каждой точке - возврату false, если какое-либо одно вмешательство возвращает false, тогда return true. В приведенном ниже примере я предположил, что многоугольник извлекается из вашегополигона и идентифицируется по первичному ключу, тогда как точки индексируются внешним ключом (используя функцию mywithin by zarun):

 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))')
      );

Дает вам количество точек, не находящихся внутри многоугольника (что довольно дорого, когда вы только хотите узнать, не находится ли NONE из точек).

Ответ 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.