Thursday, 18 June 2009

iPhone OS 3.0 - Safari Geolocation

Having installed iPhone OS 3.0 today, the first thing I wanted to play with (after MMS and Copy/Paste) was the Safari Geographical Location support.

The best example code I found was this iPhone 3.0 geolocation javascript API example... however for some reason the Google 'static map' images wouldn't work for me. I'm not 100% sure why (since the blog post appears to show it working) - but Safari on the iPhone does handle http://maps.google.com URLs in a special way (at least it does if they're anchor/links, in which case it triggers the Maps application).

Anyway, since I was keen to get "something" working, I Googled a basic 'image passthrough proxy' - which seemed to fix the problem.
iPhone safari geolocation

The HTML and javascript is very simple (it's repeated from here).

function handler(location) {
var message = document.getElementById("message");
var loc = location.coords.latitude + "," + location.coords.longitude;
message.innerHTML = "<img src='MapImageHandler.aspx?centerPoint="+ loc +"' />";
message.innerHTML+="<p>Longitude: " + location.coords.longitude + "<br />";
message.innerHTML+="Latitude: " + location.coords.latitude + "<br />";
message.innerHTML += "Accuracy: " + location.coords.accuracy + "</p>";
}
navigator.geolocation.getCurrentPosition(handler);
The MapImageHandler.aspx code is also very short (and was sourced from here).

That's about the most basic geolocation sample you could... now to find something useful to do with it! Thanks to the two authors of the code I stitched together (blog.bemoko.com and guy off CodeProject).

Wednesday, 17 June 2009

Customizing Bing (on your site)

It's fairly easy to create a site-specific, bing-powered search box, using the basic wizard at www.bing.com/siteowner.

However, it turned out to be less obvious how to 'customize' it's behaviour... specifically I wanted the search to search 'sites in Australia' by default. The final result is shown below, and you can try it here



Working with Advanced Queries in the Windows Live Search Box provides some hints about how you can customize the javascript var WLSearchBoxConfiguration={...} which controls how the search box works.

By default it looks like this

var WLSearchBoxConfiguration=
{
"global":{
"serverDNS":"www.bing.com",
"market":"en-AU"
},
"appearance":{
"autoHideTopControl":false,
"width":600,
"height":400,
"theme":"Blue"
},
"scopes":[
{
"type":"web",
"caption":"&#x57;&#x65;&#x62;",
"searchParam":""
}
]
}
which provides a simple web search. To force the search to be "only for sites from Australia" we needed to add a new scope with a searchParam set:
"searchParam":"loc:AU"

Restricting to a specific site/domain is more obvious:
"searchParam": "site:conceptdev.blogspot.com"


It ends up looking like this:
var WLSearchBoxConfiguration=
{
"global":{
"serverDNS":"www.bing.com",
"market":"en-AU"
},
"appearance":{
"autoHideTopControl":false,
"width":600,
"height":400,
"theme":"Blue"
},
"scopes": [
{
"type": "web",
"caption": "this site",
"searchParam": "site:conceptdevelopment.net"
}
,
{
"type": "web",
"caption": "ConceptDev Blog",
"searchParam": "site:conceptdev.blogspot.com"
}
,
{
"type":"web",
"caption":"&#x57;&#x65;&#x62;&#x20;&#x28;&#x41;&#x75;&#x73;&#x74;&#x72;&#x61;&#x6C;&#x69;&#x61;&#x29;",
"searchParam":"loc:AU"
}
,
{
"type":"web",
"caption":"&#x57;&#x65;&#x62;&#x20;&#x28;&#x61;&#x6c;&#x6C;&#x29;",
"searchParam":""
}
]
}
It doesn't look like you need to worry too much about the ASCII-Hex encoding for simple characters (although if you want to encode them, there are plenty of tools).

Wednesday, 10 June 2009

How I read a resumé...

I came across this graphic today - linked from a great post on How to apply for a professional job - and had to post a link to it. Many of the points are funny/humorous - generally because they're (kinda) true! All the ones about attention-to-detail in your CV are 100% spot-on.

Wednesday, 27 May 2009

Twitter spam = FAIL

In the normal course of tweeting today, I happened to post

Argh - moving an ASP.NET app that requires Crystal Reports for VS 2003... oh the humanity
Nothing special about that - I often complain about stuff on Twitter... but mostly programming and stuff, not specific products or companies (see When Word of Mouth Got a Permalink) so I was unprepared for what happened next...



W.T.F.!? Okay so Twitter is totally open and there are all sorts of search-bots BUT give-me-a-break with the crappy marketing line and unattended twitter account.

Hey, Windward Studios, I don't CARE about Windward Reports. I didn't ask about Windward Reports, and your response did nothing to help me out/solve my problem. If there was any selling opportunity for you here at all, it required some value-add and not a crappy sales line. Looking at your Twitter page reveals no evidence of any personalized responses at all - just mindless automated crap.

What's worse, you've found my tweet by searching for a competitors product name, which is underhanded at best. Try stuffing your website with competitors names and see how much Google likes that...

Welcome to my Twitter blocked list, and also to the list of products/companies that I will never use or do business with.


Phew now I feel better :-)

