奇忠诚 发表于 2015-4-24 07:26:59

用Python做GIS:翻炒篇

  今日得暇,对之前的程序进行了小幅度修改
  读取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 =
      self.sketch.reInitBuffer = True

    def ZoomAll(self, event):
      self.sketch.pos =
      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)
      else:
            if Extent < self.extent:self.extent = Extent
            if Extent > self.extent:self.extent = Extent
            if Extent < self.extent:self.extent = Extent
            if Extent > self.extent:self.extent = Extent
      #wx.MessageDialog(None,str(self.extent)).ShowModal()
      RatioX = self.size.width / (self.extent - self.extent)
      RatioY = self.size.height / (self.extent - self.extent)
      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-self.extent/2-self.extent/2)*self.ratio+self.size.width/2+self.pos
                  y = self.size.height-(coords-self.extent/2-self.extent/2)*self.ratio-self.size.height/2-self.pos
                  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:
                tmpList=[]
                tmpList.extend(geoList)
                self.addFeature(tmpList,'D',shpFeature.GetFID())
                #print 'single dot'
            if geoList==2:
                tmpList=geoList.tolist()
                self.addFeature(tmpList,'L',shpFeature.GetFID())
                #print 'single polyline'
            if geoList==3:
                tmpList=geoList.tolist()
                tmpList.extend(tmpList[:2])
                self.addFeature(tmpList,'P',shpFeature.GetFID())
                #print 'single polygon'
            if geoList==4:
                for i in range(len(geoList)):
                  tmpList=[]
                  tmpList.extend(geoList)
                  self.addFeature(tmpList,'D',shpFeature.GetFID())
                #print 'multi dots '+str(len(geoList))
            if geoList==5:
                for i in range(len(geoList)):
                  tmpList=geoList.tolist()
                  self.addFeature(tmpList,'L',shpFeature.GetFID())
                #print 'multi polylines '+str(len(geoList))
            if geoList==6:
                for i in range(len(geoList)):
                  tmpList=geoList.tolist()
                  tmpList.extend(tmpList[:2])
                  self.addFeature(tmpList,'P',shpFeature.GetFID())
                #print 'multi polygons '+str(len(geoList))
            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()
      self.oldy = event.GetPositionTuple()
      self.CaptureMouse()
      self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
      
    def OnLeftUp(self, event):
      if self.HasCapture():
            self.newx = event.GetPositionTuple()
            self.newy = event.GetPositionTuple()
            self.pos = (self.newx-self.oldx+self.pos, self.oldy-self.newy+self.pos)
            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~
页: [1]
查看完整版本: 用Python做GIS:翻炒篇