def __init__(self): tk.Tk.__init__(self) self.geometry(f'{WIDTH}x{HEIGHT}') self.title('GooMPy') self.canvas = tk.Canvas(self, width=WIDTH, height=HEIGHT) self.canvas.pack(fill='both') self.bind("<Key>", self.check_quit) self.bind('<B1-Motion>', self.drag) self.bind('<Button-1>', self.click) self.radiogroup = tk.Frame(self.canvas) self.radiovar = tk.IntVar() self.maptypes = ['roadmap', 'terrain', 'satellite', 'hybrid'] self.add_radio_button(0) self.add_radio_button(1) self.add_radio_button(2) self.add_radio_button(3) self.zoom_in_button = self.add_zoom_button('+', +1) self.zoom_out_button = self.add_zoom_button('-', -1) self.zoomlevel = ZOOM self.radiovar.set(0) self.goompy = GooMPy( WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, radius_meters=RADIUS) self.goompy.use_map_type(MAPTYPE) self.redraw()
def GetGPSPMAP(lat, long): ZOOM = 15 MAPTYPE = 'roadmap' goompy = GooMPy(WIDTH, HEIGHT, lat, long, ZOOM, MAPTYPE) file_jpg = goompy.getFileName() print(file_jpg) return file_jpg
def geolocation(self): self.maplist = [] self.buttonHeightCounter = .05 API_KEY = 'AIzaSyBPGAbevdKkeXaZT0ZsR0qbO30Bpqqm0Mc' google_places = GooglePlaces(API_KEY) self.query_result = google_places.nearby_search( location=self.entry.get(), radius=700, types=[types.TYPE_RESTAURANT]) self.current_places = self.query_result if self.query_result.has_attributions: print(self.query_result.html_attributions) for place in self.query_result.places: place.get_details() markers = "&markers=size:big|label:S|color:red|" + str( place.details['geometry']['location']['lat']) + "," + str( place.details['geometry']['location']['lng']) + "|" self.maplist.append(markers) print(place.name) self.button_list.append( Button(self, text=place.name, command=lambda pname=place.name: self.on_click(pname), width=25)) self.button_list[-1].place(relx=.70, rely=self.buttonHeightCounter, anchor="c") self.buttonHeightCounter += .035 print(place.formatted_address + "\n") google_maps = GoogleMaps( api_key='AIzaSyDlJqxwlOWWAPwf54ivrpAZw4R1Yb5j6Yk') location = google_maps.search( location=self.entry.get()) # sends search to Google Maps. my_location = location.first() # returns only first location. #MARKER = '&markers=color:blue' + '%' + str(7) + 'Clabel:S%' + str(7) + 'C' + str(my_location.lat) + ',' + str(my_location.lng) #MARKER = "&markers=size:big|label:S|color:blue|" + str(my_location.lat) + "," + str(my_location.lng) + "|" + \ MARKER = self.maplist[1] + self.maplist[2] + self.maplist[3] self.zoomlevel = ZOOM maptype_index = 0 self.radiovar.set(maptype_index) self.goompy = GooMPy(WIDTH, HEIGHT, my_location.lat, my_location.lng, ZOOM, MAPTYPE, MARKER) self.restart() print(self.query_result) print(str(my_location.lat)) print(str(my_location.lng))
def getMap(): global mapCurr lat, lan = getLatLan() if not lat: lat = 0 lan = 0 goompy = GooMPy(mapW, mapH, lat, lan, 20, 'roadmap') image = goompy.getImage() mapCurr = pygame.image.fromstring(image.tobytes(), image.size, image.mode)
def __init__(self, root): self.root = root self.max_height = self.root.winfo_screenheight() self.max_width = self.root.winfo_screenwidth() self.root.geometry((str(int(self.max_width/2))+"x"+str(int(self.max_height/2)))) ## self.radiogroup = Frame() ## self.root.bind("<Key>", self.user_input) ## self.root.bind("<Button>", self.user_input) self.root.bind("<Escape>", lambda e: self.root.destroy()) # The user is able to select differnt modes of transportation # They are diffined here, as well as the mechanism for storing them self.transport_mode = tk.StringVar() self.transport_mode.set("Walking") self.transport_modes = ["Walking", "Bicycling", "Driving", "Transit"] # All the locations the user is using, stored in a list self.locations = [] # The index used to calualate which locations are currently visable self.location_view = 0 # Used to limit the system from attempting to display more locations # than possible self.VIEW_SIZE = 10 # The coordinates of the current location of the user self.latitude = float( location.CURRENT_LOCATION[:location.CURRENT_LOCATION.find(",")] ) self.longitude = float( location.CURRENT_LOCATION[location.CURRENT_LOCATION.find(",")+1:] ) # The zoom level on the map self.zoom = 15 # The dimentions of the map self.map_width = 500 self.map_height = 500 # GooMPy object to act as an API self.goompy = GooMPy(self.map_width, self.map_height, self.latitude, self.longitude, self.zoom, "roadmap") self.live = False # Starts the system self._draw_UI() self.root.mainloop()
def gps_update_map(x, y, image_plot): gps_map_coordinate = [x, y] gps_map_zoom = 19 gps_map_type = 'satellite' gps_map_resolution = 1200 gps_map = GooMPy(gps_map_resolution, gps_map_resolution, gps_map_coordinate[0], gps_map_coordinate[1], gps_map_zoom, gps_map_type) gps_map_tile = gps_map.bigimage gps_map_corner_upper_left = gps_map.northwest gps_map_corner_lower_right = gps_map.southeast gps_map_width = (gps_map_corner_lower_right[1] - gps_map_corner_upper_left[1]) * 4 / 3 gps_map_height = (gps_map_corner_upper_left[0] - gps_map_corner_lower_right[0]) * 4 / 3 gps_map_aspect_ratio = gps_map_width / gps_map_height gps_map_array = np.array( gps_map_tile.resize((int(gps_map_resolution * gps_map_aspect_ratio), gps_map_resolution))) gps_map_array = np.swapaxes(gps_map_array[::-1, :], 0, 1) gps_map_effective_size = gps_map_height / gps_map_resolution image_plot.setScale(gps_map_effective_size) image_plot.setImage(gps_map_array) image_plot.setX(gps_map_corner_upper_left[1] - gps_map_width / 8) image_plot.setY(gps_map_corner_upper_left[0] - gps_map_height + gps_map_height / 8) image_plot.update()
def __init__(self): Tk.__init__(self) self.geometry('%dx%d+500+500' % (WIDTH,HEIGHT)) self.title('GooMPy') self.canvas = Canvas(self, width=WIDTH, height=HEIGHT) self.canvas.pack() self.bind("<Key>", self.check_quit) self.bind('<B1-Motion>', self.drag) self.bind('<Button-1>', self.click) self.label = Label(self.canvas) self.radiogroup = Frame(self.canvas) self.radiovar = IntVar() self.maptypes = ['OSM', 'GoogleSatellite', 'Satellite'] self.add_radio_button('OSM', 0) self.add_radio_button('GoogleSatellite', 1) self.add_radio_button('Satellite', 2) self.zoom_in_button = self.add_zoom_button('+', +1) self.zoom_out_button = self.add_zoom_button('-', -1) self.zoomlevel = ZOOM maptype_index = 0 self.radiovar.set(maptype_index) self.goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, MAPTYPE) self.restart()
def getMap(): global mapCurr mapOffline = pygame.image.load("icons/offline.jpg") lat, lan = getLatLan() if not lat: lat = 0 lan = 0 try: goompy = GooMPy(mapW, mapH, lat, lan, 20, 'roadmap') image = goompy.getImage() mapCurr = pygame.image.fromstring(image.tobytes(), image.size, image.mode) except Exception as e: mapCurr = mapOffline
def __init__(self): Tk.__init__(self) self.geometry('%dx%d+500+500' % (WIDTH, HEIGHT)) self.title('GooMPy') self.canvas = Canvas(self, width=WIDTH, height=HEIGHT) self.canvas.pack() self.bind("<Key>", self.check_quit) self.bind('<B1-Motion>', self.drag) self.bind('<Button-1>', self.click) self.label = Label(self.canvas) self.radiogroup = Frame(self.canvas) self.radiovar = IntVar() self.maptypes = [ 'satellite', 'roadmap', 'terrain', 'roadmap2', 'roadsonly', 'terrainonly', 'hybrid' ] self.add_radio_button('Satellite', 0) self.add_radio_button('Road Map', 1) self.add_radio_button('Terrain', 2) self.add_radio_button('Road Map 2', 3) self.add_radio_button('Roads Only', 4) self.add_radio_button('Terrain', 5) self.add_radio_button('Hybrid', 6) self.zoom_in_button = self.add_zoom_button('+', +1) self.zoom_out_button = self.add_zoom_button('-', -1) self.zoomlevel = ZOOM maptype_index = 0 self.radiovar.set(maptype_index) self.goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, MAPTYPE, None, 4, 1, KMLFILE) self.restart()
def update_gps_map(self, use_map=None): if type(use_map) == str: map_file = np.load(use_map) gps_map_effective_size = map_file['scale'] gps_map_array = map_file['map'] gps_map_x_position = map_file['x'] gps_map_y_position = map_file['y'] elif type(use_map) == int: path = sys.argv[0][:-8] print path, path + 'maps/map' + str(use_map) + '.npz' map_file = np.load(path + 'maps/map' + str(use_map) + '.npz') gps_map_effective_size = map_file['scale'] gps_map_array = map_file['map'] gps_map_x_position = map_file['x'] gps_map_y_position = map_file['y'] elif 'phoenix' in self.gps_positions.keys(): try: cur_pos_lon = self.gps_positions['phoenix']['pos'][0] cur_pos_lat = self.gps_positions['phoenix']['pos'][1] gps_map_coordinate = [cur_pos_lon, cur_pos_lat] gps_map_zoom = 19 gps_map_type = 'satellite' gps_map_resolution = 1200 gps_map = GooMPy(gps_map_resolution, gps_map_resolution, gps_map_coordinate[0], gps_map_coordinate[1], gps_map_zoom, gps_map_type) gps_map_tile = gps_map.bigimage gps_map_corner_upper_left = gps_map.northwest gps_map_corner_lower_right = gps_map.southeast gps_map_width = (gps_map_corner_lower_right[1] - gps_map_corner_upper_left[1]) * 4 / 3 gps_map_height = (gps_map_corner_upper_left[0] - gps_map_corner_lower_right[0]) * 4 / 3 gps_map_aspect_ratio = gps_map_width / gps_map_height gps_map_array = np.array( gps_map_tile.resize( (int(gps_map_resolution * gps_map_aspect_ratio), gps_map_resolution))) gps_map_array = np.swapaxes(gps_map_array[::-1, :], 0, 1) gps_map_effective_size = gps_map_height / gps_map_resolution gps_map_x_position = gps_map_corner_upper_left[ 1] - gps_map_width / 8 gps_map_y_position = gps_map_corner_upper_left[ 0] - gps_map_height + gps_map_height / 8 except: pass else: return # update map from loaded data self.gps_background_image.setScale(gps_map_effective_size) self.gps_background_image.setImage(gps_map_array) self.gps_background_image.setX(gps_map_x_position) self.gps_background_image.setY(gps_map_y_position) self.gps_background_image.update()
class TestAU: ''' ----------------------- SYDNEY TEST (+LON, -LAT) ------------- ''' test_set_au = { 'LATITUDE': -33.8566, 'LONGITUDE': 151.2153, 'longitude_result': 151.2540, 'latitude_result': -33.8839, 'x_pixels': 581, 'y_pixels': 446, } LONGITUDE = test_set_au.get('LONGITUDE') LATITUDE = test_set_au.get('LATITUDE') goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, zoom, MAPTYPE, radius_meters=None) goompy.use_map_type(MAPTYPE) goompy.leftx = 1600 goompy.uppery = 1600 def test_get_lon_from_x_au(self): x_pixels = self.test_set_au.get('x_pixels') longitude_result = self.test_set_au.get('longitude_result') lon = self.goompy.get_lon_from_x(x_pixels) assert f'{lon:0.4f}' == f'{longitude_result:0.4f}' def test_get_lat_from_y_au(self): latitude_result = self.test_set_au.get('latitude_result') y_pixels = self.test_set_au.get('y_pixels') lat = self.goompy.get_lat_from_y(y_pixels) assert f'{lat:0.4f}' == f'{latitude_result:0.4f}' def test_get_x_from_lon_au(self): longitude_result = self.test_set_au.get('longitude_result') x_pixels_result = self.test_set_au.get('x_pixels') + self.goompy.leftx x = self.goompy.get_x_from_lon(longitude_result) assert abs(x - x_pixels_result) <= 1 def test_get_y_from_lat_au(self): latitude_result = self.test_set_au.get('latitude_result') y_pixels_result = self.test_set_au.get('y_pixels') + self.goompy.uppery y = self.goompy.get_y_from_lat(latitude_result) assert abs(y - y_pixels_result) <= TEST_TOLERANCE
class TestNL: ''' ----------------------- AMSTERDAM TEST (+LON, +LAT) -------------- ''' test_set_nl = { 'LONGITUDE': 4.8994, 'LATITUDE': 52.3755, 'longitude_result': 4.8882, 'latitude_result': 52.3774, 'x_pixels': 60, 'y_pixels': 246, } LONGITUDE = test_set_nl.get('LONGITUDE') LATITUDE = test_set_nl.get('LATITUDE') goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, zoom, MAPTYPE, radius_meters=None) goompy.use_map_type(MAPTYPE) goompy.leftx = 960 goompy.uppery = 960 def test_get_lon_from_x_nl(self): x_pixels = self.test_set_nl.get('x_pixels') longitude_result = self.test_set_nl.get('longitude_result') lon = self.goompy.get_lon_from_x(x_pixels) assert f'{lon:0.4f}' == f'{longitude_result:0.4f}' def test_get_lat_from_y_nl(self): latitude_result = self.test_set_nl.get('latitude_result') y_pixels = self.test_set_nl.get('y_pixels') lat = self.goompy.get_lat_from_y(y_pixels) assert f'{lat:0.4f}' == f'{latitude_result:0.4f}' def test_get_x_from_lon_nl(self): longitude_result = self.test_set_nl.get('longitude_result') x_pixels_result = self.test_set_nl.get('x_pixels') + self.goompy.leftx x = self.goompy.get_x_from_lon(longitude_result) assert abs(x - x_pixels_result) <= 1 def test_get_y_from_lat_nl(self): latitude_result = self.test_set_nl.get('latitude_result') y_pixels_result = self.test_set_nl.get('y_pixels') + self.goompy.uppery y = self.goompy.get_y_from_lat(latitude_result) assert abs(y - y_pixels_result) <= TEST_TOLERANCE
class TestAR: ''' ----------------------- BUENOS AIRES TEST (-LON, -LAT) ------------- ''' test_set_ar = { 'LATITUDE': -34.6246, 'LONGITUDE': -58.4017, 'longitude_result': -58.4515, 'latitude_result': -34.6678, 'x_pixels': 117, 'y_pixels': 584, } LONGITUDE = test_set_ar.get('LONGITUDE') LATITUDE = test_set_ar.get('LATITUDE') goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, zoom, MAPTYPE, radius_meters=None) goompy.use_map_type(MAPTYPE) goompy.leftx = 2 goompy.uppery = 1919 def test_get_lon_from_x_ar(self): x_pixels = self.test_set_ar.get('x_pixels') longitude_result = self.test_set_ar.get('longitude_result') lon = self.goompy.get_lon_from_x(x_pixels) assert f'{lon:0.4f}' == f'{longitude_result:0.4f}' def test_get_lat_from_y_ar(self): latitude_result = self.test_set_ar.get('latitude_result') y_pixels = self.test_set_ar.get('y_pixels') lat = self.goompy.get_lat_from_y(y_pixels) assert f'{lat:0.4f}' == f'{latitude_result:0.4f}' def test_get_x_from_lon_ar(self): longitude_result = self.test_set_ar.get('longitude_result') x_pixels_result = self.test_set_ar.get('x_pixels') + self.goompy.leftx x = self.goompy.get_x_from_lon(longitude_result) assert abs(x - x_pixels_result) <= 1 def test_get_y_from_lat_ar(self): latitude_result = self.test_set_ar.get('latitude_result') y_pixels_result = self.test_set_ar.get('y_pixels') + self.goompy.uppery y = self.goompy.get_y_from_lat(latitude_result) assert abs(y - y_pixels_result) <= TEST_TOLERANCE
class TestUS: ''' ----------------------- NEW YORK TEST (-LON, +LAT) ------------- ''' test_set_us = { 'LONGITUDE': -74.012, 'LATITUDE': 40.7044, 'longitude_result': -74.0045, 'latitude_result': 40.7097, 'x_pixels': 495, 'y_pixels': 156, } LONGITUDE = test_set_us.get('LONGITUDE') LATITUDE = test_set_us.get('LATITUDE') goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, zoom, MAPTYPE, radius_meters=None) goompy.use_map_type(MAPTYPE) goompy.leftx = 960 goompy.uppery = 960 def test_get_lon_from_x_us(self): x_pixels = self.test_set_us.get('x_pixels') longitude_result = self.test_set_us.get('longitude_result') lon = self.goompy.get_lon_from_x(x_pixels) assert f'{lon:0.4f}' == f'{longitude_result:0.4f}' def test_get_lat_from_y_us(self): latitude_result = self.test_set_us.get('latitude_result') y_pixels = self.test_set_us.get('y_pixels') lat = self.goompy.get_lat_from_y(y_pixels) assert f'{lat:0.4f}' == f'{latitude_result:0.4f}' def test_get_x_from_lon_us(self): longitude_result = self.test_set_us.get('longitude_result') x_pixels_result = self.test_set_us.get('x_pixels') + self.goompy.leftx x = self.goompy.get_x_from_lon(longitude_result) assert abs(x - x_pixels_result) <= 1 def test_get_y_from_lat_us(self): latitude_result = self.test_set_us.get('latitude_result') y_pixels_result = self.test_set_us.get('y_pixels') + self.goompy.uppery y = self.goompy.get_y_from_lat(latitude_result) assert abs(y - y_pixels_result) <= TEST_TOLERANCE
def __init__(self, main_window): super(ReadUpdater, self).__init__() # ########## Reference to top level window ########## self.main_window = main_window # type: QtWidgets.QMainWindow # ########## Get the settings instance ########## self.settings = QtCore.QSettings() # ########## Get the Pick And Plate instance of the logger ########## self.logger = logging.getLogger("RoverBaseStation") self.goompy = GooMPy(2 * WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, MAPTYPE, 1500) self.tab_widget = self.main_window.tabWidget # type: QtWidgets.QTabWidget # ########## Some Flags ########## self.run_thread_flag = True # ########## Class variables ########## self.data_last_seen = time.time()
class UI(Tk): def __init__(self): Tk.__init__(self) self.geometry('%dx%d+500+500' % (WIDTH,HEIGHT)) self.title('GooMPy') self.canvas = Canvas(self, width=WIDTH, height=HEIGHT) self.canvas.pack() self.bind("<Key>", self.check_quit) self.bind('<B1-Motion>', self.drag) self.bind('<Button-1>', self.click) self.label = Label(self.canvas) self.radiogroup = Frame(self.canvas) self.radiovar = IntVar() self.maptypes = ['roadmap', 'terrain', 'satellite', 'hybrid'] self.add_radio_button('Road Map', 0) self.add_radio_button('Terrain', 1) self.add_radio_button('Satellite', 2) self.add_radio_button('Hybrid', 3) self.zoom_in_button = self.add_zoom_button('+', +1) self.zoom_out_button = self.add_zoom_button('-', -1) self.zoomlevel = ZOOM maptype_index = 0 self.radiovar.set(maptype_index) self.goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, MAPTYPE) self.restart() def add_zoom_button(self, text, sign): button = Button(self.canvas, text=text, width=1, command=lambda:self.zoom(sign)) return button def reload(self): self.coords = None self.redraw() self['cursor'] = '' def restart(self): # A little trick to get a watch cursor along with loading self['cursor'] = 'watch' self.after(1, self.reload) def add_radio_button(self, text, index): maptype = self.maptypes[index] Radiobutton(self.radiogroup, text=maptype, variable=self.radiovar, value=index, command=lambda:self.usemap(maptype)).grid(row=0, column=index) def click(self, event): self.coords = event.x, event.y def drag(self, event): self.goompy.move(self.coords[0]-event.x, self.coords[1]-event.y) self.image = self.goompy.getImage() self.redraw() self.coords = event.x, event.y def redraw(self): self.image = self.goompy.getImage() self.image_tk = ImageTk.PhotoImage(self.image) self.label['image'] = self.image_tk self.label.place(x=0, y=0, width=WIDTH, height=HEIGHT) self.radiogroup.place(x=0,y=0) x = int(self.canvas['width']) - 50 y = int(self.canvas['height']) - 80 self.zoom_in_button.place(x= x, y=y) self.zoom_out_button.place(x= x, y=y+30) def usemap(self, maptype): self.goompy.useMaptype(maptype) self.restart() def zoom(self, sign): newlevel = self.zoomlevel + sign if newlevel > 0 and newlevel < 22: self.zoomlevel = newlevel self.goompy.useZoom(newlevel) self.restart() def check_quit(self, event): if ord(event.char) == 27: # ESC exit(0)
class RoutePlanGUI: '''The GUI for the Route Planning System All the GUI features are created and run though this class. All expected user input will come though this GUI, along with all output to the user Attributes: root The Root from which the application is running #max_height Maximium height for the window #max_width transport_mode Transport mode setting locations List of all the current locations location_view Index of what can currently be viewed VIEW_SIZE A limit of how many items can be viewed at one time to ensure they fit on screen latitude The current latitude of the device running the system longitude The cyrrent longitude of the device running the system zoom The zoom level of the tiles map_width The width of the displayed map map_height The height of the displayed map goompy A goompy object to act as the API to download the map tiles Methods: _draw_UI Creates the UI features and places them in the correct location _redraw_map Redraws the map _add_location Adds a location to the list of locations _remove_location Removes a location from the list of locations _move_boxes Moves the displayed list of locations _search Runs the search algorithm after fetching and passing it data ''' def __init__(self, root): self.root = root self.max_height = self.root.winfo_screenheight() self.max_width = self.root.winfo_screenwidth() self.root.geometry((str(int(self.max_width/2))+"x"+str(int(self.max_height/2)))) ## self.radiogroup = Frame() ## self.root.bind("<Key>", self.user_input) ## self.root.bind("<Button>", self.user_input) self.root.bind("<Escape>", lambda e: self.root.destroy()) # The user is able to select differnt modes of transportation # They are diffined here, as well as the mechanism for storing them self.transport_mode = tk.StringVar() self.transport_mode.set("Walking") self.transport_modes = ["Walking", "Bicycling", "Driving", "Transit"] # All the locations the user is using, stored in a list self.locations = [] # The index used to calualate which locations are currently visable self.location_view = 0 # Used to limit the system from attempting to display more locations # than possible self.VIEW_SIZE = 10 # The coordinates of the current location of the user self.latitude = float( location.CURRENT_LOCATION[:location.CURRENT_LOCATION.find(",")] ) self.longitude = float( location.CURRENT_LOCATION[location.CURRENT_LOCATION.find(",")+1:] ) # The zoom level on the map self.zoom = 15 # The dimentions of the map self.map_width = 500 self.map_height = 500 # GooMPy object to act as an API self.goompy = GooMPy(self.map_width, self.map_height, self.latitude, self.longitude, self.zoom, "roadmap") self.live = False # Starts the system self._draw_UI() self.root.mainloop() def _draw_UI(self): '''Draw the UI ''' # Backbone of the GUI layout self.frame = tk.Frame(self.root) # Placement of Radiobuttons with correct control assignment for index, mode in enumerate(self.transport_modes): tk.Radiobutton( self.frame, text=mode, variable=self.transport_mode, value=mode ).grid(row=0, column=index) # Movement buttons self.up_button = tk.Button( self.frame, text=" Up ", bg="yellow", command=lambda: self._move_boxes(1) ) self.down_button = tk.Button( self.frame, text="Down", bg="yellow", command=lambda: self._move_boxes(-1) ) self.showing_movement_buttons = False # Start button self.go_button = tk.Button( self.frame, text="Start Search", bg="yellow", command=lambda: self._search() ) # Entry box for user input, along with an associated button self.entry_box = tk.Entry(self.frame) self.entry_box.insert("end", "Add Location") self.entry_box.bind("<Return>", self._add_location) self.entry_button = tk.Button( self.frame, text="+", bg="green", command=self._add_location ) # Configureation of the widgets just defined self.entry_box.grid(row=2, column=0, columnspan=4, sticky="ew") self.entry_button.grid(row=2, column=4) self.go_button.grid(row=1, column=3, columnspan=2, sticky="e") # Canvas to hold the map self.canvas = tk.Canvas( self.root, width=self.map_width, height=self.map_height, bg="black" ) # Underlay to configure the tile image self.label = tk.Label(self.canvas) self.zoom_in_button = tk.Button(self.canvas, text="+", width=1, command=lambda:self._map_zoom(+1)) self.zoom_out_button = tk.Button(self.canvas, text="-", width=1, command=lambda:self._map_zoom(-1)) # Packing of the two layout features self.frame.pack(side="left", fill="y") self.canvas.pack(side="right", expand=True, fill="both") ## x = int(self.canvas['width']) - 50 ## y = int(self.canvas['height']) - 80 ## ## self.zoom_in_button.place(x=x, y=y) ## self.zoom_out_button.place(x=x, y=y+30) # Load a tile self._reload() def _redraw_map(self): '''Fetch a new tile and place that on the map ''' ## print("redrawing") # Get the tile that goompy has been told to fetch self.goompy._fetch_and_update() self.image = self.goompy.getImage() # Load the image tile onto the map self.image_tk = ImageTk.PhotoImage(self.image) self.label['image'] = self.image_tk self.label.place( x=0, y=0, width=self.map_width, height=self.map_height ) def _reload(self): self.coords = None if self.live: self._redraw_map() def _add_location(self, event=None): '''Make the user's input a Location and add to the list of locations ''' # The details of the new location user_input = self.entry_box.get() new_location = location.Location(user_input) self.locations.append(new_location) precise = new_location.location # goompy loading a new tile as per the location self.goompy.lat = float(precise[:precise.find(",")]) self.goompy.lon = float(precise[precise.find(",")+1:]) self._reload() # Differnt actions depending on how many locations currently exist if len(self.locations) > self.VIEW_SIZE: # Configure the movement buttons is not configured if not self.showing_movement_buttons: self.up_button.grid(row=1, column=0, columnspan=2, sticky="w") self.down_button.grid( row=self.VIEW_SIZE+10, column=0, columnspan=2, sticky="w" ) # Ensures the latest location is displayed at the bottom while len(self.locations)-self.location_view > self.VIEW_SIZE: self._move_boxes(1) else: # Move the entry box, and its button, down on space self.entry_box.grid_configure( row=self.entry_box.grid_info()["row"]+1 ) self.entry_button.grid_configure( row=self.entry_box.grid_info()["row"] ) # The row the the entry box moved from row = self.entry_box.grid_info()["row"]-1 # Create a Label and a Button for the new location tk.Label( self.frame, text=user_input, bg="white", anchor="w" ).grid(row=row, column=0, sticky="ew", columnspan=4) tk.Button( self.frame, text="X", bg="red", command=lambda: self._remove_location(len(self.locations)) ).grid(row=row, column=4, sticky="ew") # Reset the text in the entry box self.entry_box.delete(0, "end") self.entry_box.insert("end", "Add Location") def _remove_location(self, row): '''Remove the location selected by the user by visualy and from list ''' # Remove the location from the location list self.locations.pop(row+self.location_view-1) # Marker to indicate if the locations below should move up move = False # List of all the locations, as per what is on the Labels remaining_locations = [x.user_input for x in self.locations] # Index to keep track of where is being investigated index = 0 # Looping though all the slaves and adjusting them as needed for slave in self.frame.grid_slaves()[::-1]: # Reversed for simplicity # Anaylse and configure the Labels if type(slave) == tk.Label: if self.location_view+index == len(self.locations): slave.grid_forget() else: if slave.cget("text") not in remaining_locations: move = True if move: slave.config( text=self.locations[ self.location_view+index ].user_input ) index += 1 # Ensure that the final button is removed if needed if (type(slave) == tk.Button and self.location_view+index-1 == len(self.locations)): slave.grid_forget() self.location_view -= 1 def _move_boxes(self, direction): '''Move the visual list of locations in required direction ''' for i in self.locations: print(i) # Ensure that the given command is valid in the current configuration if ((self.location_view == 0 and direction == -1) or (self.location_view+self.VIEW_SIZE == len(self.locations) and direction == 1)): return None else: self.location_view += direction # Iterate though the Labels and change their values for index, slave in enumerate(self.frame.grid_slaves()[::-1]): if type(slave) == tk.Label: slave.config( text=self.locations[ self.location_view+index ].user_input ) ## def user_input(self, event): ## if event.char == "a": ## print(self.transport_mode.get()) def _search(self): '''Calculate and return the most efficent route ''' # Using the Latitude and Longitude, calculate the distance matrix precise_locations = [l.location for l in self.locations] distance_matrix_info = location.GM.distance_matrix( precise_locations, precise_locations, mode=self.transport_mode.get().lower() ) self.distance_matrix = [] for origin in distance_matrix_info["rows"]: self.distance_matrix.append( [dest["duration"]["value"] for dest in origin["elements"]] ) ######################################################################################################################## t = time() _time, _route = search.nearest_neighbour(self.distance_matrix) print("nn time") print(time()-t) t2 = time() _time2, _route2 = search.brute_force(self.distance_matrix) print("bf time") print(time()-t2) print(_time) print(_route) ######################################################################################################################## # Write message to the user about the best route msg = "The best route to visit every location in the minimun amount of time is " for loc in _route[:-1]: msg += self.locations[loc].user_input msg += ", then " msg += "and then finally " msg += self.locations[_route[-1]].user_input # Set up the message to tell the user which route is best self.route_box = tk.Toplevel(master=self.root) self.route_box.title("Best Route") # Configure widgets in message box tk.Message(self.route_box, text=msg).pack() tk.Button( self.route_box, text="OK", command=lambda:self.route_box.destroy() ).pack()
class UI(tk.Tk): def __init__(self): tk.Tk.__init__(self) self.geometry(f'{WIDTH}x{HEIGHT}') self.title('GooMPy') self.canvas = tk.Canvas(self, width=WIDTH, height=HEIGHT) self.canvas.pack(fill='both') self.bind("<Key>", self.check_quit) self.bind('<B1-Motion>', self.drag) self.bind('<Button-1>', self.click) self.radiogroup = tk.Frame(self.canvas) self.radiovar = tk.IntVar() self.maptypes = ['roadmap', 'terrain', 'satellite', 'hybrid'] self.add_radio_button(0) self.add_radio_button(1) self.add_radio_button(2) self.add_radio_button(3) self.zoom_in_button = self.add_zoom_button('+', +1) self.zoom_out_button = self.add_zoom_button('-', -1) self.zoomlevel = ZOOM self.radiovar.set(0) self.goompy = GooMPy( WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, radius_meters=RADIUS) self.goompy.use_map_type(MAPTYPE) self.redraw() def add_zoom_button(self, text, sign): button = tk.Button( self.canvas, text=text, width=1, command=lambda: self.zoom(sign)) return button def set_cursor_to_normal(self): self.config(cursor='') self.update_idletasks() def set_cursor_to_wait(self): # A little trick to get a watch cursor along with loading self.config(cursor='watch') self.update_idletasks() def add_radio_button(self, index): maptype = self.maptypes[index] tk.Radiobutton(self.radiogroup, text=maptype, variable=self.radiovar, value=index, command=lambda: self.usemap(maptype)).grid(row=0, column=index) def click(self, event): self.coords = event.x, event.y lon = self.goompy.get_lon_from_x(self.coords[0]) lat = self.goompy.get_lat_from_y(self.coords[1]) # TODO debug print statement print(f'x: {self.coords[0]}, y: {self.coords[1]} ' f'lon: {lon:.4f}, lat: {lat:.4f}') def drag(self, event): self.goompy.move(self.coords[0] - event.x, self.coords[1] - event.y) self.redraw() self.coords = event.x, event.y def redraw(self): # clear the canvas self.canvas.delete('all') image = self.goompy.get_image() self.my_image = ImageTk.PhotoImage(image) self.canvas.create_image(0, 0, image=self.my_image, anchor='nw') self.radiogroup.place(x=0, y=0) x = int(self.canvas['width']) - 50 y = int(self.canvas['height']) - 80 self.zoom_in_button.place(x=x, y=y) self.zoom_out_button.place(x=x, y=y + 30) self.draw_point(LATITUDE, LONGITUDE, fill='blue') def usemap(self, maptype): self.set_cursor_to_wait() self.goompy.use_map_type(maptype) self.set_cursor_to_normal() self.redraw() def zoom(self, sign): self.set_cursor_to_wait() self.zoomlevel = self.goompy.get_zoom newlevel = self.zoomlevel + sign if 0 < newlevel < 22: self.zoomlevel = newlevel self.goompy.use_zoom(newlevel) self.redraw() self.set_cursor_to_normal() def draw_point(self, lat, lon, size=None, **kwargs): x = self.goompy.get_xwin_from_lon(lon) y = self.goompy.get_ywin_from_lat(lat) if size is None: size = int(DEFAULT_SYMBOL_SIZE / 2) elif not -1 < size <= MAX_SYMBOL_SIZE: raise ValueError(f'size drawing object must be positive and ' f'less than {MAX_SYMBOL_SIZE + 1}') else: size = int(size/2) bbox = (x - size, y - size, x + size, y + size) self.canvas.create_oval(*bbox, **kwargs) def check_quit(self, event): if ord(event.char) == 27: # ESC exit(0)
class UI(tk.Tk): def __init__(self): tk.Tk.__init__(self) self.geometry('%dx%d+500+500' % (WIDTH,HEIGHT)) self.title('GooMPy') self.canvas = tk.Canvas(self, width=WIDTH, height=HEIGHT) self.canvas.pack() self.bind("<Key>", self.check_quit) self.bind('<B1-Motion>', self.drag) self.bind('<Button-1>', self.click) self.label = tk.Label(self.canvas) self.radiogroup = tk.Frame(self.canvas) self.radiovar = tk.IntVar() self.maptypes = ['roadmap', 'terrain', 'satellite', 'hybrid'] self.add_radio_button('Road Map', 0) self.add_radio_button('Terrain', 1) self.add_radio_button('Satellite', 2) self.add_radio_button('Hybrid', 3) self.zoom_in_button = self.add_zoom_button('+', +1) self.zoom_out_button = self.add_zoom_button('-', -1) self.zoomlevel = ZOOM maptype_index = 0 self.radiovar.set(maptype_index) self.goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, MAPTYPE) self.restart() def add_zoom_button(self, text, sign): button = tk.Button(self.canvas, text=text, width=1, command=lambda:self.zoom(sign)) return button def reload(self): self.coords = None self.redraw() self['cursor'] = '' def restart(self): # A little trick to get a watch cursor along with loading self['cursor'] = 'watch' self.after(1, self.reload) def add_radio_button(self, text, index): maptype = self.maptypes[index] tk.Radiobutton(self.radiogroup, text=maptype, variable=self.radiovar, value=index, command=lambda:self.usemap(maptype)).grid(row=0, column=index) def click(self, event): self.coords = event.x, event.y def drag(self, event): self.goompy.move(self.coords[0]-event.x, self.coords[1]-event.y) self.image = self.goompy.getImage() self.redraw() self.coords = event.x, event.y def redraw(self): self.image = self.goompy.getImage() self.image_tk = ImageTk.PhotoImage(self.image) self.label['image'] = self.image_tk self.label.place(x=0, y=0, width=WIDTH, height=HEIGHT) self.radiogroup.place(x=0,y=0) x = int(self.canvas['width']) - 50 y = int(self.canvas['height']) - 80 self.zoom_in_button.place(x= x, y=y) self.zoom_out_button.place(x= x, y=y+30) def usemap(self, maptype): self.goompy.useMaptype(maptype) self.restart() def zoom(self, sign): newlevel = self.zoomlevel + sign if newlevel > 0 and newlevel < 22: self.zoomlevel = newlevel self.goompy.useZoom(newlevel) self.restart() def check_quit(self, event): if ord(event.char) == 27: # ESC exit(0)
def create_tabPages(self, tag, tabPage): if tag == 'parse': self.tree_parseDate = ttk.Treeview(tabPage, selectmode='browse') verticalScroll = ttk.Scrollbar(tabPage, orient='vertical', command=self.tree_parseDate.yview) verticalScroll.pack(side='right', fill='y') horScroll = ttk.Scrollbar(tabPage, orient='horizontal', command=self.tree_parseDate.xview) horScroll.pack(side='bottom', fill='x') self.tree_parseDate.configure(yscrollcommand=verticalScroll.set) self.tree_parseDate.configure(xscrollcommand=horScroll.set) self.tree_parseDate['columns'] = ('latitude', 'longhitude', 'altitude', 'distance', 'satellites', 'quality', 'speed', 'course', 'date') #self.tree_parseDate['show'] = 'headings' self.tree_parseDate.heading("#0", text='Timestamp', anchor='w') self.tree_parseDate.column("#0", anchor="w", width=40) self.tree_parseDate.heading('latitude', text='Latitude') self.tree_parseDate.column('latitude', stretch='yes', anchor='w', width=14) self.tree_parseDate.heading('longhitude', text='Longhitude') self.tree_parseDate.column('longhitude', anchor='w', width=20) self.tree_parseDate.heading('altitude', text='Altitude') self.tree_parseDate.column('altitude', anchor='w', width=20) self.tree_parseDate.heading('distance', text='Distance') self.tree_parseDate.column('distance', anchor='w', width=20) self.tree_parseDate.heading('satellites', text='Satellites') self.tree_parseDate.column('satellites', anchor='w', width=10) self.tree_parseDate.heading('quality', text='Quality') self.tree_parseDate.column('quality', anchor='w', width=20) self.tree_parseDate.heading('speed', text='Speed') self.tree_parseDate.column('speed', anchor='w', width=20) self.tree_parseDate.heading('course', text='Course') self.tree_parseDate.column('course', anchor='w', width=20) self.tree_parseDate.heading('date', text='Date') self.tree_parseDate.column('date', anchor='w', width=20) #self.init_workspaces() self.tree_parseDate.pack(expand=1, fill='both') elif tag == 'raw': self.txt_rawData = Text(tabPage) self.txt_rawData.pack(expand=1, fill='both') self.txt_rawData.insert(END, 'GPS Logger started...') pass elif tag == 'summary': pass else: self.canvas = Canvas(tabPage) self.canvas.pack(expand=1, fill='both') self.label = Label(self.canvas) self.label.bind('<B1-Motion>', self.goompy_drag) self.label.bind('<Button-1>', self.goompy_click) self.label.bind("<Double-1>", lambda e: self.goompy_zoom(+1)) self.label.bind("<Double-3>", lambda e: self.goompy_zoom(-1)) self.label.bind_all("<MouseWheel>", self.goompy_mousewheel) self.zoomlevel = ZOOM self.goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, MAPTYPE) self.goompy_restart() pass pass
class Application(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.parent.protocol("WM_DELETE_WINDOW", self.onExit) self.parent.bind("<Destroy>", lambda e: self.onExit) self.init_settings() self.init_classes() self.init_variables() self.init_images() self.init_menubar() self.init_toolbar() self.init_tabs() self.init_statusbar() self.init_connections() self.pack() def init_settings(self): pass def init_classes(self): self.config_menus = configparser.ConfigParser() self.config_tools = configparser.ConfigParser() self.config_tabs = configparser.ConfigParser() self.config_map = configparser.ConfigParser() self._serial = serial.Serial() self._parser = parsenmea.ParseNmea() self._storage = StorageDB('gps.sqlite') self._settings = Settings() self._gpgga = nmea.GPGGA() self._gprmc = nmea.GPRMC() pass def init_variables(self): self.images_ui = {} self.toolbars = {} self.menus = {} self.lbl_status = StringVar() self.connection_status = StringVar() self.port_label = StringVar() self.port = StringVar() self.baud = StringVar() self.line_raw = IntVar() self.progress = IntVar() self.progress_maximum = IntVar() self.lastLat = 0.0 self.lastLon = 0.0 self.is_zoomIn = True # get current project root path self.dir_name = os.path.dirname(os.path.realpath(__file__)) self.menu_file = os.path.join(self.dir_name, "configs/menus.ini") self.tool_file = os.path.join(self.dir_name, "configs/toolbars.ini") self.tabs_file = os.path.join(self.dir_name, "configs/tabs.ini") self.config_file = os.path.join(self.dir_name, "configs/global.ini") self.img_path = os.path.join(self.dir_name, "images") self.output_path = os.path.join(self.dir_name, "outputs") pass def init_images(self): for file in os.listdir(self.img_path): if file.endswith(".png"): self.images_ui[file.replace(".png", "")] = PhotoImage( file=str(os.path.join(self.img_path, file))) pass def init_menubar(self): # Load the menus configuration file self.config_menus.read(self.menu_file) # Initialize menus from configuration file self.menubar = Menu(self.parent) for section in self.config_menus.sections(): topMenu = Menu(self.menubar, tearoff=0) for option in self.config_menus.options(section): if option.strip() == "-": topMenu.add_separator() else: topMenu.add_command( label=self.config_menus.get(section, option), compound=LEFT, image=self.images_ui[option], command=lambda tag=option: self.doClickEvent(0, tag)) self.menus[option] = topMenu self.menubar.add_cascade(label=section, menu=topMenu) self.parent.config(menu=self.menubar) #for entry in self.menus: #self.menus[entry].config(fg= 'green', image= self.images_ui['connect']) pass def init_toolbar(self): # Load the toolbars configuration file self.config_tools.read(self.tool_file) # Initialize toolbars from configuration file self.toolbar = Frame(self.parent, bd=1, relief=RAISED) for section in self.config_tools.sections(): for option in self.config_tools.options(section): self.btn_tool = Button( self.toolbar, image=self.images_ui[option], text=option, relief=FLAT, justify=CENTER, command=lambda tag=option: self.doClickEvent(0, tag)) self.btn_tool.image = self.images_ui[option] self.btn_tool.pack(side=LEFT, padx=2, pady=2) self.toolbars[option] = self.btn_tool self.toolbar.pack(side=TOP, fill=X) #for entry in self.toolbars: # self.toolbars[entry]['state'] = DISABLED pass def init_tabs(self): # Load the tabs configuration file self.config_tabs.read(self.tabs_file) # Initialize tabs from configuration file self.tabs = ttk.Notebook(self.parent) for section in self.config_tabs.sections(): for tab in self.config_tabs.options(section): tabPage = ttk.Frame( self.tabs ) # first page, which would get widgets gridded into it self.tabs.add(tabPage, text=self.config_tabs.get(section, tab), image=self.images_ui[tab], compound=LEFT) self.create_tabPages(tab, tabPage) pass self.tabs.pack(expand=1, fill="both") # Pack to make visible def init_statusbar(self): self.status_frame = Frame(self.parent, bd=1, relief=GROOVE) self.status_frame.pack(fill=X) label_Status = Label(self.status_frame, textvariable=self.lbl_status, anchor=W) label_Status.pack(side=LEFT) label_Dummy = Label(self.status_frame, text='| GPS Device:', anchor=W) label_Dummy.pack(side=LEFT) lbl_Connection = Label(self.status_frame, textvariable=self.connection_status, anchor=E, fg='blue') lbl_Connection.pack(side=LEFT) self.connection_status.set("Disconnected") label_lineDummy = Label(self.status_frame, text='| Line:', anchor=W) label_lineDummy.pack(side=LEFT) lbl_lineRaw = Label(self.status_frame, textvariable=self.line_raw, anchor=E, fg='green') lbl_lineRaw.pack(side=LEFT) self.line_raw.set(0) def create_tabPages(self, tag, tabPage): if tag == 'parse': self.tree_parseDate = ttk.Treeview(tabPage, selectmode='browse') verticalScroll = ttk.Scrollbar(tabPage, orient='vertical', command=self.tree_parseDate.yview) verticalScroll.pack(side='right', fill='y') horScroll = ttk.Scrollbar(tabPage, orient='horizontal', command=self.tree_parseDate.xview) horScroll.pack(side='bottom', fill='x') self.tree_parseDate.configure(yscrollcommand=verticalScroll.set) self.tree_parseDate.configure(xscrollcommand=horScroll.set) self.tree_parseDate['columns'] = ('latitude', 'longhitude', 'altitude', 'distance', 'satellites', 'quality', 'speed', 'course', 'date') #self.tree_parseDate['show'] = 'headings' self.tree_parseDate.heading("#0", text='Timestamp', anchor='w') self.tree_parseDate.column("#0", anchor="w", width=40) self.tree_parseDate.heading('latitude', text='Latitude') self.tree_parseDate.column('latitude', stretch='yes', anchor='w', width=14) self.tree_parseDate.heading('longhitude', text='Longhitude') self.tree_parseDate.column('longhitude', anchor='w', width=20) self.tree_parseDate.heading('altitude', text='Altitude') self.tree_parseDate.column('altitude', anchor='w', width=20) self.tree_parseDate.heading('distance', text='Distance') self.tree_parseDate.column('distance', anchor='w', width=20) self.tree_parseDate.heading('satellites', text='Satellites') self.tree_parseDate.column('satellites', anchor='w', width=10) self.tree_parseDate.heading('quality', text='Quality') self.tree_parseDate.column('quality', anchor='w', width=20) self.tree_parseDate.heading('speed', text='Speed') self.tree_parseDate.column('speed', anchor='w', width=20) self.tree_parseDate.heading('course', text='Course') self.tree_parseDate.column('course', anchor='w', width=20) self.tree_parseDate.heading('date', text='Date') self.tree_parseDate.column('date', anchor='w', width=20) #self.init_workspaces() self.tree_parseDate.pack(expand=1, fill='both') elif tag == 'raw': self.txt_rawData = Text(tabPage) self.txt_rawData.pack(expand=1, fill='both') self.txt_rawData.insert(END, 'GPS Logger started...') pass elif tag == 'summary': pass else: self.canvas = Canvas(tabPage) self.canvas.pack(expand=1, fill='both') self.label = Label(self.canvas) self.label.bind('<B1-Motion>', self.goompy_drag) self.label.bind('<Button-1>', self.goompy_click) self.label.bind("<Double-1>", lambda e: self.goompy_zoom(+1)) self.label.bind("<Double-3>", lambda e: self.goompy_zoom(-1)) self.label.bind_all("<MouseWheel>", self.goompy_mousewheel) self.zoomlevel = ZOOM self.goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, MAPTYPE) self.goompy_restart() pass pass def goompy_reload(self): self.coords = None self.goompy_redraw() self.parent['cursor'] = '' pass def goompy_restart(self): # A little trick to get a watch cursor along with loading self.parent['cursor'] = 'watch' self.after(1, self.goompy_reload) def goompy_redraw(self): self.image = self.goompy.getImage() self.image_tk = ImageTk.PhotoImage(self.image) self.label['image'] = self.image_tk self.label.pack(expand=1, fill='both') def goompy_zoom(self, sign): newlevel = self.zoomlevel + sign if newlevel > 0 and newlevel < 22: self.zoomlevel = newlevel self.goompy.useZoom(newlevel) self.goompy_restart() def goompy_mousewheel(self, event): if event.num == 5 or event.delta < 0: self.goompy_zoom(-1) else: self.goompy_zoom(+1) pass def goompy_drag(self, event): try: # Ignore NONE value self.goompy.move(self.coords[0] - event.x, self.coords[1] - event.y) except: pass self.image = self.goompy.getImage() self.goompy_redraw() self.coords = event.x, event.y def goompy_click(self, event): self.coords = event.x, event.y def init_connections(self): self.port_label.set(self._settings.GetSetting('port_label')) self.port.set(self._settings.GetSetting('port')) self.baud.set(self._settings.GetSetting('baud')) self.lbl_status.set( ('%s | %s' % (self.port_label.get(), self.baud.get()))) self.port_old = self._settings.GetSetting('port_old') if self.port.get() != self.port_old: if self._serial.is_open == True: self._serial.close() self.connection_status.set("Disconnected") self.toolbars['connect']['image'] = self.images_ui['connect'] self.menus['connect'].entryconfig( 1, image=self.images_ui['connect'], label='Connect') self._serial.baudrate = self.baud.get() self._serial.port = self.port.get() def connect_device(self): if self._serial.is_open == False: try: self._serial.open() # Open serial port except: pass else: self._serial.close() if self._serial.is_open == True: self.connection_status.set("Connected") self.toolbars['connect']['image'] = self.images_ui['disconnect'] self.menus['connect'].entryconfig( 1, image=self.images_ui['disconnect'], label='Disconnect') self.thread = Thread(target=self.read_serial, name=str(datetime.datetime.now())) self.thread.start() else: self.connection_status.set("Disconnected") self.toolbars['connect']['image'] = self.images_ui['connect'] self.menus['connect'].entryconfig(1, image=self.images_ui['connect'], label='Connect') def read_serial(self): self.txt_rawData.insert(END, '\n') # add first line as line space self.line_raw.set(0) i = 0 while self._serial.is_open: reading = self._serial.read(self._serial.in_waiting) self.txt_rawData.insert(END, reading) self.txt_rawData.see("end") self.line_raw.set(i) self.parse_data(reading) i += 1 def read_data(self, filename): if filename.strip() == '': return self._parser.ParseGpsNmeaFile(filename) # If the gpsData is length zero the file was not in the # GPGGA, GPRMC pair format. Try the just GPRMC format if len(self._parser.gpsData) == 0: self._parser.ParseGpsNmeaGprmcFile(filename) if len(self._parser.gpsData) == 0: print("Error parsing data. Fix input file?") exit output_file = ''.join(ch for ch in str(datetime.datetime.now()) if ch.isalnum()) self._parser.SaveReducedGpsData( '%s.txt' % os.path.join(self.output_path, output_file)) self.txt_rawData.delete('1.0', END) self.txt_rawData.insert(END, '\n') # add first line as line space with open(filename) as fp: self.line_raw.set(0) i = 0 for cnt, line in enumerate(fp): #print("Line {}: {}".format(cnt, line)) if line.strip() is not '': self.txt_rawData.insert(END, line) self.txt_rawData.see("end") self.line_raw.set(i) self.parse_data(line) i += 1 def parse_data(self, line): # Skip any sentence other than GPGGA if line.startswith('$GPGGA'): self._gpgga.parse(line) #if self._parser.DoNotHaveFix(self._gpgga.latitude): # continue [lat, lon] = self._parser.ConvertLatLonToDecimalDegrees( self._gpgga.latitude, self._gpgga.lat_direction, self._gpgga.longitude, self._gpgga.lon_direction) distance = self._parser.HaversineDistance(lat, self.lastLat, lon, self.lastLon) self.lastLat = lat self.lastLon = lon self.tree_parseDate.insert( '', 'end', self._gpgga.timestamp, values=(lat, lon, self._gpgga.antenna_altitude, distance, self._gpgga.num_sats, self._gpgga.gps_qual)) ''' This region starts with control events ''' def doClickEvent(self, index, tag): if tag == 'zoom_out': self.is_zoomIn = False self.goompy_zoom(-1) elif tag == 'zoom_in': self.is_zoomIn = True self.goompy_zoom(+1) elif tag == 'port': self._settings.SetSettings('port_old', self.port.get()) cd = ConnectionDialog(self.parent) if cd.OK[0] == True: self.init_connections() elif tag == 'connect': self.connect_device() pass elif tag == 'open': self.file_name = filedialog.askopenfilename() self.lbl_status.set(self.file_name) self.read_data(self.file_name) #self.thread = Thread(target=self.read_data, name = str(datetime.datetime.now())) #self.thread.start() elif tag == 'exit': self.onExit() pass else: print((index, tag)) pass pass def onExit(self): try: if messagebox.askokcancel('Quit', 'Do you want to quit?'): self.parent.destroy() except: pass
def __init__(self): Tk.__init__(self) self.geometry('%dx%d+100+100' % (1200, 600)) self.title('Crowdtour') self.audioCount = 0 self.WAVE_OUTPUT_FILENAME = '' self.button_list = [] self.current_places = [] app = QApplication(sys.argv) self.canvas = Canvas(self, width=WIDTH, height=HEIGHT) self.canvas.pack() self.canvas.place(relx=0, rely=0) self.bind("<Key>", self.check_quit) self.bind('<B1-Motion>', self.drag) self.bind('<Button-1>', self.click) self.label = Label(self.canvas) self.radiogroup = Frame(self.canvas) self.radiovar = IntVar() self.maptypes = ['roadmap', 'terrain', 'satellite', 'hybrid'] self.add_radio_button('Road Map', 0) self.add_radio_button('Terrain', 1) self.add_radio_button('Satellite', 2) self.add_radio_button('Hybrid', 3) #input self.entry = Entry(self, bd=3) self.button = Button(self, text="Location", command=self.geolocation) self.button.place(relx=.18, rely=.90, anchor="c") self.entry.place(relx=.05, rely=.80) #buttons self.recordButton = Button(self, text="Record", command=self.record) self.recordButton.place(relx=.30, rely=.75, anchor="c") self.uploadButton = Button(self, text="Upload", command=self.upload) self.uploadButton.place(relx=.30, rely=.80, anchor="c") self.playButton = Button(self, text="Play", command=self.play) self.playButton.place(relx=.30, rely=.85, anchor="c") self.deleteButton = Button(self, text="Delete", command=self.delete) self.deleteButton.place(relx=.30, rely=.90, anchor="c") ### adding part here ### self.sound = QSoundEffect() # This is where you set default sound source if not os.path.exists('sounds'): os.makedirs('sounds') defaultBytes = b'27\xe5\xb2\x81\xe5' waveTest = wave.open(os.path.join('sounds', 'DefaultSound.wav'), 'w') waveTest.setparams((2, 2, 44100, 440320, 'NONE', 'not compressed')) waveTest.writeframes(defaultBytes) self.sound.setSource( QUrl.fromLocalFile(os.path.join('sounds', 'DefaultSound.wav'))) ### adding part here ### self.zoom_in_button = self.add_zoom_button('+', +1) self.zoom_out_button = self.add_zoom_button('-', -1) self.zoomlevel = ZOOM maptype_index = 0 self.radiovar.set(maptype_index) MARKER = "markers=size:tiny|label:B|color:blue|" + str( LATITUDE) + "," + str(LONGITUDE) self.goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, MAPTYPE, MARKER) self.restart()
class UI(Tk): def __init__(self): Tk.__init__(self) self.geometry('%dx%d+100+100' % (1200, 600)) self.title('Crowdtour') self.audioCount = 0 self.WAVE_OUTPUT_FILENAME = '' self.button_list = [] self.current_places = [] app = QApplication(sys.argv) self.canvas = Canvas(self, width=WIDTH, height=HEIGHT) self.canvas.pack() self.canvas.place(relx=0, rely=0) self.bind("<Key>", self.check_quit) self.bind('<B1-Motion>', self.drag) self.bind('<Button-1>', self.click) self.label = Label(self.canvas) self.radiogroup = Frame(self.canvas) self.radiovar = IntVar() self.maptypes = ['roadmap', 'terrain', 'satellite', 'hybrid'] self.add_radio_button('Road Map', 0) self.add_radio_button('Terrain', 1) self.add_radio_button('Satellite', 2) self.add_radio_button('Hybrid', 3) #input self.entry = Entry(self, bd=3) self.button = Button(self, text="Location", command=self.geolocation) self.button.place(relx=.18, rely=.90, anchor="c") self.entry.place(relx=.05, rely=.80) #buttons self.recordButton = Button(self, text="Record", command=self.record) self.recordButton.place(relx=.30, rely=.75, anchor="c") self.uploadButton = Button(self, text="Upload", command=self.upload) self.uploadButton.place(relx=.30, rely=.80, anchor="c") self.playButton = Button(self, text="Play", command=self.play) self.playButton.place(relx=.30, rely=.85, anchor="c") self.deleteButton = Button(self, text="Delete", command=self.delete) self.deleteButton.place(relx=.30, rely=.90, anchor="c") ### adding part here ### self.sound = QSoundEffect() # This is where you set default sound source if not os.path.exists('sounds'): os.makedirs('sounds') defaultBytes = b'27\xe5\xb2\x81\xe5' waveTest = wave.open(os.path.join('sounds', 'DefaultSound.wav'), 'w') waveTest.setparams((2, 2, 44100, 440320, 'NONE', 'not compressed')) waveTest.writeframes(defaultBytes) self.sound.setSource( QUrl.fromLocalFile(os.path.join('sounds', 'DefaultSound.wav'))) ### adding part here ### self.zoom_in_button = self.add_zoom_button('+', +1) self.zoom_out_button = self.add_zoom_button('-', -1) self.zoomlevel = ZOOM maptype_index = 0 self.radiovar.set(maptype_index) MARKER = "markers=size:tiny|label:B|color:blue|" + str( LATITUDE) + "," + str(LONGITUDE) self.goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, MAPTYPE, MARKER) self.restart() def add_zoom_button(self, text, sign): button = Button(self.canvas, text=text, width=1, command=lambda: self.zoom(sign)) return button def reload(self): self.coords = None self.redraw() self['cursor'] = '' def restart(self): # A little trick to get a watch cursor along with loading self['cursor'] = 'watch' self.after(1, self.reload) def add_radio_button(self, text, index): maptype = self.maptypes[index] Radiobutton(self.radiogroup, text=maptype, variable=self.radiovar, value=index, command=lambda: self.usemap(maptype)).grid(row=0, column=index) def click(self, event): self.coords = event.x, event.y def drag(self, event): self.goompy.move(self.coords[0] - event.x, self.coords[1] - event.y) self.image = self.goompy.getImage() self.redraw() self.coords = event.x, event.y def redraw(self): self.image = self.goompy.getImage() self.image_tk = ImageTk.PhotoImage(self.image) self.label['image'] = self.image_tk self.label.place(x=0, y=0, width=WIDTH, height=HEIGHT) self.radiogroup.place(x=0, y=0) x = int(self.canvas['width']) - 50 y = int(self.canvas['height']) - 80 self.zoom_in_button.place(x=x, y=y) self.zoom_out_button.place(x=x, y=y + 30) def usemap(self, maptype): self.goompy.useMaptype(maptype) self.restart() def zoom(self, sign): newlevel = self.zoomlevel + sign if newlevel > 0 and newlevel < 22: self.zoomlevel = newlevel self.goompy.useZoom(newlevel) self.restart() def check_quit(self, event): if ord(event.char) == 27: # ESC exit(0) #input def geolocation(self): self.maplist = [] self.buttonHeightCounter = .05 API_KEY = 'AIzaSyBPGAbevdKkeXaZT0ZsR0qbO30Bpqqm0Mc' google_places = GooglePlaces(API_KEY) self.query_result = google_places.nearby_search( location=self.entry.get(), radius=700, types=[types.TYPE_RESTAURANT]) self.current_places = self.query_result if self.query_result.has_attributions: print(self.query_result.html_attributions) for place in self.query_result.places: place.get_details() markers = "&markers=size:big|label:S|color:red|" + str( place.details['geometry']['location']['lat']) + "," + str( place.details['geometry']['location']['lng']) + "|" self.maplist.append(markers) print(place.name) self.button_list.append( Button(self, text=place.name, command=lambda pname=place.name: self.on_click(pname), width=25)) self.button_list[-1].place(relx=.70, rely=self.buttonHeightCounter, anchor="c") self.buttonHeightCounter += .035 print(place.formatted_address + "\n") google_maps = GoogleMaps( api_key='AIzaSyDlJqxwlOWWAPwf54ivrpAZw4R1Yb5j6Yk') location = google_maps.search( location=self.entry.get()) # sends search to Google Maps. my_location = location.first() # returns only first location. #MARKER = '&markers=color:blue' + '%' + str(7) + 'Clabel:S%' + str(7) + 'C' + str(my_location.lat) + ',' + str(my_location.lng) #MARKER = "&markers=size:big|label:S|color:blue|" + str(my_location.lat) + "," + str(my_location.lng) + "|" + \ MARKER = self.maplist[1] + self.maplist[2] + self.maplist[3] self.zoomlevel = ZOOM maptype_index = 0 self.radiovar.set(maptype_index) self.goompy = GooMPy(WIDTH, HEIGHT, my_location.lat, my_location.lng, ZOOM, MAPTYPE, MARKER) self.restart() print(self.query_result) print(str(my_location.lat)) print(str(my_location.lng)) #print(self.button_list) def record(self): print("Hello Anthony") #audioCount = 0 CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 44100 RECORD_SECONDS = 10 self.WAVE_OUTPUT_FILENAME = "output" + str(self.audioCount) + ".wav" self.audioCount += 1 p = pyaudio.PyAudio() stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) print("recording...") frames = [] for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): data = stream.read(CHUNK) frames.append(data) print("...done recording") stream.stop_stream() stream.close() p.terminate() wf = wave.open(os.path.join('sounds', self.WAVE_OUTPUT_FILENAME), 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(frames)) wf.close() label = Label(self, text="recording is 10 seconds...done recording") #this creates a new label to the GUI label.place(relx=.35, rely=.80) def upload(self): #Convert .Wav into Binary self.w = wave.open(os.path.join('sounds', 'output0.wav')) #Parameters of the source file (keep this) #print(self.w.getparams()) #Write the binary as a string... self.binary_data = self.w.readframes(self.w.getnframes()) self.w.close() #Store binary into SQL cursorTest = connection.cursor() #TEST INSERT cursorTest.execute( "INSERT INTO `MARKERS` (`id`, `name`, `address`, `lat`, `lng`, `type`,`sound`) VALUES (%s, %s, %s, %s, %s, %s, %s)", ('9', 'Test Human', '999 Test Street, Rozelle, NSW', '-33.861034', '151.171936', 'restaurant', self.binary_data)) # cursorTest.execute("INSERT INTO `MARKERS` (`name`) VALUES (%s)", ('10')) # cursorTest.execute("INSERT INTO `MARKERS` (`address`) VALUES (%s)", ('Insert Name Here')) # cursorTest.execute("INSERT INTO `MARKERS` (`lat`) VALUES (%s)", ('0')) # cursorTest.execute("INSERT INTO `MARKERS` (`lng`) VALUES (%s)", ('0')) # cursorTest.execute("INSERT INTO `MARKERS` (`type`) VALUES (%s)", ('Insert Type Here')) # cursorTest.execute("INSERT INTO `MARKERS` (`sound`) VALUES (%s)", ('Insert Sound Here')) #Read Binary from SQL cursors = connection.cursor(pymysql.cursors.DictCursor) cursors.execute("SELECT sound FROM MARKERS") result_set = cursors.fetchall() x = 0 listSoundbytes = [None] * 1 for row in result_set: listSoundbytes.insert(0, row["sound"]) x += 1 #Convert string to .wav file stringToByte = bytes(listSoundbytes[0]) waveSave = wave.open(os.path.join('sounds', 'testFile.wav'), 'w') #Set parameters for writing waveSave.setparams((2, 2, 44100, 440320, 'NONE', 'not compressed')) waveSave.writeframes(stringToByte) connection.close() #Set sound source to soundbyte from SQL self.sound.setSource( QUrl.fromLocalFile(os.path.join('sounds', 'testFile.wav'))) #The "All clear" print("Upload Successful") label1 = Label(self, text="Upload Successful!") #this creates a new label to the GUI label1.place(relx=.35, rely=.85) def play(self): pygame.init() pygame.mixer.init() sounda = pygame.mixer.Sound("./sounds/testFile.wav") sounda.play() #self.isPlaying = not self.isPlaying #self.isPlaying = True; #if self.isPlaying: # self.sound.play() # print('Play') #else: # self.sound.stop() # print('Stop') #print("play/stop") def delete(self): print("File Deleted from local device") try: os.remove('sounds/' + self.WAVE_OUTPUT_FILENAME) if self.audioCount < 0: self.audioCount -= 1 except OSError as e: print("Error: %s - %s." % (e.filename, e.strerror)) def on_click(self, pname): for place in self.query_result.places: if (place.name == pname): place.get_details() if (place.photos): place.photos[0].get(200, 200) place.photos[2].get(200, 200) url = place.photos[0].url url1 = place.photos[2].url print(url) resource = urllib.request.urlopen(url) im = resource.read() resource.close() self.img = Image.open(BytesIO(im)) resource1 = urllib.request.urlopen(url1) im1 = resource1.read() resource1.close() self.img1 = Image.open(BytesIO(im1)) canvas = Canvas(width=200, height=200, bg='black') canvas1 = Canvas(width=200, height=200, bg='black') canvas.pack() canvas1.pack() canvas.place(relx=.81, rely=.1) canvas1.place(relx=.81, rely=.5) img = self.img.resize((200, 200), Image.ANTIALIAS) self.photo = ImageTk.PhotoImage(img) img1 = self.img1.resize((200, 200), Image.ANTIALIAS) self.photo1 = ImageTk.PhotoImage(img1) canvas.create_image(105, 105, image=self.photo, anchor="c") canvas1.create_image(105, 105, image=self.photo1, anchor="c") self.restart()
if __name__ == '__main__': test_set_ar = { 'LATITUDE': -34.6246, 'LONGITUDE': -58.4017, 'longitude_result': -58.4589, 'latitude_result': -34.6109, 'x_pixels': 266, 'y_pixels': 572, } print(test_set_ar) LONGITUDE = test_set_ar.get('LONGITUDE') LATITUDE = test_set_ar.get('LATITUDE') goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, zoom, MAPTYPE, radius_meters=None) goompy.use_map_type(MAPTYPE) goompy.leftx = 0 goompy.uppery = 572 print(goompy.get_lon_from_x(test_set_ar.get('x_pixels'))) print(goompy.get_lat_from_y(test_set_ar.get('y_pixels'))) print(goompy.get_x_from_lon(test_set_ar.get('longitude_result'))) print(goompy.get_y_from_lat(test_set_ar.get('latitude_result')))
def main(): for zoom in range(START_ZOOM, END_ZOOM): goompy = GooMPy(WIDTH, HEIGHT, LATITUDE, LONGITUDE, zoom, MAPTYPE, None, 4, 1, KMLFILE) goompy._KML2XY() goompy._fetch()
class ReadUpdater(QtCore.QThread): request_viewport_update = QtCore.pyqtSignal() def __init__(self, main_window): super(ReadUpdater, self).__init__() # ########## Reference to top level window ########## self.main_window = main_window # type: QtWidgets.QMainWindow # ########## Get the settings instance ########## self.settings = QtCore.QSettings() # ########## Get the Pick And Plate instance of the logger ########## self.logger = logging.getLogger("RoverBaseStation") self.goompy = GooMPy(2 * WIDTH, HEIGHT, LATITUDE, LONGITUDE, ZOOM, MAPTYPE, 1500) self.tab_widget = self.main_window.tabWidget # type: QtWidgets.QTabWidget # ########## Some Flags ########## self.run_thread_flag = True # ########## Class variables ########## self.data_last_seen = time.time() def run(self): #self.logger.debug("Read Updater Thread Starting...") self.request_viewport_update.connect( self.main_window.show_graphics_view__slot) #self.goompy.move(650, 400) dx = 1 dy = 1 x_num = 0 y_num = 0 dir_x = 0 dir_y = 0 count_max = 500 while self.run_thread_flag: #self.scene.clear() #self.scene = QtWidgets.QGraphicsScene(self) #self.graphics_view.setScene(self.scene) if dir_x: self.goompy.move(-dx, 0) x_num -= 1 else: self.goompy.move(dx, 0) x_num += 1 if dir_y: self.goompy.move(0, -dy) y_num -= 1 else: self.goompy.move(0, dy) y_num += 1 if x_num >= count_max: dir_y = 1 dir_x = 1 elif x_num <= 0: dir_y = 0 dir_x = 0 self.image = self.goompy.getImage().convert( "RGBA") # type: PIL.Image.Image print(self.goompy.northwest) print(self.goompy.southeast) print(self.goompy.uppery) print(self.goompy.leftx) print(self.goompy.bigimage.size) #self.goompy. #self.image = self.image.crop((500, 500, 750, 750)) print(self.image) # print(self.image.height) # print(self.image.width) qim = ImageQt(self.image) #self.pix. # type: QtGui.QPixmap # print(test) # test.setPixmap(pixmap) # print(self.pix.width()) # print(self.pix.height()) # print(self.pix.colorCount()) # self.pix self.pix = QtGui.QPixmap.fromImage(qim) self.request_viewport_update.emit() # while self.wait_til_shown: # self.msleep(1) self.msleep(20) #self.logger.debug("Read Updater Thread Stopping...") def connect_signals_to_slots__slot(self): self.main_window.kill_threads_signal.connect( self.on_kill_threads__slot) def on_image_shown__slot(self): self.wait_til_shown = False def on_kill_threads__slot(self): self.run_thread_flag = False