一个shapefile中多边形在另一多边形中的百分比


13

我是新手,很抱歉,如果这很明显/已经有人问过并回答了,但我找不到任何东西。

我有两个shapefile:1.英国某县的行政边界层,称为LSOA边界,其中有500个小区域2.洪水区。

理想情况下,我想找出洪水泛滥区内的哪个小LSOA区域≥50%,最后对500个LSOA区域中的每一个以是/否或1/0结尾。

但是我不知道该怎么做。我以为可以合并两个shapefile,但是它们之间没有共同的属性。然后,我想我可以使用“按位置连接属性”功能,该功能有效,并向我显示了哪些LSOA处于洪泛区,但是几乎所有这些都存在(参见图2)。

我认为这是一个SQL问题,但我不知道。我是QGIS的新手,从未使用过PostgreSQL。

任何帮助将不胜感激。我可以提供您可爱的人需要帮助的任何信息。

在此处输入图片说明

在此处输入图片说明

Answers:


12

使用QGIS中包含的地理处理工具,这是一项相对简单的任务。

  1. 计算您的LSOA区域的面积。

    • 打开LSOA图层属性表。
    • 启用编辑模式。
    • 打开字段计算器。
    • 用表达式“ $ area”创建一个类型为“ Decimal number(real)”的新字段。
    • 禁用编辑模式(保存编辑)。
  2. 将洪泛区图层合并为单个多部分要素。

    • Vector > Geometry Tools > Singleparts to Multipart
    • 在唯一ID字段中选择“ ---全部合并---”。
  3. 将LSOA区域层与多部分洪水区域层相交。

    • Vector > Geoprocessing Tools > Intersect
    • 输入层是LSOA区,相交层是洪水区。
  4. 结果层将是LSOA区域的一部分(具有LSOA区域层的属性),该部分与洪泛区层重叠。要计算洪泛区内每个LSOA区域的比例:

    • 计算相交要素的面积(如步骤1),然后
    • 添加另一个字段,将原始(总)区域除以相交区域。结果是一个介于0和1之间的十进制数。乘以100得出一个百分比。
  5. 使用两层共享的唯一ID,将原始LSOA层连接到相交的层。

  6. 将连接的图层导出为新的shapefile。

  7. 删除重复的属性。

等等!

如果没有步骤2,将为每个LSOA功能的每个不同的洪泛区功能创建一个单独的功能。如果您仅对每个LSOA区域的总覆盖率感兴趣,那么这可能不是您想要的。如果要区分河流洪水/潮汐洪水/洪灾洪水(且洪水区数据支持该洪水洪水),则可以将“部分”转换为“多部分”,将“ TYPE”字段指定为“唯一ID”字段。


谢谢您的帮助!非常感激。但是,我遇到了麻烦。我已经按照步骤进行了。第3步(相交)需要10个小时才能完成,完成后,我得到的只是一个空的shapefile:i.imgur.com/QIM6Gtg.png 我想念什么吗?我尝试完成该过程并执行第4步,但没有数据可计算出相交区域。
KJGarbutt

我以前在与洪水层进行交叉路口时遇到了问题。这些功能又大又复杂。我过去解决该问题的方法是将它们拆分为较小的要素,因此空间索引可以完成更多工作。为此,请创建与泛洪层(Vector > Research Tools > Vector Grid... Output grid as polygons)具有相同程度的矢量网格,然后将网格与泛洪层相交。然后在第3步中使用输出而不是Flood层。我猜测该层为空是因为它崩溃了。
Snorfalorpagus

再次感谢。现在唯一的问题是,每次我尝试创建矢量网格时,QGIS都会崩溃。我遵循了这里的建议,但每次都会崩溃。我已经多次更改了参数,并仅尝试使用泛洪区shapefile,而不是打开我的整个项目文件,每次都失败。有任何想法吗?!屏幕截图在这里
KJGarbutt

您指定的X和Y参数太小。尝试类似1000 x 1000的操作。您甚至可以多次执行此操作,即首先执行5000 x 5000,使用输出创建500 x500
Snorfalorpagus

在您的帮助下,我几乎破解了它!但是,当我将原始的LSOA层与相交的层连接在一起时,我丢失了很多数据。我认为这是因为创建的某些矢量网格正方形位于相同的LSOA区域内,因此每个网格都有相同的LSOA代码。因此,当我加入时,每个LSOA区域的最终结果都是2%以上,而我似乎只得到其中一个。有没有一种方法可以将具有相同LSOA的每个矢量网格平方的每个百分比相加?
KJGarbutt

6

您可以使用spatialite和一些空间SQL函数。

Select t1.geometry, t1.ID, area(t1.geometry), area(t2.geometry) ...... (anything you need to have in the table results)

(area(intersection(t1.geometry,t2.geometry))) as "Commun_AREA"

, ("Commun_AREA"*100/(area(t1.geometry))) as "Percent_AREA"

From lsoa as t1, flood_zone as t2

Where Intersects( t1.geometry,t2.geometry ) = 1

3

这似乎比提交的答案要容易得多。我会亲自使用一个简单的python脚本:

floodName = "the layer name here"
boundryName = "the layer name here"
fieldName = "the name of the field to contain the output 1/0"
minCoverage = 0.5 # the minimum amount of area covered to write 1
updateMap = [] # this will store values to be written    

# get layers
floodLayer = QgsMapLayerRegistry.instance().mapLayersByName(floodName)[0]
boundryLayer = QgsMapLayerRegistry.instance().mapLayersByName(boundryName)[0]
fieldIndex = boundryLayer.dataProvider().fieldNameIndex(fieldName)    

# iterate through boundries
for b in boundryLayer.getFeatures():
    # get only flood features that intersect with this feature's bounding box
    # this will make the script go way faster than it would otherwise
    request = QgsFeatureRequest().setFilterRect(b.geometry().boundingBox())
    floodGeom = geometry()
    floodFeat = QgsFeature()
    iter = floodLayer.getFeatures(request)
    iter.nextFeature(feat)
    while iter.nextFeature(feat):
        floodGeom = floodGeom.combine(feat.geometry())
    intersectGeom = b.geometry().intersection(feat.geometry())
    if intersectGeom.area() > minCoverage * b.geometry().area():
        updateMap[b.id()] = {fieldIndex : 1}
    else:
        updateMap[b.id()] = {fieldIndex : 0}

boundryLayer.dataProvider().changeAttributeValues(updateMap)

这只会评估与每个边界图层的边界框相交的洪水多边形,因此应该相当快地运行,然后只更新现有图层中的一个字段(而不是制作一个新的新图层并复制旧值的复杂操作然后删除)


2

按照Snorfalorpagus在步骤3中使用“相交”方法的指示,我遇到了与KJ相同的问题。花了相当长的时间才能计算出结果,而我所剩无几。

我尝试执行相同的步骤,只是在QGIS中使用“剪辑”方法而不是“相交”-因此,在您的示例中,剩下的将是洪水区域未覆盖的部分区域。这似乎由于某些原因而起作用,我能够使用上一步中的“面积”字段计算,再加上对每个多边形其余部分的新“面积”计算,以找出每个面积中未包含的百分比被另一个多边形层覆盖。

从技术上讲,这与您的要求相反。但是,从那里,它只是一个从1减去每个价值得到什么之事被洪水区覆盖。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.