Difference between revisions of "CSC111 Lab 11 2015b"

From dftwiki3
Jump to: navigation, search
 
(7 intermediate revisions by the same user not shown)
Line 2: Line 2:
 
----
 
----
 
<br />
 
<br />
 +
<showafterdate after="20151118 12:00" before="20151231 00:00">
 
=<center>A Map-Digitizer Tool</center>=
 
=<center>A Map-Digitizer Tool</center>=
 
<br />
 
<br />
Line 28: Line 29:
  
 
=GIF Image for Digitizer=
 
=GIF Image for Digitizer=
 +
<br />
 +
This map you should use is below, and was generated by Emily Kim.  It is available on the Smith GIS Web pages, maintained by Jon Caris. 
 
<br />
 
<br />
 
[[Image:SmithMap0.gif|center|500px]]
 
[[Image:SmithMap0.gif|center|500px]]
Line 61: Line 64:
 
<br />
 
<br />
 
* The PDF for all the graphics objects in Zelle's graphics library can be found [http://mcsp.wartburg.edu/zelle/python/graphics/graphics.pdf  here].
 
* The PDF for all the graphics objects in Zelle's graphics library can be found [http://mcsp.wartburg.edu/zelle/python/graphics/graphics.pdf  here].
 +
* In case you are interested in the file containing the years of construction for all the Smith buildings, it can be found [[Smith_College_Building_Construction_Dates|here]].
 
<br />
 
<br />
 
=Moodle Submission=
 
=Moodle Submission=
 
<br />
 
<br />
* Submit your digitizer tool to Moodle.   
+
* '''Submit''' your digitizer tool to Moodle.   
 
* You will not be able to evaluate the tool, as it uses the graphics library, which Moodle does not know how to handle.  But make sure your tool can be run if needed.  Incomplete programs, or programs that crash will be given a failing grade.
 
* You will not be able to evaluate the tool, as it uses the graphics library, which Moodle does not know how to handle.  But make sure your tool can be run if needed.  Incomplete programs, or programs that crash will be given a failing grade.
* Submit a copy of the CSV file generated by your tool.
+
* '''Submit''' a copy of the CSV file generated by your tool.
 +
<br />
 +
=Sharing Your CSV=
 
<br />
 
<br />
 +
* You should all have received an email via Google about dthiebaut@smith.edu sharing a file with you.  It's name is SmithMap.csv, and you should paste the data generated by your Python tool to this file, making sure the information follows the format we have selected in class.
 +
