WhereIsMyMac¶
This example shows how to use the CoreLocation framework and is a translation in Python of the example at “Cocoa with Love”
Sources¶
WhereIsMyMacAppDelegate.py¶
"""
This file is a translation from Objective-C. The original
copy-right:
// Copyright 2009 Matt Gallagher. All rights reserved.
//
// Permission is given to use this source code file, free of charge, in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
"""
import math
import Cocoa
import WebKit # noqa: F401
import CoreLocation
import objc
class WhereIsMyMacAppDelegate(Cocoa.NSObject):
window = objc.ivar()
webView = objc.IBOutlet()
locationManager = objc.ivar()
locationLabel = objc.IBOutlet()
accuracyLabel = objc.IBOutlet()
def applicationDidFinishLaunching_(self, notification):
self.locationManager = CoreLocation.CLLocationManager.alloc().init()
self.locationManager.setDelegate_(self)
self.locationManager.startUpdatingLocation()
@classmethod
def latitudeRangeForLocation_(self, location):
M = 6_367_000.0
# approximate average meridional radius of curvature of earth
metersToLatitude = 1.0 / ((math.pi / 180.0) * M)
accuracyToWindowScale = 2.0
return location.horizontalAccuracy() * metersToLatitude * accuracyToWindowScale
@classmethod
def longitudeRangeForLocation_(self, location):
latitudeRange = WhereIsMyMacAppDelegate.latitudeRangeForLocation_(location)
return latitudeRange * math.cos(
location.coordinate().latitude * math.pi / 180.0
)
@objc.IBAction
def openInDefaultBrowser_(self, sender):
currentLocation = self.locationManager.location()
externalBrowserURL = Cocoa.NSURL.URLWithString_(
"http://maps.google.com/maps?ll=%f,%f&spn=%f,%f"
% (
currentLocation.coordinate().latitude,
currentLocation.coordinate().longitude,
WhereIsMyMacAppDelegate.latitudeRangeForLocation_(currentLocation),
WhereIsMyMacAppDelegate.longitudeRangeForLocation_(currentLocation),
)
)
Cocoa.NSWorkspace.sharedWorkspace().openURL_(externalBrowserURL)
def locationManager_didUpdateToLocation_fromLocation_(
self, manager, newLocation, oldLocation
):
# Ignore updates where nothing we care about changed
if newLocation is None:
return
if oldLocation is None:
pass
elif (
newLocation.coordinate().longitude == oldLocation.coordinate().longitude
and newLocation.coordinate().latitude == oldLocation.coordinate().latitude
and newLocation.horizontalAccuracy() == oldLocation.horizontalAccuracy()
):
return
# Load the HTML for displaying the Google map from a file and replace the
# format placeholders with our location data
path = Cocoa.NSBundle.mainBundle().pathForResource_ofType_(
"HTMLFormatString", "html"
)
with open(path) as fp:
htmlString = fp.read() % (
newLocation.coordinate().latitude,
newLocation.coordinate().longitude,
WhereIsMyMacAppDelegate.latitudeRangeForLocation_(newLocation),
WhereIsMyMacAppDelegate.longitudeRangeForLocation_(newLocation),
)
# Load the HTML in the WebView and set the labels
self.webView.mainFrame().loadHTMLString_baseURL_(htmlString, None)
self.locationLabel.setStringValue_(
"%f, %f"
% (newLocation.coordinate().latitude, newLocation.coordinate().longitude)
)
self.accuracyLabel.setStringValue_(f"{newLocation.horizontalAccuracy():f}")
def locationManager_didFailWithError_(self, manager, error):
self.webView.mainFrame.loadHTMLString_baseURL_(
Cocoa.NSLocalizedString("Location manager failed with error: %s", objc.nil)
% (error.localizedDescription()),
None,
)
self.locationLabel.setStringValue_("")
self.accuracyLabel.setStringValue_("")
def applicationWillTerminate_(self, aNotification):
self.locationManager.stopUpdatingLocation()
main.py¶
import WhereIsMyMacAppDelegate # noqa: F401
from PyObjCTools import AppHelper
AppHelper.runEventLoop()
setup.py¶
"""
Script for building the example.
Usage:
python3 setup.py py2app
"""
from setuptools import setup
setup(
name="WhereIsMyMac",
app=["main.py"],
data_files=["English.lproj", "HTMLFormatString.html"],
setup_requires=[
"py2app",
"pyobjc-framework-Cocoa",
"pyobjc-framework-CoreLocation",
],
)