我在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()
答案 0 :(得分:0)
我建议使用 shapely 来迭代您的外部和内部多边形。
当您有一个包含所有外部和内部多边形的多边形时:
假设您的多边形称为 R,
R.exterior.coords ,给你一个带有外部坐标的对象
R.interiors,给你一个带有所有内环的内环序列的对象,你可以对它进行切片或迭代。
因此,如果您想要第一个内环,
r.interiors[0] 如果你想要第二个内环, r.interiors[1] 如果你想要坐标 r.interiors[1].coords
通过这种方式,您可以在操作中包含每个内部多边形。