diff --git a/MapWalker/MapWalker.xcodeproj/project.pbxproj b/MapWalker/MapWalker.xcodeproj/project.pbxproj index 06ffb7b..95d1127 100644 --- a/MapWalker/MapWalker.xcodeproj/project.pbxproj +++ b/MapWalker/MapWalker.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + B2009BFD1D5BA1530016A625 /* JumpLocationWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2009BFC1D5BA1530016A625 /* JumpLocationWindowController.swift */; }; + B2009BFF1D5BA1630016A625 /* JumpLocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2009BFE1D5BA1630016A625 /* JumpLocationViewController.swift */; }; + B2A9F13F1D5C69B5006C4B9C /* MapPin.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2A9F13E1D5C69B5006C4B9C /* MapPin.swift */; }; E182A4891D571E55002C9180 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E182A4881D571E55002C9180 /* AppDelegate.swift */; }; E182A48B1D571E55002C9180 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E182A48A1D571E55002C9180 /* ViewController.swift */; }; E182A48D1D571E55002C9180 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E182A48C1D571E55002C9180 /* Assets.xcassets */; }; @@ -37,6 +40,9 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + B2009BFC1D5BA1530016A625 /* JumpLocationWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JumpLocationWindowController.swift; sourceTree = ""; }; + B2009BFE1D5BA1630016A625 /* JumpLocationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JumpLocationViewController.swift; sourceTree = ""; }; + B2A9F13E1D5C69B5006C4B9C /* MapPin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MapPin.swift; sourceTree = ""; }; E182A4851D571E55002C9180 /* MapWalker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MapWalker.app; sourceTree = BUILT_PRODUCTS_DIR; }; E182A4881D571E55002C9180 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; E182A48A1D571E55002C9180 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -112,7 +118,10 @@ E182A4B81D57289B002C9180 /* WindowController.swift */, E182A48C1D571E55002C9180 /* Assets.xcassets */, E182A48E1D571E55002C9180 /* Main.storyboard */, + B2009BFC1D5BA1530016A625 /* JumpLocationWindowController.swift */, + B2009BFE1D5BA1630016A625 /* JumpLocationViewController.swift */, E182A4911D571E55002C9180 /* Info.plist */, + B2A9F13E1D5C69B5006C4B9C /* MapPin.swift */, ); path = MapWalker; sourceTree = ""; @@ -284,8 +293,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B2009BFF1D5BA1630016A625 /* JumpLocationViewController.swift in Sources */, E182A48B1D571E55002C9180 /* ViewController.swift in Sources */, + B2A9F13F1D5C69B5006C4B9C /* MapPin.swift in Sources */, E182A4B91D57289B002C9180 /* WindowController.swift in Sources */, + B2009BFD1D5BA1530016A625 /* JumpLocationWindowController.swift in Sources */, E182A4891D571E55002C9180 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/MapWalker/MapWalker/AppDelegate.swift b/MapWalker/MapWalker/AppDelegate.swift index eed38fd..13b807b 100644 --- a/MapWalker/MapWalker/AppDelegate.swift +++ b/MapWalker/MapWalker/AppDelegate.swift @@ -7,10 +7,11 @@ // import Cocoa +import MapKit @NSApplicationMain -class AppDelegate: NSObject, NSApplicationDelegate { - +class AppDelegate: NSObject, NSApplicationDelegate, JumpLocationProtocol { + func applicationDidFinishLaunching(notification: NSNotification) { // Insert code here to initialize your application } @@ -19,5 +20,48 @@ class AppDelegate: NSObject, NSApplicationDelegate { // Insert code here to tear down your application } + @IBAction func menuJumpToLocationClick(sender: AnyObject) { + let storyboard = NSStoryboard(name: "Main", bundle: nil) + let jumpLocationWindowController = storyboard.instantiateControllerWithIdentifier("JumpLocation") as! NSWindowController + + if let jumpLocationWindow = jumpLocationWindowController.window { + let jumpLocationViewController = jumpLocationWindow.contentViewController as! JumpLocationViewController + jumpLocationViewController.delegate = self + if let coordinate = getCoordinateFromViewController() { + jumpLocationViewController.setCoordinate(coordinate) + let application = NSApplication.sharedApplication() + application.runModalForWindow(jumpLocationWindow) + } + } + } + + @IBAction func menuRemoveAllPinsClick(sender: AnyObject) { + getMapViewController()?.handleRemoveAllPins() + } + + func returnJumpToLocation(coordinate: CLLocationCoordinate2D) { + getMapViewController()?.handleJumpToLocation(coordinate) + } + + func returnMarkItLocation(coordinate: CLLocationCoordinate2D) { + getMapViewController()?.handleMarkItLocation(coordinate) + } + + func getuserLocation() -> CLLocationCoordinate2D? { + return getMapViewController()?.userLocationCoordinate; + } + + func getMapViewController() -> ViewController? { + for window in NSApplication.sharedApplication().windows { + if let viewController:ViewController = window.contentViewController as? ViewController { + return viewController + } + } + return nil + } + + func getCoordinateFromViewController() -> CLLocationCoordinate2D? { + return getMapViewController()?.centerCoordinate; + } } diff --git a/MapWalker/MapWalker/Base.lproj/Main.storyboard b/MapWalker/MapWalker/Base.lproj/Main.storyboard index 1a22453..41aaaa3 100644 --- a/MapWalker/MapWalker/Base.lproj/Main.storyboard +++ b/MapWalker/MapWalker/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - - + + @@ -56,84 +56,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -149,12 +75,6 @@ - - - - - - @@ -166,447 +86,22 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - + - + - - - + + - - - - - - - + @@ -664,7 +159,7 @@ - + @@ -678,6 +173,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -697,6 +326,9 @@ + + + diff --git a/MapWalker/MapWalker/JumpLocationViewController.swift b/MapWalker/MapWalker/JumpLocationViewController.swift new file mode 100644 index 0000000..cb04272 --- /dev/null +++ b/MapWalker/MapWalker/JumpLocationViewController.swift @@ -0,0 +1,60 @@ +// +// JumpLocationViewController.swift +// MapWalker +// +// Created by Johnny on 8/11/16. +// Copyright © 2016 MapWalker. All rights reserved. +// + +import Foundation +import MapKit +import Cocoa + +protocol JumpLocationProtocol { + func returnMarkItLocation (coordinate:CLLocationCoordinate2D) + func returnJumpToLocation (coordinate:CLLocationCoordinate2D) + func getuserLocation () -> CLLocationCoordinate2D? +} + +class JumpLocationViewController: NSViewController, NSWindowDelegate { + @IBOutlet weak var textFieldLat: NSTextField! + @IBOutlet weak var textFieldLng: NSTextField! + + var delegate:JumpLocationProtocol? + + override func viewDidLayout() { + view.window?.delegate = self + } + + func windowWillClose(notification: NSNotification) { + let application = NSApplication.sharedApplication() + application.stopModal() + } + + @IBAction func buttonFillGPSLocationClick(sender: AnyObject) { + if let coordinate = delegate?.getuserLocation() { + setCoordinate(coordinate) + } + } + + @IBAction func buttonMarkItClick(sender: AnyObject) { + view.window?.close() + delegate?.returnMarkItLocation(getInputCoordinate()) + } + + @IBAction func buttonJumpToClick(sender: AnyObject) { + view.window?.close() + delegate?.returnJumpToLocation(getInputCoordinate()) + } + + func getInputCoordinate() -> CLLocationCoordinate2D { + let lat:Double = (Double(textFieldLat.stringValue) == nil) ? 0.0 : Double(textFieldLat.stringValue)! + let lng:Double = (Double(textFieldLng.stringValue) == nil) ? 0.0 : Double(textFieldLng.stringValue)! + return CLLocationCoordinate2D.init(latitude: lat, longitude: lng) + } + + func setCoordinate(coordinate:CLLocationCoordinate2D) { + textFieldLat.stringValue = String(coordinate.latitude) + textFieldLng.stringValue = String(coordinate.longitude) + } +} \ No newline at end of file diff --git a/MapWalker/MapWalker/JumpLocationWindowController.swift b/MapWalker/MapWalker/JumpLocationWindowController.swift new file mode 100644 index 0000000..1d4f53d --- /dev/null +++ b/MapWalker/MapWalker/JumpLocationWindowController.swift @@ -0,0 +1,15 @@ +// +// JumpLocationWindowController.swift +// MapWalker +// +// Created by Johnny on 8/11/16. +// Copyright © 2016 MapWalker. All rights reserved. +// + +import Foundation +import Cocoa +import MapKit + +class JumpLocationWindowController : NSWindowController { + +} \ No newline at end of file diff --git a/MapWalker/MapWalker/MapPin.swift b/MapWalker/MapWalker/MapPin.swift new file mode 100644 index 0000000..f3f1da3 --- /dev/null +++ b/MapWalker/MapWalker/MapPin.swift @@ -0,0 +1,22 @@ +// +// MyAnnotation.swift +// MapWalker +// +// Created by Johnny on 8/11/16. +// Copyright © 2016 MapWalker. All rights reserved. +// + +import Foundation +import MapKit + +class MapPin : NSObject, MKAnnotation { + var coordinate: CLLocationCoordinate2D + var title: String? + var subtitle: String? + + init(coordinate: CLLocationCoordinate2D, title: String, subtitle: String) { + self.coordinate = coordinate + self.title = title + self.subtitle = subtitle + } +} \ No newline at end of file diff --git a/MapWalker/MapWalker/ViewController.swift b/MapWalker/MapWalker/ViewController.swift index 284337b..514cff7 100644 --- a/MapWalker/MapWalker/ViewController.swift +++ b/MapWalker/MapWalker/ViewController.swift @@ -11,17 +11,20 @@ import MapKit import Dispatch class ViewController: NSViewController, MKMapViewDelegate, CLLocationManagerDelegate { - + internal let defaultLocationCoordinate = CLLocationCoordinate2D(latitude: 25.033680, longitude: 121.564548) // Location of Taipei 101 let headingDelta:CLLocationDirection = 3.0 let moveDelta:CLLocationDegrees = 0.0001 var heading:CLLocationDirection = 0.0 - var centerCoordinate = CLLocationCoordinate2D() - + internal var centerCoordinate = CLLocationCoordinate2D() + internal var userLocationCoordinate = CLLocationCoordinate2D() + let locationManager = CLLocationManager() var keyDownList = Set(minimumCapacity: 10) var keyHandlerDispatched:Bool = false + + var timer:NSTimer? @IBOutlet weak var mapView: MKMapView! @@ -35,6 +38,8 @@ class ViewController: NSViewController, MKMapViewDelegate, CLLocationManagerDele locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.startUpdatingLocation() + timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: #selector(ViewController.applyDefaultCoordinate), userInfo: nil, repeats: false) + mapView.showsBuildings = true mapView.mapType = .Standard } @@ -44,16 +49,30 @@ class ViewController: NSViewController, MKMapViewDelegate, CLLocationManagerDele // Update the view, if already loaded. } } + + func applyDefaultCoordinate() { + locationManager.stopUpdatingLocation() + centerCoordinate = defaultLocationCoordinate + userLocationCoordinate = defaultLocationCoordinate + print("applyDefaultCoordinate lat:\(centerCoordinate.latitude) lng:\(centerCoordinate.longitude)") + initializeMap() + } func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) { locationManager.stopUpdatingLocation() + timer?.invalidate() + userLocationCoordinate = newLocation.coordinate centerCoordinate = newLocation.coordinate /* let viewRegion = MKCoordinateRegionMake(centerCoordinate, MKCoordinateSpan(latitudeDelta: 0.001, longitudeDelta: 0.001)) let adjustedRegion = mapView.regionThatFits(viewRegion) mapView.setRegion(adjustedRegion, animated: true) */ + initializeMap() + } + + func initializeMap() { updateCamera(false) let url = NSURL(fileURLWithPath: "MapWalker.gpx") let folderUrl = url.URLByDeletingLastPathComponent @@ -122,6 +141,10 @@ class ViewController: NSViewController, MKMapViewDelegate, CLLocationManagerDele if (keyDownList.contains(NSRightArrowFunctionKey)) { moveRight(nil) } + if (keyDownList.contains(Int((String(" ").unicodeScalars.first?.value)!))) { + updateCamera() + } + dispatch_async(dispatch_get_main_queue()) { self.keyHandler() } @@ -146,6 +169,7 @@ class ViewController: NSViewController, MKMapViewDelegate, CLLocationManagerDele } func handleKeyDown(event: NSEvent) { + guard let characters = event.charactersIgnoringModifiers else { return } @@ -175,6 +199,9 @@ class ViewController: NSViewController, MKMapViewDelegate, CLLocationManagerDele keyDownList.insert(Int((String("=").unicodeScalars.first?.value)!)) case Int((String("-").unicodeScalars.first?.value)!): keyDownList.insert(Int((String("+").unicodeScalars.first?.value)!)) + + case Int((String(" ").unicodeScalars.first?.value)!): + keyDownList.insert(Int((String(" ").unicodeScalars.first?.value)!)) default: return } @@ -211,10 +238,28 @@ class ViewController: NSViewController, MKMapViewDelegate, CLLocationManagerDele keyDownList.remove(Int((String("=").unicodeScalars.first?.value)!)) case Int((String("-").unicodeScalars.first?.value)!): keyDownList.remove(Int((String("+").unicodeScalars.first?.value)!)) + + case Int((String(" ").unicodeScalars.first?.value)!): + keyDownList.remove(Int((String(" ").unicodeScalars.first?.value)!)) default: - break; + break; } } + + internal func handleJumpToLocation(coordinate: CLLocationCoordinate2D) { + centerCoordinate = coordinate + updateCamera() + } + + internal func handleMarkItLocation(coordinate: CLLocationCoordinate2D) { + let num = mapView.annotations.count + 1 + let mapPin = MapPin.init(coordinate: coordinate, title: "Location \(num)", subtitle: "Latitude:\(centerCoordinate.latitude)\nLongitude:\(centerCoordinate.longitude)") + mapView.addAnnotation(mapPin) + } + + internal func handleRemoveAllPins() { + mapView.removeAnnotations(mapView.annotations) + } override func moveUp(sender: AnyObject?) { let scaleFactor = 1500.0 / mapView.camera.altitude @@ -239,5 +284,9 @@ class ViewController: NSViewController, MKMapViewDelegate, CLLocationManagerDele heading += headingDelta updateCamera() } + + @IBAction func roundButtonClick(sender: AnyObject) { + updateCamera() + } }