* For completeness, the link to the shared file is [https://docs.google.com/a/smith.edu/document/d/19fregdyl0jgCCEKJhc__9faUZqGyB_lQRAJXkb-FeEE/edit?usp=sharing here].
 +
</showafterdate>
 
<br />
 
<br />
 
<br />
 
<br />
Line 77: Line 86:
 
<br />
 
<br />
 
<source lang="python">
 
<source lang="python">
 +
 
# Lab12_solution.py
 
# Lab12_solution.py
 
# D. Thiebaut
 
# D. Thiebaut
Line 132: Line 142:
 
# Functions
 
# Functions
 
#---------------------------------------------------------------
 
#---------------------------------------------------------------
def recordPointsToCSV( listPoints ):
+
def recordPointsToCSV( buildingName, listPoints ):
 
     """records the list of points in a CSV file.  The points
 
     """records the list of points in a CSV file.  The points
 
     are graphics points, as defined in the graphics library."""
 
     are graphics points, as defined in the graphics library."""
Line 142: Line 152:
 
     # store additional information at the front of each line
 
     # store additional information at the front of each line
 
     # according to the decision made in class
 
     # according to the decision made in class
     s = "building, 11/14/15, DT,"
+
     s = "building, " + buildingName + ", 11/14/15, DT,"
 
     for p in listPoints:
 
     for p in listPoints:
 
         x = p.getX()
 
         x = p.getX()
Line 181: Line 191:
 
     stop.draw( win )
 
     stop.draw( win )
  
     # create an empty list of points
+
     # create an empty list of points, and a dummy building name
 
     listPoints = []
 
     listPoints = []
 +
    buildingName = ""
  
 
     # animation loop
 
     # animation loop
Line 198: Line 209:
 
         if record.isClicked( clickedPoint ):
 
         if record.isClicked( clickedPoint ):
 
             listPoints = []
 
             listPoints = []
 +
            buildingName = input( "Building name? " )
 
             continue
 
             continue
  
Line 204: Line 216:
 
             # yes, record points accumulated and display
 
             # yes, record points accumulated and display
 
             # polygon for feedback.
 
             # polygon for feedback.
             recordPointsToCSV( listPoints )
+
             recordPointsToCSV( buildingName, listPoints )
 
             displayPolygonBack( win, listPoints )
 
             displayPolygonBack( win, listPoints )
 
             listPoints = []
 
             listPoints = []
Line 218: Line 230:
 
          
 
          
 
     # We currently will not reach this point, as there is
 
     # We currently will not reach this point, as there is
     # no way to escape the while loop.  A good idear would be
+
     # no way to escape the while loop.  A good idea would be
 
     # to add an exit button.
 
     # to add an exit button.
 
     win.getMouse()
 
     win.getMouse()
Line 224: Line 236:
  
 
main()
 
main()
 +
 +
 +
 +
 +
  
 
</source>
 
</source>

Latest revision as of 09:32, 23 November 2015

--D. Thiebaut (talk) 10:50, 14 November 2015 (EST)



<showafterdate after="20151118 12:00" before="20151231 00:00">

A Map-Digitizer Tool


The purpose of this lab is to crowd-source a CSV file that will be used in the homework to create a color-coded map of the Smith College buildings, along with other map elements of your choice. We will view the program that you create in this lab as a tool used to create data in a well-defined format. The program you will create in the homework will be more sophisticated, and we will refer to it as an application, which will deserve closer attention to details.
The due date for submitting the lab is, as usual, Friday at 11:55 p.m. (11/20/15).



Lab Assignment


Your task today is to create a Python tool that:

  1. loads up a gif image representing the Smith College campus. The map can be found below. You’ll have to click on it twice before it appears by itself in your browser, at which point you can save the image to your computer.
  2. The tool creates a user interface (UI) with one or several buttons. The buttons will allow the user to clearly define the action of digitizing an element of the map. You are free to define how your buttons operate. A possible option is to have a Start and Stop button, but you may want to define your UI differently.
  3. When the digitization starts, your tool will
  1. prompt the user for the name of the map element you are about to digitize (e.g. "Tree", "Ford Hall"), and
  2. allow the you and your partner to record the coordinates of several points in a list.
  1. Upon indicating to your tool that the collection of the given item is over, it will store each list of points in a CSV file.
  2. The format of your CSV file should be the format that we will have selected in class (Monday/Wednesday lectures)
  3. Once you have recorded a sufficient number of map elements, stop the tool, and copy/paste the contents of your CSV file to the shared Google doc we’ll use for this LAM.


GIF Image for Digitizer


This map you should use is below, and was generated by Emily Kim. It is available on the Smith GIS Web pages, maintained by Jon Caris.

SmithMap0.gif



Quadrants


SmithMap0Quadants.png


  • The figure above divides the map into 4 quadrants.
  • The Wed 1-3 group will digitize map elements from Quadrant 1.
  • The Thu 1-3 group will digitize map elements from Quadrant 2.
  • The Thu 3-5 group will digitize map elements from Quadrant 3.
  • The last group will digitize map elements from Quadrant 4.


FYI, the quadrant lines are generated as follows:

    # draw quadrant lines (for lab only)
    line1 = Line( Point(0, 6*HEIGHT//10 ), Point( WIDTH, 6*HEIGHT//10 ) )
    line1.setWidth( 2 )
    line1.setOutline( "orange" )
    line1.draw( win )

    line2 = Line( Point(WIDTH//2, 0), Point( WIDTH//2, HEIGHT ) )
    line2.setWidth( 2 )
    line2.setOutline( "orange" )
    line2.draw( win )

Reference


  • The PDF for all the graphics objects in Zelle's graphics library can be found here.
  • In case you are interested in the file containing the years of construction for all the Smith buildings, it can be found here.


Moodle Submission


  • Submit your digitizer tool to Moodle.
  • You will not be able to evaluate the tool, as it uses the graphics library, which Moodle does not know how to handle. But make sure your tool can be run if needed. Incomplete programs, or programs that crash will be given a failing grade.
  • Submit a copy of the CSV file generated by your tool.


Sharing Your CSV


  • You should all have received an email via Google about dthiebaut@smith.edu sharing a file with you. It's name is SmithMap.csv, and you should paste the data generated by your Python tool to this file, making sure the information follows the format we have selected in class.
  • For completeness, the link to the shared file is here.

</showafterdate>


<showafterdate after="20151121 00:00" before="20151231 00:00">

Solution Program


# Lab12_solution.py
# D. Thiebaut
# Solution program for Lab 12.
# This program allows one to digitize several elements of
# a map of the campus, which already contains several elements
# such as buildings, roads, parkings, and rivers.

from graphics import *

# Global variables
WIDTH = 750
HEIGHT = 730
CSV = "lab12map.csv"
MAP = "SmithMap0.gif"

class Button:
    """Implements a button, which contains a label (text),
    is rectangular (frame), and can be clicked (True) or not clicked."""
    
    def __init__(self, x1, y1, w, h, text ):
        """constructor: pass (x,y) of top left corner,
        and width and height.  Pass the text displayed in
        button."""
        p1 = Point( x1, y1 )
        p2 = Point( x1+w, y1+h )
        self.frame = Rectangle( p1, p2 )
        self.frame.setFill( "white" )
        self.label = Text(Point( x1+w//2, y1+h//2 ), text )
        self.clicked = False
        
    def draw( self, win ):
        """display button on window."""
        self.frame.draw( win )
        self.label.draw( win )

    def isClicked( self, p ):
        """Checks if p is inside the frame of the button.  Returns True
        if p inside frame, False otherwise.  If p inside, button
        changes state and color."""
        x1, y1 = self.frame.getP1().getX(), self.frame.getP1().getY()
        x2, y2 = self.frame.getP2().getX(), self.frame.getP2().getY()
        
        if x1 <= p.getX() <= x2 and y1 <= p.getY() <= y2:
            self.clicked = not self.clicked
            if self.clicked:
                self.frame.setFill( "yellow" )
            else:
                self.frame.setFill( "white" )
            return True
        else:
            return False

#---------------------------------------------------------------
# Functions
#---------------------------------------------------------------
def recordPointsToCSV( buildingName, listPoints ):
    """records the list of points in a CSV file.  The points
    are graphics points, as defined in the graphics library."""
    global CSV # the file name

    # open the file and append to the data already in it
    file = open( CSV, "a" )

    # store additional information at the front of each line
    # according to the decision made in class
    s = "building, " + buildingName + ", 11/14/15, DT,"
    for p in listPoints:
        x = p.getX()
        y = p.getY()
        s = s + "{0:1}, ".format( x )
        s = s + "{0:1}, ".format( y )
    s = s[0:-2] # remove last comma
    file.write( s + "\n" )
    file.close()

def displayPolygonBack( win, listPoints ):
    """ given a list of graphic points, display the
    polygon associated with the points. Color set to
    light-blue.  Provides feedback to user.
    """
    p = Polygon( listPoints )
    p.setFill( "lightblue" )
    p.draw( win )

def main():
    """The main interactive function.  Declare the graphic
    window, populate it with a map and 2 buttons, and allows
    the user to enter different polygons."""
    global WIDTH, HEIGHT, MAP

    # create graphic window.  make it the size of the map.
    win = GraphWin( "Lab 12", WIDTH, HEIGHT )

    # display background image
    map = Image( Point( WIDTH//2, HEIGHT//2 ), MAP )
    map.draw( win )

    # create 2 buttons to start recording and record points to
    # csv
    record = Button( 10, 10, 40, 30, "Record" )
    record.draw( win )
    stop = Button( 60, 10, 40, 30, "Stop" )
    stop.draw( win )

    # create an empty list of points, and a dummy building name
    listPoints = []
    buildingName = ""

    # animation loop
    while True:
        # has user clicked on a point?
        clickedPoint = win.checkMouse()

        # no, do nothing, keep checking
        if clickedPoint == None:
            continue

        # yes, mouse clicked.

        # was it on record button?
        if record.isClicked( clickedPoint ):
            listPoints = []
            buildingName = input( "Building name? " )
            continue

        # no.  Was it on stop button?
        if stop.isClicked( clickedPoint ):
            # yes, record points accumulated and display
            # polygon for feedback.
            recordPointsToCSV( buildingName, listPoints )
            displayPolygonBack( win, listPoints )
            listPoints = []
            continue

        # no.
        
        # if we're here, it's because the user clicked
        # outside the buttons, and we should record the
        # point in the list.
        listPoints.append( clickedPoint )

        
    # We currently will not reach this point, as there is
    # no way to escape the while loop.  A good idea would be
    # to add an exit button.
    win.getMouse()
    win.close()

main()

</showafterdate>