Wednesday, 27 June 2007

"Corporate"Book?

Interesting article about Facebook for the Enterprise.
"Today, I see a combination of Twitter and Facebook as having the potential to replace 90% of the email I receive while improving my personal productivity."

Many companies still don't see IM as anything other than a nuisance to be blocked, so it's sorta interesting to think about whether spending time on Facebook can be 'productive'.

Quote from Facebook generations
"...my 14-year-old daughter is appalled that I am a member of Facebook, and refuses to let me friend her, lest her other friends find out via News Feed."
raises an issue with I suspect would extend into "Corporate"Book - do you really want everyone knowing everything about you... at work?

[sot] Apparently Australia is the 5th biggest Facebook community, after USA, Canada, UK & Norway!

UPDATE: Looking for Facebook applications or ideas? - someone's already started a 'portal' for Facebook apps and news. Helps find neat new stuff, like the Facebook ToolBar for Firefox - because you don't spend enough time checking Facebook already...

Saturday, 23 June 2007

Synchronise Live Maps & Silverlight canvas


If you overlay a location-specific Silverlight canvas on a Live Map (or is it Virtual Earth?, you'll probably want to 'synchronise' the canvas with the underlying map as it is panned/zoomed.

Although it might seem a tough task, with the help of the Virtual Earth 5 SDK it's relatively easy.

Firstly, check out the end result - a Silverlight canvas/animation that zooms and pans with the Live Map underneath it.

To accomplish the effect, I needed to:

0. Load the map and Silverlight controls
map = new VEMap('myMap');
map.LoadMap(
new VELatLong(-33.865052673579655, 151.22375965118408),
16, VEMapStyle.Hybrid);
//...
Sys.Silverlight.createObject( "xaml/Domain.Xaml", ...
Remembering to set isWindowless:'true' and the position of the elements so they float together.

1. Add Scale and Translate Transforms to the canvas
lt;Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"
x:Name="canvasScale" />
<TranslateTransform X="0" Y="0"
x:Name="canvasTranslate" Name="canvasTranslate" />
</TransformGroup>
</Canvas.RenderTransform>
(this was the only change required to the Xaml). You will use the x:Names later to make it easy to transform the canvas.

2. Determine the lat-long of the canvas

So that you can always position it accurately, regardless of how the map has been panned or zoomed. In this case, the top-left of the canvas should be is at 33.858210507117995, 151.2127733230591, and the map center when loaded is -33.865052673579655, 151.22375965118408.

3. Support panning
Simply shift the map and canvas by the same pixel delta, eg. simply call the Pan function on the map object, and modify the named TranslateTransform on the canvas.
function MoveNorth()
{
map.Pan(0, -100);
var sl8 = document.getElementById("WpfeControlHost_1");
var canvasT = sl8.content.findName("canvasTranslate");
//canvasT.X = canvasT.X - 100;
canvasT.Y = canvasT.Y + 100;
}

4. Support zooming
Other than a little bit of hardcoding, the zoom javascript is pretty simple
function ZoomIn()
{
map.ZoomIn();
var zoom = map.GetZoomLevel();
media_scale(zoom);
return false;
}
function media_scale(zoomLevel)
{
var sl8 = document.getElementById("WpfeControlHost_1");
var canvasT = sl8.content.findName("canvasTranslate");
var canvasS = sl8.content.findName("canvasScale");

var canvasLatLong = new VELatLong(-33.858210507117995, 151.2127733230591);
var canvasPixel = map.LatLongToPixel(canvasLatLong);

canvasT.X = canvasPixel.x;
canvasT.Y = canvasPixel.y;

if (zoomLevel == 17)
{
canvasS.ScaleX = 2;
canvasS.ScaleY = 2;
}
else if (zoomLevel == 16)
{
canvasS.ScaleX = 1;
canvasS.ScaleY = 1;
}
else if (zoomLevel == 15)
{
canvasS.ScaleX = 0.5;
canvasS.ScaleY = 0.5;
}
else if (zoomLevel == 14)
{
canvasS.ScaleX = 0.25;
canvasS.ScaleY = 0.25;
}
else if (zoomLevel == 13)
{
canvasS.ScaleX = 0.125;
canvasS.ScaleY = 0.125;
}
else if (zoomLevel == 12)
{
canvasS.ScaleX = 0.0625;
canvasS.ScaleY = 0.0625;
}
// haven't supported tinier zoom levels - might need to just hide content?
}

As long as your canvas and map loaded 'in sync', the panning should work without trouble, and if the top-left lat-long of your canvasis set, zooming should work too. Note that the scale-factors will depend on what 'resolution' your original Xaml was drawn in - I was tracing a map at zoom level 16 (as you can see).

There's a lot more you could add to this - including animating the zoom and supporting 'drag' for the canvas and map...


Thursday, 21 June 2007

Silverlight/Live Maps overlay

sydney landmarks is based on
Using Opacity with a Silverlight / Virtual Earth Mashup (Remix) - in addition to changing the locations it's also using v5 of the map sdk (rather than v4).

The idea is to eventually get RaceReplay.net working with 'live' maps rather than using embedded images.

No source is "posted" - it's all right there in the browser for the View Source Reflector tool for Silverlight to see.

Monday, 18 June 2007

New code online...

New code uploaded on

RaceReplay.net - more courses, satellite imagery

RecipeNow.net - new look, SEO friendly pagenames (Silverlight 'recipe book' "coming soon")

Nothing new on Searcharoo.net but came across some more 'users': Ultimate Safari, Health service. Kinda funny seeing it in the wild.

Saturday, 16 June 2007

Silverlight z-order, html layering, etc

Took longer that it should to figure this one out: the Silverlight control on RaceReplay.net was obscuring the CssControlAdaptor menus.

Anyway, short story is that the solution is simple - WindowlessMode - and is introduced in this post on Using Opacity with a ... Mashup.

However, it shows javascript new agHost for "WPF/E", which looks slightly different now we have "Silverlight", so find your createSilverlight() function and add the bolded line (don't forget the comma):
function createSilverlight()
{
var scene = new Blend1.Scene();
Sys.Silverlight.createObjectEx({
source: "Scene.xaml",
parentElement: document.getElementById("SilverlightControlHost"),
id: "SilverlightControl",
properties: {
width: "100%",
height: "100%",
version: "0.9",
isWindowless: "true"
},
events: {
onLoad: Sys.Silverlight.createDelegate(scene, scene.handleLoad)
}
});
}
[UPDATE] isWindowless works just fine on:

  • Windows/IE

  • Windows/Firefox

  • MacOS/Firefox - Css menus look/work great versus the standard ASP.NET control

... but there seems to be a little problem with MacOS/Safari -- the menus pop-down behind the Silverlight control (making them slightly useless) BUT if you know their content, the mouseclick actually seems to go through the Silverlight control and trigger the relevant menuitem/link! Weird.
BTW, Silverlight doesn't even install on Safari 3.0 for Windows (yet)

Friday, 15 June 2007

HtmlAgilityPack rocks (again)

I've said it before, but have to say it again... the HtmlAgilityPack is awesome.

If you are doing any sort of scraping or other Html processing and aren't using it, you're writing too much code!

Today's task was parsing 38 html pages of html-tabular data into SQL INSERT statements (37,919 statements in the end). Create a ConsoleApplication, using System.IO and HtmlAgilityPack, and use this Main (redirecting the output to a textfile program.exe > inserts.sql)

string[] filenames = Directory.GetFiles(@"C:\Temp\", "*.htm", SearchOption.TopDirectoryOnly);
foreach(string filename in filenames)
{
string file = File.OpenText(filename).ReadToEnd(); // parsing out the <table> i want here
int tableStart = file.IndexOf("<table"); tableStart = file.IndexOf("<table", tableStart + 1);
int tableEnd = file.IndexOf("</table>") + "</table>".Length;

string table = file.Substring(tableStart, tableEnd - tableStart) + Environment.NewLine;
HtmlAgilityPack.HtmlDocument hd = new HtmlDocument();
hd.LoadHtml(table); // you can load a fragment, in this case just a <table></table>

HtmlNode tableNode = hd.DocumentNode.ChildNodes[0];
foreach (HtmlNode rowOrText in tableNode.ChildNodes)
{
if (rowOrText.NodeType == HtmlNodeType.Element)
{
if (rowOrText.Name == "tr")
{
if (rowOrText.Attributes["class"] == null) // only 'header' rows have a class in my example
{
String Place = rowOrText.ChildNodes[0].InnerText.Trim();
String Name = rowOrText.ChildNodes[3].InnerText.Trim();
String Time = rowOrText.ChildNodes[4].InnerText.Trim();

Console.WriteLine("INSERT INTO RaceRunner ([Name], [Time]) VALUES ('{1}', '{2}')", Name, Time);
}
}
}
}
}

p.s. in case you were wondering, the source Html was NOT valid Xml that could be loaded into XmlDocument or other built-in .NET class
p.p.s. I really must find a reliable code prettifier...

Thursday, 14 June 2007

Facebook takes off...

The 3 week old 'Facebook Platform' is getting some interesting write-ups, not only that but they've partnered with Microsoft (/Popfly) to give Yahoo Pipes a run for it's money.

Furthermore, all of a sudden everyone I know is on Facebook.com, so I'm uploading photos of
Cuba and Mexico there as well as on Flickr (maybe there's a mashup to 'share' them, but couldn't be bothered with that for now).

Where will social networking go now?

EDIT: As if in answer, SMH published OMG, mum's joined Facebook! today...

EDIT2: (the other?) Paul Allen makes a big call: Prediction: Facebook will be the largest social network in the world. There's additional coverage in SMH 19-Jul-07, but the article isn't online...

Friday, 8 June 2007

ASP.NET Ajax vs Silverlight

Not quite 'Alien vs Predator', but an interesting experiment nevertheless.

I stumbled across this post using the ASP.NET Ajax AnimationExtender to move points around and immediately recognised the similarities to the Silverlight 'race simulator' demos I've been playing with.

It seemed a natural progression to try animating same North Head (Sydney) race runner data using ASP.NET AJAX to animate the runner markers. A quick massage of the Silverlight XAML (using Excel!) and I had a couple of JSON arrays ready to go.

The result, as you can see, is not quite as smooth as Silverlight - and I suspect that Ajax would have even more trouble than Silverlight with 400 elements to animate!

You can View Source of the AJAX page - it's all there.

Saturday, 2 June 2007

Silverlight docs (link drop)

Silverlight Learning Guide is a very complete list of links about Silverlight (1.0 and 1.1), including this one which helps explain the connection between Ruby/Python and C#/VB.NET (dynamic vs 'managed'?) langauges : Clearing the air about Silverlight and the DLR.

OT1: Awesome video explaining Seadragon and Photosynth technologies from MS research. Seadragon seems like a natural progression from a viewer like Flickrleech.
Ultimately the 'player' for both should/would be Silverlight (you'd think...) The Photosynth 'Notre Dame' poster example is cool (WOT: parts of the Photosynth site are Flash9 :)

OT2: Apple will want to release a non-iPhone multitouch iPod before Microsoft launches a milan/surface based Zune