CoreLocation

I changed the HTML file to acually show a cursor on where I am. It didn’t before.

OK. I have a project that searches in Google Maps. The problem is, if I search a business that has a website, a link will appear for the business, and the site will load in the WebKit frame. How do I stop that? Couldn’t I just use “[[[[[webView mainFrame] provisionalDataSource] request] URL] absoluteString]” to stop incoming websites, but I need it to be converted. Would it just be 's after eveything?

Project (Code, then HTML file):

--
--  Google_MapsAppDelegate.applescript
--  Google Maps
--  Created by Dylan Weber on Sunday, May 9, 2010.
--  Copyright 2010 Dylan Weber. All rights reserved.

script Google_MapsAppDelegate
    property parent : class "NSObject"
    property webView : missing value
    property textfield : missing value
    property NSString : class "NSString"
    property NSBundle : class "NSBundle"
    
    on searchforplace_(sender)
        set myplace to textfield's stringValue() as string
        set myPath to NSBundle's mainBundle's pathForResource_ofType_("mapsembed", "html")
        set urlFromFile to NSString's stringWithContentsOfFile_encoding_error_(myPath, 4, missing value)
        set htmlString to NSString's stringWithFormat_(urlFromFile, myplace)
        webView's mainFrame()'s loadHTMLString_baseURL_(htmlString, missing value)
        performSelectorInBackground_withObject_("checkURL", missing value)
    end searchforplace_
    
    on checkURL()
        log "checking"
        repeat
            if webView's mainFrame()'s provisionalDataSource's request()'s |URL|'s absoluteString() as string does not start with "http://maps.google.com/maps" then
                set myplace to textfield's stringValue() as string
                set myPath to NSBundle's mainBundle's pathForResource_ofType_("mapsembed", "html")
                set urlFromFile to NSString's stringWithContentsOfFile_encoding_error_(myPath, 4, missing value)
                set htmlString to NSString's stringWithFormat_(urlFromFile, myplace)
                webView's mainFrame()'s loadHTMLString_baseURL_(htmlString, missing value)
            end if
        end repeat
    end checkURL
end script

[code]

Google Map [/code]

Dylan,

I tested my code with some made up locations, and it does appear that when oldLocation doesn’t exist, then the program throws an error and doesn’t open the map. I could fix it by adding these lines to the beginning of the locationManager_didUpdateToLocation_fromLocation_ method:

if oldLocation = missing value then
			set oldLocation to CLLocation's alloc()'s initWithLatitude_longitude_(0.0, 0.0)
		end if

Ric

Great, but can you help with my code? My Google Maps Application? :smiley:

I don’t know – what’s wrong with it now? I tried it and it seemed to work ok.

Ric

This one – http://mactweaks.info/files/Google%20Maps.zip

I want it to not go out of google maps, like if I search a business, a link to their site will appear under them and I don’t want WebKit to go away from the maps. (Other words – keep the URL of webkit’s mainframe() to be the HTML file)

Like I said above, I tried it and it works for me – I searched for companies and it never went out of Google Maps. Give me an example of a search that goes out of Google Maps.

Google Map Search “Youtube”.

It will give you a result of youtube. In the “chat bubble,” there is a link to Youtube.com. I don’t want mainframe() to display Youtube.com!

It seems to me that the bubble that comes up when you click on a marker is part of Google Maps functionality, and I don’t know if you can change that. Anything else that loads as a result of clicking in the map isn’t calling your method again – it’s just responding to code imbedded in Google maps.

Well, what is the method that is called when WebView loads a website?

@rdelmar, What happens when there is no location data? Is there a way to simulate it?

With a random location from 2 numbers, ºN and ºW

What I meant was that I’m getting location data where I am. I need to simulate what would happen when someone who uses my app doesn’t have location data where they are.

Oh… ummm… cut the internet. Their won’t be a map, though.

The way I tested my program was to create the newLocation and oldLocation objects and then call the locationManager_didUpdateToLocation_fromLocation_ method directly since the location manager won’t do so if it’s not receiving any location data. I put those in the applicationWillFinishLaunching method. I also changed some of the logic in the locationManager_didUpdateToLocation_fromLocation_ method to take care of the situation where oldLocation doesn’t exist, and split out the part of that method that loads the webView into a new method called runWebView. Here is the code:

