多边形内圈/孔问题

时间:2015-11-11 10:09:48

标签: python python-2.7 scipy shapefile smoothing

我在8天前在GIS SE上发布了相同的question,但没有回复,并决定扩大知识库。

我正在制作一个平滑多边形的脚本。基本上,它分离内环和外环/多边形并将坐标发送到平滑def /函数。然后使用pyshp附加“平滑”坐标并将其写入shapefile。

我面临的问题如下: 对于一些多边形,在平滑之后,并非所有内环/孔都被绘制/插入。然而,对于类似的复杂多边形,绘制/插入孔。原因我不完全确定。

到目前为止,我已经尝试确定的问题可能是打印到平滑def /函数的坐标,似乎缺少的内环由于某种原因没有发送到平滑def /函数

以下是脚本和示例图像。请注意我对python和脚本编写起来相当新。

有任何解决此问题的建议???

修改 我可以确认平滑的shapefile中缺少的内环是由于它没有被发送到平滑函数。

import os
import sys
import ogr
import fileinput
import shapefile
import Tkinter
import tkSimpleDialog
import gdalnumeric
import tkFileDialog
import numpy as np
from scipy.ndimage import gaussian_filter
import shapely
import time
import shutil


root = Tkinter.Tk()

#Smoothing formula for outer rings
def smoothingouter(pts):
    for i in pts:

        array = np.array(pts)
        x, y = array.T
        t = np.linspace(0, 1, len(x))
        t2 = np.linspace(0, 1, 100)

        x2 = np.interp(t2, t, x)
        y2 = np.interp(t2, t, y)

        sigma = 1.25
        x3 = gaussian_filter(x2, sigma)
        y3 = gaussian_filter(y2, sigma)

        x4 = np.interp(t, t2, x3)
        y4 = np.interp(t, t2, y3)

        zipped = zip(x4,y4)
        return zipped

#Smoothing formula for inner rings       
def smoothinginner(pts):
    for i in pts:

        array = np.array(pts)
        x, y = array.T
        t = np.linspace(0, 1, len(x))
        t2 = np.linspace(0, 1, 100)

        x2 = np.interp(t2, t, x)
        y2 = np.interp(t2, t, y)

        sigma = 0.2
        x3 = gaussian_filter(x2, sigma)
        y3 = gaussian_filter(y2, sigma)

        x4 = np.interp(t, t2, x3)
        y4 = np.interp(t, t2, y3)

        zipped = zip(x4,y4)
        return zipped

#Select input shapefile
inshp = tkFileDialog.askopenfilename(title='Select shapefile to smooth:')
mdir, mfilename = os.path.split(inshp)
mnam, mext = os.path.splitext(mfilename)

sf = shapefile.Reader(inshp)
shapeout = mdir + '/' + mnam + '_smoothed.shp'
w = shapefile.Writer(shapefile.POLYGON)
w.autoBalance = 1
w.field("ID")
id=8 

shape = sf.shapes()

# a: feature index tracker
a = 0

#Steps and cnt for the progress bar
steps = len(shape)/10
cnt = 0

#for each feature in layer 
for i in shape:
    b = shape[a].points
    # add feature points to numpy array
    d = np.array(b)
    exterior = True
    #q is the index of the first point for each ring (includes both inner and outer rings)
    q = 0
    #v is the index tracker of each point in a feature regardless whether it is part of inner or outer ring
    v = 0
    #create a list to add smoothed points to
    wparts = []
    #loops through each point of a polygon
    for c in b:
        #get the first point (this is the first point of the exterior polygon since all points of the outer ring are first in the index, all inner rings thereafter)
        first = b[q]
        #compares each point to the first point. Every ring will have identical coords for its first and last points. From this we can seperate each rings coords      
        if c == first:
            # q must be smaller than v. E.g For the first coord, q = 0 and v = 0 therefore d[q] and d[v] are the same point and no range will be found
            if (q < v):
                #All points from the exterior ring of a polygon gets processed using the smoothingouter function
                if exterior == True:
                    ss = smoothingouter(d[q:v])
                #Points from each inner ring of a polygon gets processed using the smoothinginner function 
                else:
                    ss = smoothinginner(d[q:v])
                #Add the resulting coordinates to the list
                wparts.append(ss)

                if (exterior == True):
                    w.record(id)
                #Update the starting index of the next exterior polygon
                q = v+1
                exterior = False



        v+=1
    w.poly(wparts)

    a+=1

#Create new smoothed poly shapefile
w.save(shapeout)

prjcopy = shapeout[:-3] + 'prj'

shutil.copy(inshp[:-3] + 'prj', prjcopy)

print 'done'

root.destroy()

带内圈的未平滑多边形: enter image description here

内圈缺失的平滑多边形: enter image description here

1 个答案:

答案 0 :(得分:0)

我建议使用 shapely 来迭代您的外部和内部多边形。

当您有一个包含所有外部和内部多边形的多边形时:

假设您的多边形称为 R,

R.exterior.coords ,给你一个带有外部坐标的对象

R.interiors,给你一个带有所有内环的内环序列的对象,你可以对它进行切片或迭代。

因此,如果您想要第一个内环,

r.interiors[0] 如果你想要第二个内环, r.interiors[1] 如果你想要坐标 r.interiors[1].coords

通过这种方式,您可以在操作中包含每个内部多边形。