今日得暇,对之前的程序进行了小幅度修改
读取shp文件的程序保持不变
环境:python 2.5
gdal 1.5
外加wxpython、numpy
Code
#-*- encoding:GBK -*-
import sys,os,string
import wx
import random
from wkb import *
class guiFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, 'tri-S: Sketch Shape Show', size=(1000,690))
self.sketch = sketchWindow(self, -1)
self.Center()
#菜单
menuBar=wx.MenuBar()
mFile=wx.Menu()
mFile.Append(101, '打开(&O)', '打开文件')
mFile.Append(102, '保存(&S)', '保存文件')
mFile.Append(103, '关闭(&C)', '关闭文件')
mFile.AppendSeparator()
mFile.Append(109, '退出(&X)', '退出系统')
menuBar.Append(mFile, '文件(&F)')
mView=wx.Menu()
mView.Append(201, '放大(&I)', '放大视图')
mView.Append(202, '缩小(&O)', '缩小视图')
mView.Append(203, '平移(&P)', '平移视图')
mView.Append(204, '全图(&E)', '整个视图')
menuBar.Append(mView, '视图(&V)')
mLayer=wx.Menu()
mLayer.Append(301, '列表(&L)', '图层列表')
mLayer.AppendSeparator()
mLayer.Append(311, '线划(&L)', '线段样式')
mLayer.Append(312, '填充(&S)', '填充样式')
mLayer.Append(313, '线宽(&T)', '边线宽度')
mLayer.Append(314, '线型(&M)', '边线形状')
menuBar.Append(mLayer, '图层(&L)')
self.SetMenuBar(menuBar)
#命令
wx.EVT_MENU(self, 101, self.OnOpen)
wx.EVT_MENU(self, 103, self.OnClose)
wx.EVT_MENU(self, 109, self.OnQuit)
wx.EVT_MENU(self, 201, self.ZoomIn)
wx.EVT_MENU(self, 202, self.ZoomOut)
wx.EVT_MENU(self, 203, self.ZoomPan)
wx.EVT_MENU(self, 204, self.ZoomAll)
wx.EVT_MENU(self, 311, self.OnLine)
wx.EVT_MENU(self, 312, self.OnPolygon)
def OnOpen(self, event):
dialog = wx.FileDialog(None, '打开Shape文件', '.', '', 'Shape File (*.shp)|*.shp|All Files (*.*)|*.*', style = wx.OPEN )
if dialog.ShowModal() == wx.ID_OK:
self.sketch.color = wx.Colour(random.randrange(0,255),random.randrange(0,255),random.randrange(0,255))
self.sketch.brush = wx.Brush(self.sketch.color)
self.sketch.addLayer(dialog.GetPath(), self.sketch.pen, self.sketch.brush)
dialog.Destroy()
def OnClose(self, event):
self.sketch.SetLayers([])
self.sketch.extent = []
def OnQuit(self, event):
dlg = wx.MessageDialog(None,'确定退出?','提示',wx.YES_NO|wx.ICON_QUESTION)
result = dlg.ShowModal()
if result == wx.ID_YES:
self.Close()
dlg.Destroy()
def OnLine(self, event):
self.sketch.lineColor()
def OnPolygon(self, event):
self.sketch.polygonColor()
def ZoomIn(self, event):
self.sketch.ratio=self.sketch.ratio*2
self.sketch.reInitBuffer = True
def ZoomOut(self, event):
self.sketch.ratio=self.sketch.ratio/2
self.sketch.reInitBuffer = True
def ZoomPan(self, event):
#self.sketch.pos = [i+10 for i in self.sketch.pos]
self.sketch.reInitBuffer = True
def ZoomAll(self, event):
self.sketch.pos = [0,0]
self.sketch.OnSize(event)
class sketchWindow(wx.Window):
def __init__(self, parent, ID):
wx.Window.__init__(self, parent, ID)
self.SetBackgroundColour('White')
#默认设置
self.color = 'Black'
self.brush = wx.Brush('Blue')
self.thickness = 2
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
self.pos = (0, 0)
self.size = []
self.extent = []
self.ratio = 0.0
#图层设置
self.geometry = []
self.layer = []
self.layers = []
#初始化
self.InitBuffer()
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_IDLE, self.OnIdle)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
def OnSize(self, event):
self.size = self.GetClientSize()
if self.extent: self.SetExtent(self.extent)
self.reInitBuffer = True
def OnIdle(self, event):
if self.reInitBuffer:
self.InitBuffer()
self.Refresh(False)
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self, self.buffer)
def InitBuffer(self):
self.size = self.GetClientSize()
self.buffer = wx.EmptyBitmap(self.size.width, self.size.height)
dc = wx.BufferedDC(None, self.buffer)
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.Clear()
self.DrawLayers(dc)
#重设变量状态
self.reInitBuffer = False
def SetExtent(self, Extent):
if self.extent == []:
for i in range(4): self.extent.append(Extent[i])
else:
if Extent[0] < self.extent[0]: self.extent[0] = Extent[0]
if Extent[1] > self.extent[1]: self.extent[1] = Extent[1]
if Extent[2] < self.extent[2]: self.extent[2] = Extent[2]
if Extent[3] > self.extent[3]: self.extent[3] = Extent[3]
#wx.MessageDialog(None,str(self.extent)).ShowModal()
RatioX = self.size.width / (self.extent[1] - self.extent[0])
RatioY = self.size.height / (self.extent[3] - self.extent[2])
if RatioX < RatioY:
self.ratio = RatioX
else:
self.ratio = RatioY
def GetLayers(self):
return self.layers[:]
def SetLayers(self, layers):
self.layers = layers[:]
self.InitBuffer()
self.Refresh()
def DrawLayers(self, dc):
for name, pen, brush, layer in self.layers:
self.pen = pen
self.brush = brush
for OID, type, geometry in layer:
self.geometry = []
for coords in geometry:
x = (coords[0]-self.extent[0]/2-self.extent[1]/2)*self.ratio+self.size.width/2+self.pos[0]
y = self.size.height-(coords[1]-self.extent[2]/2-self.extent[3]/2)*self.ratio-self.size.height/2-self.pos[1]
self.geometry.append((x,y))
if type == 'D':
dc.DrawPointList(self.geometry)
if type == 'L':
dc.DrawLines(self.geometry)
if type == 'P':
dc.SetBrush(self.brush)
dc.DrawPolygon(self.geometry)
else: pass
def addFeature(self, list, type, OID):
self.geometry = []
while len(list):
y = list.pop()
x = list.pop()
self.geometry.append((x,y))
self.layer.append((OID, type, self.geometry))
#self.reInitBuffer = True
def addLayer(self, fileIn, pen, brush):
self.layer = []
shpFile=ogr.Open(str(fileIn))
shpLayer=shpFile.GetLayer()
shpExtent=shpLayer.GetExtent()
self.SetExtent(shpExtent)
shpFeature=shpLayer.GetNextFeature()
while shpFeature:
geoFeature=shpFeature.GetGeometryRef()
geoWKB=geoFeature.ExportToWkb()
geoList=WkbUnPacker(geoWKB)
if geoList[1]==1:
tmpList=[]
tmpList.extend(geoList[2])
self.addFeature(tmpList,'D',shpFeature.GetFID())
#print 'single dot'
if geoList[1]==2:
tmpList=geoList[2].tolist()
self.addFeature(tmpList,'L',shpFeature.GetFID())
#print 'single polyline'
if geoList[1]==3:
tmpList=geoList[2][0].tolist()
tmpList.extend(tmpList[:2])
self.addFeature(tmpList,'P',shpFeature.GetFID())
#print 'single polygon'
if geoList[1]==4:
for i in range(len(geoList[2])):
tmpList=[]
tmpList.extend(geoList[2][i])
self.addFeature(tmpList,'D',shpFeature.GetFID())
#print 'multi dots '+str(len(geoList[2]))
if geoList[1]==5:
for i in range(len(geoList[2])):
tmpList=geoList[2][i].tolist()
self.addFeature(tmpList,'L',shpFeature.GetFID())
#print 'multi polylines '+str(len(geoList[2]))
if geoList[1]==6:
for i in range(len(geoList[2])):
tmpList=geoList[2][i][0].tolist()
tmpList.extend(tmpList[:2])
self.addFeature(tmpList,'P',shpFeature.GetFID())
#print 'multi polygons '+str(len(geoList[2]))
else:
pass
shpFeature=shpLayer.GetNextFeature()
self.layers.append((shpLayer.GetName(), pen, brush, self.layer))
self.reInitBuffer = True
def lineColor(self):
colorData = wx.ColourData()
colorData.SetColour(self.color)
dlg = wx.ColourDialog(self, colorData)
if dlg.ShowModal() == wx.ID_OK:
colorData = dlg.GetColourData()
self.SetColor(colorData.GetColour())
dlg.Destroy()
def polygonColor(self):
colorData = wx.ColourData()
colorData.SetColour(self.brush.GetColour())
dlg = wx.ColourDialog(self, colorData)
if dlg.ShowModal() == wx.ID_OK:
colorData = dlg.GetColourData()
self.brush = wx.Brush(colorData.GetColour())
dlg.Destroy()
def SetColor(self, color):
self.color = color
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
def SetThickness(self, num):
self.thickness = num
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
def OnLeftDown(self, event):
self.oldx = event.GetPositionTuple()[0]
self.oldy = event.GetPositionTuple()[1]
self.CaptureMouse()
self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
def OnLeftUp(self, event):
if self.HasCapture():
self.newx = event.GetPositionTuple()[0]
self.newy = event.GetPositionTuple()[1]
self.pos = (self.newx-self.oldx+self.pos[0], self.oldy-self.newy+self.pos[1])
self.ReleaseMouse()
self.reInitBuffer = True
self.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = guiFrame(None)
frame.Show()
app.MainLoop()
#-*- encoding:GBK -*-
import sys,os,string
import wx
import random
from wkb import *
class guiFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, 'tri-S: Sketch Shape Show', size=(1000,690))
self.sketch = sketchWindow(self, -1)
self.Center()
#菜单
menuBar=wx.MenuBar()
mFile=wx.Menu()
mFile.Append(101, '打开(&O)', '打开文件')
mFile.Append(102, '保存(&S)', '保存文件')
mFile.Append(103, '关闭(&C)', '关闭文件')
mFile.AppendSeparator()
mFile.Append(109, '退出(&X)', '退出系统')
menuBar.Append(mFile, '文件(&F)')
mView=wx.Menu()
mView.Append(201, '放大(&I)', '放大视图')
mView.Append(202, '缩小(&O)', '缩小视图')
mView.Append(203, '平移(&P)', '平移视图')
mView.Append(204, '全图(&E)', '整个视图')
menuBar.Append(mView, '视图(&V)')
mLayer=wx.Menu()
mLayer.Append(301, '列表(&L)', '图层列表')
mLayer.AppendSeparator()
mLayer.Append(311, '线划(&L)', '线段样式')
mLayer.Append(312, '填充(&S)', '填充样式')
mLayer.Append(313, '线宽(&T)', '边线宽度')
mLayer.Append(314, '线型(&M)', '边线形状')
menuBar.Append(mLayer, '图层(&L)')
self.SetMenuBar(menuBar)
#命令
wx.EVT_MENU(self, 101, self.OnOpen)
wx.EVT_MENU(self, 103, self.OnClose)
wx.EVT_MENU(self, 109, self.OnQuit)
wx.EVT_MENU(self, 201, self.ZoomIn)
wx.EVT_MENU(self, 202, self.ZoomOut)
wx.EVT_MENU(self, 203, self.ZoomPan)
wx.EVT_MENU(self, 204, self.ZoomAll)
wx.EVT_MENU(self, 311, self.OnLine)
wx.EVT_MENU(self, 312, self.OnPolygon)
def OnOpen(self, event):
dialog = wx.FileDialog(None, '打开Shape文件', '.', '', 'Shape File (*.shp)|*.shp|All Files (*.*)|*.*', style = wx.OPEN )
if dialog.ShowModal() == wx.ID_OK:
self.sketch.color = wx.Colour(random.randrange(0,255),random.randrange(0,255),random.randrange(0,255))
self.sketch.brush = wx.Brush(self.sketch.color)
self.sketch.addLayer(dialog.GetPath(), self.sketch.pen, self.sketch.brush)
dialog.Destroy()
def OnClose(self, event):
self.sketch.SetLayers([])
self.sketch.extent = []
def OnQuit(self, event):
dlg = wx.MessageDialog(None,'确定退出?','提示',wx.YES_NO|wx.ICON_QUESTION)
result = dlg.ShowModal()
if result == wx.ID_YES:
self.Close()
dlg.Destroy()
def OnLine(self, event):
self.sketch.lineColor()
def OnPolygon(self, event):
self.sketch.polygonColor()
def ZoomIn(self, event):
self.sketch.ratio=self.sketch.ratio*2
self.sketch.reInitBuffer = True
def ZoomOut(self, event):
self.sketch.ratio=self.sketch.ratio/2
self.sketch.reInitBuffer = True
def ZoomPan(self, event):
#self.sketch.pos = [i+10 for i in self.sketch.pos]
self.sketch.reInitBuffer = True
def ZoomAll(self, event):
self.sketch.pos = [0,0]
self.sketch.OnSize(event)
class sketchWindow(wx.Window):
def __init__(self, parent, ID):
wx.Window.__init__(self, parent, ID)
self.SetBackgroundColour('White')
#默认设置
self.color = 'Black'
self.brush = wx.Brush('Blue')
self.thickness = 2
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
self.pos = (0, 0)
self.size = []
self.extent = []
self.ratio = 0.0
#图层设置
self.geometry = []
self.layer = []
self.layers = []
#初始化
self.InitBuffer()
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_IDLE, self.OnIdle)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
def OnSize(self, event):
self.size = self.GetClientSize()
if self.extent: self.SetExtent(self.extent)
self.reInitBuffer = True
def OnIdle(self, event):
if self.reInitBuffer:
self.InitBuffer()
self.Refresh(False)
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self, self.buffer)
def InitBuffer(self):
self.size = self.GetClientSize()
self.buffer = wx.EmptyBitmap(self.size.width, self.size.height)
dc = wx.BufferedDC(None, self.buffer)
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.Clear()
self.DrawLayers(dc)
#重设变量状态
self.reInitBuffer = False
def SetExtent(self, Extent):
if self.extent == []:
for i in range(4): self.extent.append(Extent[i])
else:
if Extent[0] < self.extent[0]: self.extent[0] = Extent[0]
if Extent[1] > self.extent[1]: self.extent[1] = Extent[1]
if Extent[2] < self.extent[2]: self.extent[2] = Extent[2]
if Extent[3] > self.extent[3]: self.extent[3] = Extent[3]
#wx.MessageDialog(None,str(self.extent)).ShowModal()
RatioX = self.size.width / (self.extent[1] - self.extent[0])
RatioY = self.size.height / (self.extent[3] - self.extent[2])
if RatioX < RatioY:
self.ratio = RatioX
else:
self.ratio = RatioY
def GetLayers(self):
return self.layers[:]
def SetLayers(self, layers):
self.layers = layers[:]
self.InitBuffer()
self.Refresh()
def DrawLayers(self, dc):
for name, pen, brush, layer in self.layers:
self.pen = pen
self.brush = brush
for OID, type, geometry in layer:
self.geometry = []
for coords in geometry:
x = (coords[0]-self.extent[0]/2-self.extent[1]/2)*self.ratio+self.size.width/2+self.pos[0]
y = self.size.height-(coords[1]-self.extent[2]/2-self.extent[3]/2)*self.ratio-self.size.height/2-self.pos[1]
self.geometry.append((x,y))
if type == 'D':
dc.DrawPointList(self.geometry)
if type == 'L':
dc.DrawLines(self.geometry)
if type == 'P':
dc.SetBrush(self.brush)
dc.DrawPolygon(self.geometry)
else: pass
def addFeature(self, list, type, OID):
self.geometry = []
while len(list):
y = list.pop()
x = list.pop()
self.geometry.append((x,y))
self.layer.append((OID, type, self.geometry))
#self.reInitBuffer = True
def addLayer(self, fileIn, pen, brush):
self.layer = []
shpFile=ogr.Open(str(fileIn))
shpLayer=shpFile.GetLayer()
shpExtent=shpLayer.GetExtent()
self.SetExtent(shpExtent)
shpFeature=shpLayer.GetNextFeature()
while shpFeature:
geoFeature=shpFeature.GetGeometryRef()
geoWKB=geoFeature.ExportToWkb()
geoList=WkbUnPacker(geoWKB)
if geoList[1]==1:
tmpList=[]
tmpList.extend(geoList[2])
self.addFeature(tmpList,'D',shpFeature.GetFID())
#print 'single dot'
if geoList[1]==2:
tmpList=geoList[2].tolist()
self.addFeature(tmpList,'L',shpFeature.GetFID())
#print 'single polyline'
if geoList[1]==3:
tmpList=geoList[2][0].tolist()
tmpList.extend(tmpList[:2])
self.addFeature(tmpList,'P',shpFeature.GetFID())
#print 'single polygon'
if geoList[1]==4:
for i in range(len(geoList[2])):
tmpList=[]
tmpList.extend(geoList[2][i])
self.addFeature(tmpList,'D',shpFeature.GetFID())
#print 'multi dots '+str(len(geoList[2]))
if geoList[1]==5:
for i in range(len(geoList[2])):
tmpList=geoList[2][i].tolist()
self.addFeature(tmpList,'L',shpFeature.GetFID())
#print 'multi polylines '+str(len(geoList[2]))
if geoList[1]==6:
for i in range(len(geoList[2])):
tmpList=geoList[2][i][0].tolist()
tmpList.extend(tmpList[:2])
self.addFeature(tmpList,'P',shpFeature.GetFID())
#print 'multi polygons '+str(len(geoList[2]))
else:
pass
shpFeature=shpLayer.GetNextFeature()
self.layers.append((shpLayer.GetName(), pen, brush, self.layer))
self.reInitBuffer = True
def lineColor(self):
colorData = wx.ColourData()
colorData.SetColour(self.color)
dlg = wx.ColourDialog(self, colorData)
if dlg.ShowModal() == wx.ID_OK:
colorData = dlg.GetColourData()
self.SetColor(colorData.GetColour())
dlg.Destroy()
def polygonColor(self):
colorData = wx.ColourData()
colorData.SetColour(self.brush.GetColour())
dlg = wx.ColourDialog(self, colorData)
if dlg.ShowModal() == wx.ID_OK:
colorData = dlg.GetColourData()
self.brush = wx.Brush(colorData.GetColour())
dlg.Destroy()
def SetColor(self, color):
self.color = color
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
def SetThickness(self, num):
self.thickness = num
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
def OnLeftDown(self, event):
self.oldx = event.GetPositionTuple()[0]
self.oldy = event.GetPositionTuple()[1]
self.CaptureMouse()
self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
def OnLeftUp(self, event):
if self.HasCapture():
self.newx = event.GetPositionTuple()[0]
self.newy = event.GetPositionTuple()[1]
self.pos = (self.newx-self.oldx+self.pos[0], self.oldy-self.newy+self.pos[1])
self.ReleaseMouse()
self.reInitBuffer = True
self.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = guiFrame(None)
frame.Show()
app.MainLoop()
enjoy~