script LocatorAppDelegate
	property parent : class "NSObject"
	property CLLocation : class "CLLocation"
	property CLLocationManager : class "CLLocationManager"
	property NSString : class "NSString"
	property NSURL : class "NSURL"
	property NSDate : class "NSDate"
	property NSWorkspace : class "NSWorkspace"
	property NSBundle : class "NSBundle"
	property locationManager : 0
	property webView : missing value
	property locationText : missing value
	property accuracyText : missing value
	
	on openInDefaultBrowser_(sender) --Connected to a button in IB
		set currentLocation to locationManager's |location|()
		if currentLocation is not missing value then
			set lat to currentLocation's coordinate's pointValue()'s x
			set lon to currentLocation's coordinate's pointValue()'s y
			set latRange to latitudeRangeForLocation_(currentLocation)
			set lonRange to longitudeRangeForLocation_(currentLocation)
		else
			set lat to 37.76
			set lon to -122.434
			set latRange to 0.15
			set lonRange to 0.15
		end if
		set browserURL to NSURL's URLWithString_(NSString's stringWithFormat_("http://maps.google.com/maps?ll=%@,%@&spn=%@,%@", lat, lon, latRange, lonRange))
		NSWorkspace's sharedWorkspace's openURL_(browserURL)
	end openInDefaultBrowser_
	
	on locationManager_didFailWithError_(locationManager, myError)
		set errorString to NSString's stringWithFormat_("Location manager failed with error: %@", myError's localizedDescription())
		webView's mainFrame()'s loadHTMLString_baseURL_(errorString, missing value)
		locationText's setStringValue_("No Data Available")
		accuracyText's setStringValue_("")
	end locationManager_didFailWithError_
	
	on locationManager_didUpdateToLocation_fromLocation_(locationManager, newLocation, oldLocation)
		if oldLocation is missing value then
			runWebView_(newLocation)
		else if newLocation's coordinate's pointValue()'s y = oldLocation's coordinate's pointValue()'s y and ¬
			newLocation's coordinate's pointValue()'s x = oldLocation's coordinate's pointValue()'s x and ¬
			newLocation's horizontalAccuracy() = oldLocation's horizontalAccuracy() then
			return
		else
			runWebView_(newLocation) -- goes to runWebView if oldLocation and newLocation are different
		end if
	end locationManager_didUpdateToLocation_fromLocation_
	
	on runWebView_(newLocation)
		set myPath to NSBundle's mainBundle's pathForResource_ofType_("HTMLFormatString", "html")
		set urlFromFile to NSString's stringWithContentsOfFile_encoding_error_(myPath, 4, missing value)
		set lat to newLocation's coordinate's pointValue()'s x
		set lon to newLocation's coordinate's pointValue()'s y
		set latRange to latitudeRangeForLocation_(newLocation)
		set lonRange to longitudeRangeForLocation_(newLocation)
		set htmlString to NSString's stringWithFormat_(urlFromFile, lat, lon, latRange, lonRange)
		webView's mainFrame()'s loadHTMLString_baseURL_(htmlString, missing value)
		locationText's setStringValue_(NSString's stringWithFormat_("%@, %@", lat, lon))
		accuracyText's setStringValue_(NSString's stringWithFormat_("%@", newLocation's horizontalAccuracy()))
	end runWebView_
	
	on latitudeRangeForLocation_(aLocation)
		set M to 6.367E+6 --approximate average meridional radius of curvature of earth
		set metersToLatitude to 1.0 / ((3.1416 / 180.0) * M)
		set accuracyToWindowScale to 2.0
		return (aLocation's horizontalAccuracy()) * metersToLatitude * accuracyToWindowScale
	end latitudeRangeForLocation_
	
	on longitudeRangeForLocation_(aLocation)
		set latRange to latitudeRangeForLocation_(aLocation)
		return latRange * (getCos_((aLocation's coordinate's pointValue()'s x) * 3.1416 / 180.0))
	end longitudeRangeForLocation_
	
	on getCos_(x)
		return (1 - x ^ 2 / 2 + x ^ 4 / 24 - x ^ 6 / 720 + x ^ 8 / 40320) --Approximates the cosine function
	end getCos_
	
	on applicationWillFinishLaunching_(aNotification)
		set locationManager to CLLocationManager's alloc()'s init()
		set oldLocation to CLLocation's alloc()'s initWithLatitude_longitude_(38.002, -122)
		set newLocation to CLLocation's alloc()'s initWithLatitude_longitude_(38.001, -122)
		locationManager's setDelegate_(me)
		locationManager's setDesiredAccuracy_(0)
		locationManager's setDistanceFilter_(0)
		locationManager's startUpdatingLocation()
		if locationManager's |location|() is missing value then
			locationManager_didUpdateToLocation_fromLocation_(locationManager, newLocation, oldLocation) --Call this directly
		end if
	end applicationWillFinishLaunching_
	
	on killProgram_(sender) --Connected to a button in IB
		tell current application's NSApp to terminate_(me)
	end killProgram_
	
	on applicationShouldTerminate_(sender)
		locationManager's stopUpdatingLocation()
		return current application's NSTerminateNow
	end applicationShouldTerminate_
	
end script

So, when CoreLocation can’t get location data will newLocation just be missing value?

I don’t know about that one, but if you set up an observer to look at notifications coming from webView, you’ll see that it sends a “WebProgressFinishedNotification” message after it finishes loading. This is the modification of your code that I made to look at notifications:

script Google_MapsAppDelegate
	property parent : class "NSObject"
	property webView : missing value
	property textfield : missing value
	property NSString : class "NSString"
	property NSBundle : class "NSBundle"
	property NSNotificationCenter : class "NSNotificationCenter"
	
	on searchforplace_(sender)
		set myplace to textfield's stringValue() as string
		set myPath to NSBundle's mainBundle's pathForResource_ofType_("mapsembed", "html")
		set urlFromFile to NSString's stringWithContentsOfFile_encoding_error_(myPath, 4, missing value)
		set htmlString to NSString's stringWithFormat_(urlFromFile, myplace)
		webView's mainFrame()'s loadHTMLString_baseURL_(htmlString, missing value)
	end searchforplace_
	
	on logNotifications_(aNotification)
		log aNotification
	end logNotifications_
	
	on applicationWillFinishLaunching_(aNotification)
		set observer to NSNotificationCenter's defaultCenter
		observer's addObserver_selector_name_object_(me, "logNotifications:", missing value, webView) 
	end applicationWillFinishLaunching_
end script

If you want to see all the notifications, replace webView in the addObserver_selector_name_object_ method with missing value --you’ll get a whole lot of notifications!

Ric

Yes, if you don’t create it explicitly with the CLLocation’s alloc()'s initWithLatitude:longitude:

Ric

Ok, will locationManager_didUpdateToLocation_fromLocation_ still be called if it can’t get location data, or is there a separate method for that?

No, it doesn’t get called if the location manager isn’t getting location data. That’s why I put an explicit call to it in the if statement in the applicationWillFinishLaunching method, so I could test whether that method was working.

Ric