POST 请求只有在通过 httr 感知之前在站点上执行时才有效

POST request works only if it is executed on the site before sensing through httr

我想从这个站点抓取数据:https://ispu.mgipu.hr/ 这个想法是提取放大后可以看到的小点(它们的坐标)。

这是程序(至少缩放到 1:5000 之后)我想自动化:

  1. 你必须点击右边有正方形、三角形和圆形的符号。
  2. 那你要点下面'Info lokacija'.
  3. 那你要选'Poligonom'上面'Odabir'.
  4. 现在你必须用鼠标拖任何东西,完成后双击。

如果您在上述过程中检查网络,您会看到一个新的 XHR 请求出现:'obuhvat'。这是一个 POST 请求,它只有一个负载元素(带坐标的 POLYGON)。

我试图将这些 POST 请求直接发送到同一站点,但我总是收到 400 响应。

只有当我首先在浏览器中执行所有操作并将相同的负载复制粘贴到请求时,它才会起作用。

这是我的尝试:

library(httr)


# params
url <- 'https://ispu.mgipu.hr/geo/api/info-lokacija/obuhvat'
ua <- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36'

# this works becuase I have already draw these polygon in app manually
data <- list(
  geom = "POLYGON((466131.6322632646 5062601.925203851,466141.4322828647 5062489.924979851,466292.63258526527 5062489.924979851,466287.03257406526 5062596.325192652,466131.6322632646 5062601.925203851))"
)
req <- POST(url, body = data, encode = 'json', user_agent(ua))
print(req$status_code)

# this doesnt work, I have just change the one number in data
data <- list(
  geom = "POLYGON((466131.6322632647 5062601.925203851,466141.4322828647 5062489.924979851,466292.63258526527 5062489.924979851,466287.03257406526 5062596.325192652,466131.6322632646 5062601.925203851))"
)
req <- POST(url, body = data, encode = 'json', user_agent(ua))
print(req$status_code)

所以,这不是我想给出的完整答案,但可能是 10 的开始。

回想起学校的几何学,我记得涵盖了多边形的规则,并假设您改变坐标可能违反了规则。

以你给出的例子为例-

工作:

POLYGON((470883.3817753086 4925329.690667927,470757.9415158831 4925207.6103212265,470924.8218453713 4925156.090320726,470883.3817753086 4925329.690667927))

不工作:

POLYGON((466131.6322632647 5062601.925203851,466141.4322828647 5062489.924979851,466292.63258526527 5062489.924979851,466287.03257406526 5062596.325192652,466131.6322632646 5062601.925203851)))

我决定通过一个包来传递,该包至少可以检查多边形的一些规则并给我返回比 http 代码更有意义的信息。

library(sf)
#> Warning: package 'sf' was built under R version 4.0.3
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1

x = st_as_sfc("POLYGON((466131.6322632646 5062601.925203851,466141.4322828647 5062489.924979851,466292.63258526527 5062489.924979851,466287.03257406526 5062596.325192652,466131.6322632646 5062601.925203851)))")
st_is_valid(x, reason = TRUE)
#> [1] "Valid Geometry"

# your altered
x = st_as_sfc("POLYGON((466131.6322632647 5062601.925203851,466141.4322828647 5062489.924979851,466292.63258526527 5062489.924979851,466287.03257406526 5062596.325192652,466131.6322632646 5062601.925203851)))")
st_is_valid(x, reason = TRUE)
#> Error in CPL_geos_is_valid_reason(x): Evaluation error: IllegalArgumentException: Points of LinearRing do not form a closed linestring.

reprex package (v0.3.0)

于 2021-02-09 创建

我们现在根据 sf 包中应用的规则获得一些关于您的调整有效性的有用信息。

Error in CPL_geos_is_valid_reason(x): Evaluation error: IllegalArgumentException: Points of LinearRing do not form a closed linestring.

通过谷歌搜索该错误让我找到了 @yellowcap 的答案:

A valid polygon or multipolygon must have identical start and endpoints.

有道理。您更改了起点,使其与终点不匹配,这意味着您没有封闭的多边形。

# start 466131.6322632647 5062601.925203851 
# end   466131.6322632646 5062601.925203851

通过更改一组不同的坐标(不是第一个|最后一个)进行测试;保持开始和结束对相同并改变第二对

# 466141.4322828647 5062489.924979851  >> 566141.4322828647 6062489.924979851

x = st_as_sfc("POLYGON((466131.6322632647 5062601.925203851,566141.4322828647 6062489.924979851,466292.63258526527 5062489.924979851,466287.03257406526 5062596.325192652,466131.6322632647 5062601.925203851))")
st_is_valid(x, reason = TRUE)
# [1] "Valid Geometry"

然而,这并不能保证在您的 POST 中被接受。所以,我在想象我的 sf 应用程序没有处理的其他一些限制。我对 GIS 的了解还不够多,无法解决这个问题,但也许 gis.stackexchange.com 上的某个人可能会这样做?

我看过 this 对于一些背景,它列出了:

21.1. What is Validity

Validity is most important for polygons, which define bounded areas and require a good deal of structure. Lines are very simple and cannot be invalid, nor can points.

Some of the rules of polygon validity feel obvious, and others feel arbitrary (and in fact, are arbitrary).

  1. Polygon rings must close.
  2. Rings that define holes should be inside rings that define exterior boundaries.
  3. Rings may not self-intersect (they may neither touch nor cross one another).
  4. Rings may not touch other rings, except at a point.

所以,我想知道 sf 包是否提供了一个快速解决方法:

st_make_valid()

遗憾的是,我无法解决您的失败案例。

然后我开始从一个大的 GIS 洞中掉下来,对我要去哪里一无所知。我开始查看 QGIS 看看我是否可以编辑几何图形并进行更多锻炼,但没有取得太大进展。


这是我的假设,有一些证据,关于下一步 ask/look 的建议以及“目前失败但有兴趣所以会重新访问”的出口......


阅读中:

  1. http://postgis.refractions.net/docs/ST_MakeValid.html

  2. https://docs.qgis.org/testing/en/docs/user_manual/working_with_vector/editing_geometry_attributes.html#vertex-tool

  3. https://r-spatial.github.io/sf/articles/sf5.html

  4. https://postgis.net/workshops/postgis-intro/validity.html

  5. https://www.rdocumentation.org/packages/lwgeom/versions/0.2-1/topics/valid