Thursday, 14 May 2009

Microsoft Translator Widget

The Microsoft Translator Widget has been popping up on various sites recently - and now some of mine...

ConceptDevelopment.net in Spanish


Geoquery2008.com in Japanese


It's difficult to tell how useful this will be - unless Google can 'discover' this content is available in other languages it will be difficult to attract foreign-language traffic to Translator-enabled sites. It's all client-side/script-driven, so Google isn't going to get any translated content under normal spidering conditions. Those who land on the content organically may find it helpful I suppose...
I wonder if Live Search does anything special for Translator sites?

Tuesday, 12 May 2009

Draw on Silverlight Virtual Earth Map Control

There are a couple of different projects where I'd like to enable 'drawing' on a map (including RaceReplay.net) - this is a basic first-cut of drawing within the Microsoft VE Map Control.

Each click on the map will start/continue a line. The MouseLeave event is wired to start a 'new' line. Navigating the map (dragging/double-click zoom) also causes points to be drawn - obviously this needs some work...


The two files required to build it are Page.xaml and Page.xaml.cs, the key pieces of code being

private void VEMap_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Map m = (Map)sender;
Location l = m.ViewportPointToLocation(e.GetPosition(m));
if (polyline == null)
CreateNewPolyline(l);
else
polyline.Locations.Add(l);
}
and
private void CreateNewPolyline(Location startPoint)
{
polyline = new MapPolyline();
polyline.Stroke = new SolidColorBrush(Colors.Red);
polyline.StrokeThickness = 2;
var lc = new LocationCollection();
lc.Add(startPoint);
polyline.Locations = lc;
VEMap.Children.Add(polyline);
}
Simple, eh?

p.s. these are plain old straight lines - at the 'continent' level you might expect them to curve as though on a great-circle; I'm not too worried about implementing that right now since the target usage of my drawing is at a much "smaller scale"... however Geoquery2008 does draw great circle lines correctly...

Saturday, 9 May 2009

Silverlight DataContractJsonSerializer Error

Admittedly there is very little excuse for hand-crafting Json output these days, with libraries like Json.NET available, and WCF supporting Json natively. However, I was tweaking an existing ASPX page (that was actually rendering Xaml for a Silverlight 1.0 application) to turn it into a 'service' for Silverlight 2.0... and it seemed like the fastest way to do that was simply replace a whole pile of <s and >s with {}

I got some hints/reminders on how to Consume a JSON object in Silverlight, and found Jsonlint really helpful in tuning the output until it was valid Json.


Then I created a 'matching' object model in Silverlight C#


and wired up the OpenReadCompleted event using DataContractJsonSerializer


Everything LOOKED like it should work, so at first I was confused by this error message:
Unable to cast object of type 'System.Collections.Generic.List`1[System.Object]' to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]'

After staring blankly at the code for a while, I finally realised where my Json had gone wrong -- at the very root of my Json response (see Jsonlint image above) I was "accidentally" wrapping the entire Json output with an unnecessary [] pair. I guess this meant the Deserializer was expecting to cast into a collection (albeit with a single element), but I was intending the root Json element to be a single object (to match my C# JsonCourse).

The simple fix was removing the enclosing [] so that my Json started off like this instead:

{
"width": 800 ,
"height": 600 ,
"runners": [
{
"name": "mapcanberramarathon",
"points": [
Lesson for tonight is to better understand the underlying Json representation before consuming it (or else use a library rather than hand-craft the output). Anyway now it is fixed RaceReplay.net 2.0 is that much closer to fruition...