How to display a map with Python?

11040
2
10-28-2012 09:14 PM
PratikMehta
New Contributor
Good Morning Everyone,

I am working on a project and i am making a desktop based application using Python. I have made models with ArcGIS 10 and with Tkinter i am making GUI. I wanted to display a shapefile when i click on submit button. How can i display a shapefile with python code?

With Python Shapefile Library we can read and write into the shapefile, but that is not i want. Please help me with this.

Regards
Pratik Mehta
Tags (2)
0 Kudos
2 Replies
MathewCoyle
Frequent Contributor
You want to display the shapefile geographic data in your tkinter GUI outside of ArcMap? You would have to use some kind of drawing module. You could use something like Canvas in Tkinter with some geometry fiddling.
0 Kudos
RoryHall
New Contributor III
I might be a bit late with this reply, but I have had success by using mapnik to symbolize the shapefile and export this as a jpeg. You then can load the jpg into a Tkinter canvas or even a label using Photo Imaging Library PIL.
Below is a bit of code that could give you some ideas. I am by no means a programmer, but I found this fairly straight forward. This creates a TKinter GUI and loads the image of the shapefile onto a canvas widget. It might be a bit of an overkill as it creates a map using 3 layers, but can be easily converted just to show one. I have used this method to show a resulted shapefile from some geoprocessing outside of an ArcMap session.

import mapnik
from Tkinter import *
from PIL import Image, ImageTk
import os

class MyFrame(Frame):
    def __init__(self):
        Frame.__init__(self)

        self.master.title("Shapefile Viewer")
      
        self.iframe = Frame (width = 900, height = 900, bd= 1, relief = SUNKEN)
        self.iframe.grid (row = 0, column = 1)

        self.iframe2 = Frame (width = 400, height = 110, bd= 1, relief = SUNKEN)
        self.iframe2.grid (row = 1, column = 1)
       
        self.Canvas = Canvas (width = 890, height = 890, bg = "White")
        self.Canvas.grid(row = 0, column = 1)

    def labels(self):
       
        self.Label_01 = Label(text = "                      Map generated by Mapnik                             ")
        self.Label_01.grid(row = 0, column =0, sticky = N)
        self.Label_02 = Label(text = "                         ........                         ")
        self.Label_02.grid(row = 1, column =0)

    def output (self):
        self.TextBox_01 =Text(height=6,width=48,background='steelblue')
        self.TextBox_01.grid(row = 1, column = 1, sticky = W, padx = 5, pady = 5)
        self.TextBox_01.insert(END, "Message dialog: ....")
        self.Scroll_01 = Scrollbar (command = self.TextBox_01.yview)
        self.TextBox_01.configure(yscrollcommand = self.Scroll_01.set)
        self.Scroll_01.grid(row = 1, column = 1, sticky = N+S+E, pady = 5, padx = 5)       

frame01 = MyFrame()
frame01.labels()
frame01.output()

directory = "C:/MapnikTemp"
if not os.path.exists(directory):
    os.makedirs(directory)

# map parameters   
map1 = mapnik.Map(880,880)
map1.background = mapnik.Color('lightblue')

baseStyle = mapnik.Style()
streamsStyle = mapnik.Style()
townsPointStyle = mapnik.Style()
townsLabelStyle = mapnik.Style()

##---------------------------------------------------
baseRule = mapnik.Rule()
polygon_symbolizer = mapnik.PolygonSymbolizer(mapnik.Color('snow'))
baseRule.symbols.append(polygon_symbolizer)
line_symbolizer1 = mapnik.LineSymbolizer(mapnik.Color('grey'),0.2)  
baseRule.symbols.append(line_symbolizer1)

# Note the difference in how to query in Mapnik2
basinsLabels = mapnik.TextSymbolizer(mapnik.Expression ('[SUB_NAME]'), 'DejaVu Sans Bold',12,mapnik.Color('black'))
basinsLabels.halo_fill = mapnik.Color ('yellow')
basinsLabels.halo_radius = 2
baseRule.symbols.append(basinsLabels)
##----------------------------------------------------

streamsRule = mapnik.Rule()
line_symbolizer2 = mapnik.LineSymbolizer(mapnik.Color('blue'),0.5)  
streamsRule.symbols.append(line_symbolizer2)

##----------------------------------------------------

townsPointRule = mapnik.Rule()
townsPoint = mapnik.PointSymbolizer()
townsPoint.allow_overlap = True
townsPointRule.symbols.append(townsPoint)

townsLabelsRule = mapnik.Rule()
townsLabels = mapnik.TextSymbolizer(mapnik.Expression ('[NAME]'),'DejaVu Sans Bold',6, mapnik.Color('black'))
townsLabels.allow_overlap = True
townsLabels.displacement = (10, -10)
townsLabelsRule.symbols.append(townsLabels)

# Apply Rules to Styles
baseStyle.rules.append(baseRule)
streamsStyle.rules.append(streamsRule)
townsPointStyle.rules.append(townsPointRule)
townsLabelStyle.rules.append(townsLabelsRule)

# Append Syles to map
map1.append_style('Base Style',baseStyle)
map1.append_style('Streams Style',streamsStyle)
map1.append_style('Towns Point Style',townsPointStyle)
map1.append_style('Towns Label Style',townsLabelStyle)

dataset1 = mapnik.Shapefile(file='FitzroyClip_subbasins.shp')
dataset2 = mapnik.Shapefile(file='FBA_Streams1.shp')
dataset3 = mapnik.Shapefile(file='FitzroyClip_towns.shp')

# Layers, add data source, apply style to layer
layer1 = mapnik.Layer('FBA SubBasins')
layer1.datasource = dataset1
layer1.styles.append('Base Style')

layer2 = mapnik.Layer('FBA Streams')
layer2.datasource = dataset2
layer2.styles.append('Streams Style')

layer3 = mapnik.Layer('FBA Towns')
layer3.datasource = dataset3
layer3.styles.append('Towns Point Style')

layer4 = mapnik.Layer('FBA Towns labels')
layer4.datasource = dataset3
layer4.styles.append('Towns Label Style')

# Add Layers to map
map1.layers.append(layer1)
map1.layers.append(layer2)
map1.layers.append(layer3)
map1.layers.append(layer4)

# Zoom to map extent
map1.zoom_all()

mapnik.render_to_file(map1,directory +'\FBA_multipleLayers.png', 'png')

print "rendered image to 'FBA_multipleLayers.png'"

im = Image.open(directory +'\FBA_multipleLayers.png')

tk_im = ImageTk.PhotoImage(im)

# To centre png on canvas. Canvas size / 2 + 2
frame01.Canvas.create_image(445, 445, image = tk_im)

# Create Frame object
frame01.mainloop()

Hope it sheds a bit of light on what can be done with Tkinter 🙂
0 Kudos