资讯详情

python – 从边界点创建闭合多边形

我有一系列的经度 – 定义区域边界的纬度点.我想根据这些点创建一个多边形,并在地图上绘制多边形并填充它.目前,我的多边形似乎由许多连接所有点的补丁组成,但点的顺序不正确。当我试图填充多边形时,我得到了一个奇怪的外观区域(见附件).

我根据多边形中心对经度进行了处理 – 纬度点(mypolyXY数组)进行排序,但我的猜测是这不正确:

cent=(np.sum([p[0] for p in mypolyXY])/len(mypolyXY),np.sum([p[1] for p in mypolyXY])/len(mypolyXY))

# sort by polar angle

mypolyXY.sort(key=lambda p: math.atan2(p[1]-cent[1],p[0]-cent[0]))

我用画点位置(黑圆)和我的多边形(彩色贴片)

scatter([p[0] for p in mypolyXY],[p[1] for p in mypolyXY],2)

p = Polygon(mypolyXY,facecolor=colors,edgecolor='none')

ax.add_artist(p)

我的问题是:如何根据经度 – 纬度点数组关闭多边形?

更新:

我测试了更多关于如何绘制多边形的信息.我删除了排序例程,只是按照它们在文件中的顺序使用数据.这似乎改善了结果,但就像@tcaswell多边形仍在削弱自己(见新图).我希望有一个路径/多边形例程可以解决我的问题,并将所有形状或路径合并到多边形边界.非常欢迎建议.

更新2:

我现在有一个基础@Rutger Kassies和Roland Smith建议脚本的工作版.我最后使用org阅读了Shapefile,它工作得很好.适用于标准lmes_64.shp但是当我使用更详细的文件时LME每个文件LME可包括多个多边形,脚本崩溃了.我必须找到合并相同的方法LME各种多边形名称,使其工作.我附上了我的剧本,以防有人看.我非常感谢关于如何改进脚本或使其更通用的评论.这个脚本创建了多边形提取我netcdf在多边形区域读取的数据.输入文件的网格为-180到180和-90到90.

import numpy as np

import math

from pylab import *

import matplotlib.patches as patches

import string, os, sys

import datetime, types

from netCDF4 import Dataset

import matplotlib.nxutils as nx

from mpl_toolkits.basemap import Basemap

import ogr

import matplotlib.path as mpath

import matplotlib.patches as patches

def getLMEpolygon(coordinatefile,mymap,index,first):

ds = ogr.Open(coordinatefile)

lyr = ds.GetLayer(0)

numberOfPolygons=lyr.GetFeatureCount()

if first is False:

ft = lyr.GetFeature(index)

print "Found polygon:", ft.items()['LME_NAME']

geom = ft.GetGeometryRef()

codes = []

all_x = []

all_y = []

all_XY= []

if (geom.GetGeometryType() == ogr.wkbPolygon):

for i in range(geom.GetGeometryCount()):

r = geom.GetGeometryRef(i)

x = [r.GetX(j) for j in range(r.GetPointCount())]

y = [r.GetY(j) for j in range(r.GetPointCount())]

codes = [mpath.Path.MOVETO] (len(x)-1)*[mpath.Path.LINETO]

all_x = x

all_y = y

all_XY =mymap(x,y)

if len(all_XY)==0:

all_XY=None

mypoly=None

else:

mypoly=np.empty((len(all_XY[][0]),2)

mypoly[:,0]=all_XY[:][0]

mypoly[:,1]=all_XY[:][3]

else:

print "Will extract data for %s polygons"%(numberOfPolygons)

mypoly=None

first=False

return mypoly, first, numberOfPolygons

def openCMIP5file(CMIP5name,myvar,mymap):

if os.path.exists(CMIP5name):

myfile=Dataset(CMIP5name)

print "Opened CMIP5 file: %s"%(CMIP5name)

else:

print "Could not find CMIP5 input file %s : abort"%(CMIP5name)

sys.exit()

mydata=np.squeeze(myfile.variables[myvar][-1,:, - 273.15

lonCMIP5=np.squeeze(myfile.variables["lon"][:])

latCMIP5=np.squeeze(myfile.variables["lat"][:])

lons,lats=np.meshgrid(lonCMIP5,latCMIP5)

lons=lons.flatten()

lats=lats.flatten()

mygrid=np.empty((len(lats),2))

mymapgrid=np.empty((len(lats),2))

for i in xrange(len(lats)):

mygrid[i,0]=lons[i]

mygrid[i,1]=lats[i]

X,Y=mymap(lons[i],lats[i])

mymapgrid[i,0]=X

mymapgrid[i,1]=Y

return mydata, mygrid, mymapgrid

def drawMap(NUM_COLORS):

ax = plt.subplot(111)

cm = plt.get_cmap('RdBu')

ax.set_color_cycle([cm(1.*j/NUM_COLORS) for j in range(NUM_COLORS)])

mymap = Basemap(resolution='l',projection='robin',lon_0=0)

mymap.drawcountries()

mymap.drawcoastlines()

mymap.fillcontinents(color='grey',lake_color='white')

mymap.drawparallels(np.arange(-90.,120.,30.))

mymap.drawmeridians(np.arange(0.,360.,60.))

mymap.drawmapboundary(fill_color='white')

return ax, mymap, cm

"""Edit the correct names below:"""

LMEcoordinatefile='ShapefileBoundaries/lmes_64.shp'

CMIP5file='tos_Omon_CCSM4_rcp85_r1i1p1_200601-210012_regrid.nc'

mydebug=False

doPoints=False

first=True

"""initialize the map:"""

mymap=None

mypolyXY, first, numberOfPolygons = getLMEpolygon(LMEcoordinatefile, mymap, 0,first)

NUM_COLORS=numberOfPolygons

ax, mymap, cm = drawMap(NUM_COLORS)

"""Getthe CMIP5 data together with the grid"""

SST,mygrid, mymapgrid = openCMIP5file(CMIP5file,"tos",mymap)

"""For each LME of interest create a polygon of coordinates defining the boundaries"""

for counter in xrange(numberOfPolygons-1):

mypolyXY,first,numberOfPolygons = getLMEpolygon(LMEcoordinatefile, mymap,counter,first)

if mypolyXY != None:

"""Find the indices inside the grid that are within the polygon"""

insideBoolean = plt.mlab.inside_poly(np.c_[mymapgrid[:,0],mymapgrid[:,1]],np.c_[mypolyXY[:,0],mypolyXY[:,1]])

SST=SST.flatten()

SST=np.ma.masked_where(SST>50,SST)

mymapgrid=np.c_[mymapgrid[:,0],mymapgrid[:,1]]

myaverageSST=np.mean(SST[insideBoolean])

mycolor=cm(myaverageSST/SST.max())

scaled_z = (myaverageSST - SST.min()) / SST.ptp()

colors = plt.cm.coolwarm(scaled_z)

scatter([p[0] for p in mypolyXY],[p[1] for p in mypolyXY],2)

p = Polygon(mypolyXY,facecolor=colors,edgecolor='none')

ax.add_artist(p)

if doPoints is True:

for point in xrange(len(insideBoolean)):

pointX=mymapgrid[insideBoolean[point],0]

pointY=mymapgrid[insideBoolean[point],1]

ax.scatter(pointX,pointY,8,color=colors)

ax.hold(True)

if doPoints is True:

colorbar()

print "Extracted average values for %s LMEs"%(numberOfPolygons)

plt.savefig('LMEs.png',dpi=300)

plt.show()

附上最终图片.谢谢你的帮助.

干杯,特隆德

标签: omon安全继电器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司