ST_Within неправильно возвращает true, когда точка находится за пределами многоугольника - PullRequest
0 голосов
/ 19 октября 2018

Этот запрос, чтобы определить, находится ли точка внутри многоугольника ...

SELECT ST_Within
(
    ST_GeogPoint(69.6, 21.1),
    ST_GeogFromText('POLYGON((67.8 23.4, 69 17, 72.8 16.9, 67.8 23.4))')
)

... возвращает TRUE в BigQuery.Это неверный результат.

Тот же запрос ...

SELECT ST_Within
(
    ST_MakePoint(69.6, 21.1),
    'POLYGON((67.8 23.4, 69 17, 72.8 16.9, 67.8 23.4))'
)

... возвращает FALSE в PostGIS.Это правильный результат.

Ответы [ 3 ]

0 голосов
/ 20 октября 2018

Когда вы строите это в Google Планета Земля, оно выходит за пределы многоугольника.Вот скриншот и файл kml, который содержит и многоугольник, и эту точку.Означает ли это, что Google Планета Земля и Инструмент визуализации данных ГИС BigQuery используют разные системы координат?

точка вне полигона в Google Планета Земля

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Folder>
    <name>Temporary Places</name>
    <open>1</open>
    <Document>
        <name>Big Query ST_Within test.kml</name>
        <Style id="prelim">
            <LineStyle>
                <color>ff0000ff</color>
            </LineStyle>
            <PolyStyle>
                <color>4c0000ff</color>
            </PolyStyle>
        </Style>
        <Placemark>
            <name>Big Query ST_Within polygon</name>
            <styleUrl>#prelim</styleUrl>
            <Polygon>
                <tessellate>1</tessellate>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>
                            67.8,23.4,0 69,17,0 72.8,16.9,0 67.8,23.4,0 
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
    </Document>
    <Placemark>
        <name>Big Query ST_Within point</name>
        <Point>
            <coordinates>69.6,21.1,0</coordinates>
        </Point>
    </Placemark>
</Folder>
</kml>
0 голосов
/ 20 октября 2018

Этот запрос дает вам false ответ, который вы искали:

SELECT ST_WITHIN(
  ST_GeogPoint(69.6, 21.1)
  , ST_GeogFromGeoJSON(
    '{"type": "Polygon", "coordinates": [[[67.8, 23.4], [69, 17], [72.8, 16.9], [67.8, 23.4]]]}'
))

В чем разница?

Давайте проверим документы:

Географическая структура BigQuery имеет сферические геодезические ребра, в то время как объект GeoJSON Geometry явно имеет плоские ребра.Для преобразования между этими двумя типами ребер BigQuery добавляет дополнительные точки к линии, где это необходимо, чтобы результирующая последовательность ребер оставалась в пределах 10 метров от исходного ребра.

На самом деле, есть действительно интересныйтесселяция, происходящая для преобразования между обеими системами:

 SELECT ST_GeogFromGeoJSON(
   '{"type": "Polygon", "coordinates": [[[67.8, 23.4], [69, 17], [72.8, 16.9], [67.8, 23.4]]]}'
 )

 POLYGON((67.8 23.4, 67.875 23, 67.95 22.6, 68.025 22.2, 68.1 21.8, 68.175 21.4, 68.25 21, 68.325 20.6, 68.4 20.2, 68.475 19.8, 68.55 19.4, 68.625 19, 68.7 18.6, 68.775 18.2, 68.85 17.8, 68.925 17.4, 69 17, 69.2375 16.99375, 69.475 16.9875, 69.7125 16.98125, 69.95 16.975, 70.1875 16.96875, 70.425 16.9625, 70.6625 16.95625, 70.9 16.95, 71.1375 16.94375, 71.375 16.9375, 71.6125 16.93125, 71.85 16.925, 72.0875 16.91875, 72.325 16.9125, 72.5625 16.90625, 72.8 16.9, 72.64375 17.103125, 72.4875 17.30625, 72.33125 17.509375, 72.175 17.7125, 72.01875 17.915625, 71.8625 18.11875, 71.70625 18.321875, 71.55 18.525, 71.39375 18.728125, 71.2375 18.93125, 71.08125 19.134375, 70.925 19.3375, 70.76875 19.540625, 70.6125 19.74375, 70.45625 19.946875, 70.3 20.15, 70.14375 20.353125, 69.9875 20.55625, 69.83125 20.759375, 69.675 20.9625, 69.51875 21.165625, 69.3625 21.36875, 69.20625 21.571875, 69.05 21.775, 68.89375 21.978125, 68.7375 22.18125, 68.58125 22.384375, 68.425 22.5875, 68.26875 22.790625, 68.1125 22.99375, 67.95625 23.196875, 67.8 23.4))   

Кстати, от Earth Engine документы:

A геометриясозданный в Earth Engine является либо геодезическим (т.е. ребра - это самый короткий путь на поверхности сферы), либо плоским (то есть ребра - это самый короткий путь в двумерной декартовой плоскости).Ни одна плоская система координат не подходит для глобальных коллекций объектов, поэтому конструкторы геометрии Earth Engine по умолчанию строят геодезические геометрии.

enter image description here


Теперь давайте проверим PostGIS - который может работать с геометрией и географией.

SELECT ST_CoveredBy (
    ST_MakePoint(69.6, 21.1),
    'POLYGON((67.8 23.4, 69 17, 72.8 16.9, 67.8 23.4))'
)    
false

SELECT ST_CoveredBy(
    ST_MakePoint(69.6, 21.1)::geography,
    'POLYGON((67.8 23.4, 69 17, 72.8 16.9, 67.8 23.4))'
)
true

(в континентальном масштабе этого многоугольника: вы действительно хотите использовать географию над геометрией - даже если производительность в PostGIS будет ниже)


Назад к BigQuery:Каково расстояние между Парижем и Лос-Анджелесом?

SELECT ROUND(ST_Length(line)/1000,2) km
FROM (
  SELECT [
    ST_GeogFromGeoJSON('{"type": "LineString", "coordinates": [[-118.4079, 33.9434], [2.5559, 49.0083]]}')
    , ST_GEOGFROMTEXT('LINESTRING(-118.4079 33.9434, 2.5559 49.0083)')
  ] lines
), UNNEST(lines) line


km
10187.92     
9103.09

enter image description here

Я только что сэкономил вам 1084 км пути, используя геодезическую линию.

0 голосов
/ 20 октября 2018

Google BigQuery не использует плоские линии на карте, скорее, BigQuery Geography определяет их как геодезические (подробнее в разделе " Системы координат и ребра ")

Так что, если вынарисует ваш многоугольник и укажет на BigQuery GIS Data Visualization Tool - вы увидите, что точка находится внутри многоугольника

...