<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-785523881057002641</id><updated>2012-02-16T09:58:41.361-08:00</updated><category term='Mobile'/><category term='WP7'/><category term='Windows Phone 7'/><category term='SharpMap'/><category term='GDAL'/><category term='Mastermap'/><category term='SpatiaLite'/><category term='WPF'/><category term='Ordnance Survey'/><title type='text'>EPSG:27700</title><subtitle type='html'>A blog about Open source GIS, SharpMap, Ordnance Survey and WPF</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-7886463207611179891</id><published>2011-04-22T12:55:00.000-07:00</published><updated>2011-04-22T13:21:26.011-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='WP7'/><title type='text'>In-Traction</title><content type='html'>My head has been hurting of late. As well as continuing to plug away at WPF, doing fun stuff like creating optimised vector graphics editors and custom controls, I am having to develop in XNA and Silverlight for Windows Phone 7, Objective-C and Cocoa for iPhone and somehow find room to at least keep abreast of Android and Java. Ouch!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It strikes me there are just too many devices, platforms and API's out there. Luckily I have some great people working with me and I can at least leave HTML5 and Android alone...for now.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In other news, &lt;a href="http://www.boneheadsoftware.com/2011/02/dicebox-rpg-dicebox-rpg-brings-gorgeous.html"&gt;DiceBox RPG&lt;/a&gt; has been doing really well. Its just a shame we can't make it's counterpart (&lt;a href="http://www.boneheadsoftware.com/2010/12/dicebox.html"&gt;DiceBox&lt;/a&gt;) free on the app store. If Microsoft would only get its act in gear and let its developers in the UK ad support their apps... Oh well, sure we wont have to wait too much longer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyhow. I now find myself well and truly in the mobile arena and I'm not sure how much longer this blog has left in it. I guess you never know, I may well end up doing some GIS stuff again at some point but, outside of mobile, that is looking increasingly unlikely.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Having said that, a new and interesting blogging effort is underway. If you are at all interested in smartphones, tablets and the future of computing then why not pop in on the new site at &lt;a href="http://www.in-traction.com/"&gt;www.in-traction.com&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;See you there.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-7886463207611179891?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/7886463207611179891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2011/04/in-traction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/7886463207611179891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/7886463207611179891'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2011/04/in-traction.html' title='In-Traction'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-934288713600274627</id><published>2011-01-22T05:54:00.000-08:00</published><updated>2011-01-22T06:30:19.356-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><title type='text'>An Expression Blend TabControl Style</title><content type='html'>&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap; "  &gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; white-space: normal; "&gt;&lt;span id="internal-source-marker_0.42019161535426974" style="color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;After spending some time trawling the web and failing to find the style I was after, I decided to sit down and put one together myself.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; white-space: normal; "&gt;&lt;span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;A couple of hours later, and with a bit of help from &lt;/span&gt;&lt;a href="http://snoopwpf.codeplex.com/"&gt;&lt;span style="color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "&gt;Snoop&lt;/span&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;, this is what I came up with; It’s a style for a tab control and, in-particular, a tab item, that goes some way to looking and feeling like the one used by Expression Blend.&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; "&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; "&gt;&lt;span style="color: rgb(0, 0, 0); font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; background-color: transparent; "&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: 15px; white-space: pre-wrap;"&gt;&lt;img src="http://3.bp.blogspot.com/_T06LOmirxsQ/TTrmCfMxukI/AAAAAAAAAv4/njhyrusz_PI/s400/blendtabcontrol.png" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 284px; height: 400px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5565013219978885698" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; font-size: 11pt; background-color: transparent;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "  &gt;The tabs are prevented from rearranging themselves into multiple lines by swapping out the TabPanel with a StackPanel. &lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; "&gt;&lt;span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; "&gt;&lt;span class="Apple-style-span"  &gt;&lt;span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;To more closely resemble the style adopted by Blend the TabPanel could instead be replaced with the SqueezeTabPanel, which can be found on &lt;/span&gt;&lt;a href="http://www.codeproject.com/KB/WPF/WpfSqueezeTabPanel.aspx"&gt;&lt;span style="color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "&gt;CodeProject&lt;/span&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;. For the time being, this has been left as an exercise for the reader ;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; "&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; "&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;b&gt;XAML:&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; "&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;pre style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:400px;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; &amp;lt;Style TargetType="{x:Type TabControl}"&amp;gt;&lt;br /&gt;&amp;lt;Setter Property="OverridesDefaultStyle" Value="True" /&amp;gt;&lt;br /&gt;&amp;lt;Setter Property="SnapsToDevicePixels" Value="True" /&amp;gt;&lt;br /&gt;&amp;lt;Setter Property="Template"&amp;gt;&lt;br /&gt; &amp;lt;Setter.Value&amp;gt;&lt;br /&gt;   &amp;lt;ControlTemplate TargetType="{x:Type TabControl}"&amp;gt;&lt;br /&gt;     &amp;lt;Grid KeyboardNavigation.TabNavigation="Local"&amp;gt;&lt;br /&gt;       &amp;lt;Grid.RowDefinitions&amp;gt;&lt;br /&gt;         &amp;lt;RowDefinition Height="Auto"/&amp;gt;&lt;br /&gt;         &amp;lt;RowDefinition Height="*"/&amp;gt;&lt;br /&gt;       &amp;lt;/Grid.RowDefinitions&amp;gt;&lt;br /&gt;       &amp;lt;StackPanel&lt;br /&gt;         Orientation="Horizontal"&lt;br /&gt;         Name="HeaderPanel"&lt;br /&gt;         Grid.Row="0"&lt;br /&gt;         Panel.ZIndex="1"&lt;br /&gt;         Margin="0,0,4,-1"&lt;br /&gt;         IsItemsHost="True"&lt;br /&gt;         KeyboardNavigation.TabIndex="1"&lt;br /&gt;         Background="Transparent" /&amp;gt;&lt;br /&gt;       &amp;lt;Border&lt;br /&gt;         Name="Border"&lt;br /&gt;         Grid.Row="1"&lt;br /&gt;         Background="LightGray"          &lt;br /&gt;         CornerRadius="2"&lt;br /&gt;         KeyboardNavigation.TabNavigation="Local"&lt;br /&gt;         KeyboardNavigation.DirectionalNavigation="Contained"&lt;br /&gt;         KeyboardNavigation.TabIndex="2" &amp;gt;&lt;br /&gt;         &amp;lt;ContentPresenter&lt;br /&gt;           Name="PART_SelectedContentHost"&lt;br /&gt;           Margin="4"&lt;br /&gt;           ContentSource="SelectedContent" /&amp;gt;&lt;br /&gt;       &amp;lt;/Border&amp;gt;&lt;br /&gt;     &amp;lt;/Grid&amp;gt;&lt;br /&gt;     &amp;lt;ControlTemplate.Triggers&amp;gt;&lt;br /&gt;       &amp;lt;Trigger Property="IsEnabled" Value="False"&amp;gt;&lt;br /&gt;         &amp;lt;Setter Property="Foreground" Value="#888888" /&amp;gt;&lt;br /&gt;         &amp;lt;Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" /&amp;gt;&lt;br /&gt;       &amp;lt;/Trigger&amp;gt;&lt;br /&gt;     &amp;lt;/ControlTemplate.Triggers&amp;gt;&lt;br /&gt;   &amp;lt;/ControlTemplate&amp;gt;&lt;br /&gt; &amp;lt;/Setter.Value&amp;gt;&lt;br /&gt;&amp;lt;/Setter&amp;gt;&lt;br /&gt;&amp;lt;/Style&amp;gt;&lt;br /&gt;&amp;lt;Style TargetType="{x:Type Button}"&amp;gt;&lt;br /&gt;&amp;lt;Setter Property="SnapsToDevicePixels" Value="true"/&amp;gt;&lt;br /&gt;&amp;lt;Setter Property="OverridesDefaultStyle" Value="true"/&amp;gt;&lt;br /&gt;&amp;lt;Setter Property="Template"&amp;gt;&lt;br /&gt; &amp;lt;Setter.Value&amp;gt;&lt;br /&gt;   &amp;lt;ControlTemplate TargetType="{x:Type Button}"&amp;gt;&lt;br /&gt;     &amp;lt;Grid&amp;gt;&lt;br /&gt;       &amp;lt;Path&lt;br /&gt;         x:Name="Cross"&lt;br /&gt;         Data="M0,0L6,6 M6,0L0,6z"&lt;br /&gt;         Stroke="LightGray"           &lt;br /&gt;         StrokeThickness="1.7"/&amp;gt;&lt;br /&gt;     &amp;lt;/Grid&amp;gt;&lt;br /&gt;     &amp;lt;ControlTemplate.Triggers&amp;gt;&lt;br /&gt;       &amp;lt;Trigger Property="IsMouseOver" Value="true"&amp;gt;&lt;br /&gt;         &amp;lt;Setter TargetName="Cross" Property="Stroke" Value="White"/&amp;gt;&lt;br /&gt;       &amp;lt;/Trigger&amp;gt;&lt;br /&gt;       &amp;lt;Trigger Property="IsPressed" Value="true"&amp;gt;&lt;br /&gt;         &amp;lt;Setter TargetName="Cross" Property="Stroke" Value="LightGray"/&amp;gt;&lt;br /&gt;       &amp;lt;/Trigger&amp;gt;&lt;br /&gt;       &amp;lt;Trigger Property="IsEnabled" Value="false"&amp;gt;&lt;br /&gt;         &amp;lt;Setter Property="Foreground" Value="#888888"/&amp;gt;&lt;br /&gt;       &amp;lt;/Trigger&amp;gt;&lt;br /&gt;     &amp;lt;/ControlTemplate.Triggers&amp;gt;&lt;br /&gt;   &amp;lt;/ControlTemplate&amp;gt;&lt;br /&gt; &amp;lt;/Setter.Value&amp;gt;&lt;br /&gt;&amp;lt;/Setter&amp;gt;&lt;br /&gt;&amp;lt;/Style&amp;gt;&lt;br /&gt;&amp;lt;Style TargetType="{x:Type TabItem}"&amp;gt;&lt;br /&gt;&amp;lt;Setter Property="Template"&amp;gt;&lt;br /&gt; &amp;lt;Setter.Value&amp;gt;&lt;br /&gt;   &amp;lt;ControlTemplate TargetType="{x:Type TabItem}"&amp;gt;&lt;br /&gt;     &amp;lt;Grid Margin="0,0,-12,0"&amp;gt;&lt;br /&gt;       &amp;lt;Grid.ColumnDefinitions&amp;gt;&lt;br /&gt;         &amp;lt;ColumnDefinition Width="Auto"/&amp;gt;&lt;br /&gt;         &amp;lt;ColumnDefinition Width="Auto"/&amp;gt;&lt;br /&gt;         &amp;lt;ColumnDefinition Width="24"/&amp;gt;&lt;br /&gt;       &amp;lt;/Grid.ColumnDefinitions&amp;gt;&lt;br /&gt;       &amp;lt;Border&lt;br /&gt;         x:Name="Border"&lt;br /&gt;         Grid.Column="0"&lt;br /&gt;         Grid.ColumnSpan="2"&lt;br /&gt;         CornerRadius="3,0,0,0"    &lt;br /&gt;         Background="#FF333333" /&amp;gt;&lt;br /&gt;       &amp;lt;Path&lt;br /&gt;         x:Name="RoundedCorner"&lt;br /&gt;         Grid.Column="2"&lt;br /&gt;         Stretch="Fill"&lt;br /&gt;         Data="M6.5,2.6C4.767,0.973 2.509,0 0,0 0,0 0,19 0,19L23,19z"&lt;br /&gt;         Fill="#FF333333" /&amp;gt;&lt;br /&gt;       &amp;lt;Button&lt;br /&gt;         x:Name="CloseButton"&lt;br /&gt;         Grid.Column="1"&lt;br /&gt;         Visibility="Collapsed"&lt;br /&gt;         Margin="0,0,0,0"&lt;br /&gt;         Width="6"&lt;br /&gt;         Height="6"/&amp;gt;&lt;br /&gt;       &amp;lt;ContentPresenter               &lt;br /&gt;         x:Name="ContentSite"&lt;br /&gt;         TextElement.Foreground="White"&lt;br /&gt;         VerticalAlignment="Center"&lt;br /&gt;         HorizontalAlignment="Center"&lt;br /&gt;         ContentSource="Header"&lt;br /&gt;         Margin="12,2,12,2"&lt;br /&gt;         RecognizesAccessKey="True"/&amp;gt;&lt;br /&gt;     &amp;lt;/Grid&amp;gt;&lt;br /&gt;     &amp;lt;ControlTemplate.Triggers&amp;gt;&lt;br /&gt;       &amp;lt;Trigger Property="IsSelected" Value="True"&amp;gt;&lt;br /&gt;         &amp;lt;Setter Property="Panel.ZIndex" Value="100" /&amp;gt;&lt;br /&gt;         &amp;lt;Setter TargetName="Border" Property="Background" Value="Gray" /&amp;gt;&lt;br /&gt;         &amp;lt;Setter TargetName="RoundedCorner" Property="Fill" Value="Gray" /&amp;gt;&lt;br /&gt;         &amp;lt;Setter TargetName="CloseButton" Property="Visibility" Value="Visible" /&amp;gt;&lt;br /&gt;       &amp;lt;/Trigger&amp;gt;&lt;br /&gt;       &amp;lt;Trigger Property="IsEnabled" Value="False"&amp;gt;&lt;br /&gt;         &amp;lt;Setter TargetName="Border" Property="Background" Value="#EEEEEE" /&amp;gt;&lt;br /&gt;         &amp;lt;Setter TargetName="RoundedCorner" Property="Fill" Value="#EEEEEE" /&amp;gt;&lt;br /&gt;         &amp;lt;Setter Property="Foreground" Value="#888888" /&amp;gt;&lt;br /&gt;       &amp;lt;/Trigger&amp;gt;&lt;br /&gt;     &amp;lt;/ControlTemplate.Triggers&amp;gt;&lt;br /&gt;   &amp;lt;/ControlTemplate&amp;gt;&lt;br /&gt; &amp;lt;/Setter.Value&amp;gt;&lt;br /&gt;&amp;lt;/Setter&amp;gt;&lt;br /&gt;&amp;lt;/Style&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; "&gt;&lt;span style="background-color: transparent; vertical-align: baseline; text-decoration: none; white-space: pre-wrap; font-weight: normal; font-style: normal; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-934288713600274627?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/934288713600274627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2011/01/expression-blend-tabcontrol-style.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/934288713600274627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/934288713600274627'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2011/01/expression-blend-tabcontrol-style.html' title='An Expression Blend TabControl Style'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_T06LOmirxsQ/TTrmCfMxukI/AAAAAAAAAv4/njhyrusz_PI/s72-c/blendtabcontrol.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-1025924037380426869</id><published>2010-12-31T05:52:00.000-08:00</published><updated>2010-12-31T06:20:18.584-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Phone 7'/><title type='text'>Bonehead</title><content type='html'>&lt;div style="text-align: left;"&gt;DiceBox seems to be doing pretty well, at least according to the stats coming in from &lt;a href="http://create.msdn.com/en-US/"&gt;AppHub&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, as well as the DiceBox 1.1 update, work is underway for an RPG version that is already looking pretty awesome. Unfortunately, its still to early to release any details but a video preview should be available soon. To provide a home on the web for this exciting new endeavour, may I present to you...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://2.bp.blogspot.com/_T06LOmirxsQ/TR3imJ72nHI/AAAAAAAAAvg/4f72AnCUJyU/s400/banner_logo.png" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 225px; height: 177px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5556846660374928498" /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://www.boneheadsoftware.com/"&gt;www.boneheadsoftware.com&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The site should be slowly evolving over the following weeks and months, so be sure to keep an eye out.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-1025924037380426869?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/1025924037380426869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2010/12/bonehead.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/1025924037380426869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/1025924037380426869'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2010/12/bonehead.html' title='Bonehead'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_T06LOmirxsQ/TR3imJ72nHI/AAAAAAAAAvg/4f72AnCUJyU/s72-c/banner_logo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-6633734884050646181</id><published>2010-12-23T06:52:00.001-08:00</published><updated>2010-12-23T07:25:30.454-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Phone 7'/><title type='text'>And now for something completely different: DiceBox</title><content type='html'>&lt;div&gt;This is bit of a shameless plug really...&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Recently a couple of friends and myself have been playing around with the Windows Phone 7 developer tools.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first fruits of this is DiceBox, a simple dice app, now available on the windows marketplace. If you don't have the Zune software installed you can see the blurb &lt;a href="http://www.marketplacebrowser.com/256671/dicebox"&gt;here&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_T06LOmirxsQ/TRNj6GE9YaI/AAAAAAAAAu4/p0lGRzgszCA/s1600/phones.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 379px;" src="http://3.bp.blogspot.com/_T06LOmirxsQ/TRNj6GE9YaI/AAAAAAAAAu4/p0lGRzgszCA/s400/phones.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5553892615192928674" /&gt;&lt;/a&gt;Currently there are 6 kinds of dice texture, realistic physics and sound, a total score display and a "shake to roll" feature. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We are planning a series of updates which will introduce a number of additional features, such as backgrounds, shadows and a dice tray for playing poker dice/yahtzee etc&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;If you have a Windows Phone 7, why not give it a try :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-6633734884050646181?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/6633734884050646181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2010/12/and-now-for-something-completely.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/6633734884050646181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/6633734884050646181'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2010/12/and-now-for-something-completely.html' title='And now for something completely different: DiceBox'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_T06LOmirxsQ/TRNj6GE9YaI/AAAAAAAAAu4/p0lGRzgszCA/s72-c/phones.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-8564042846408783960</id><published>2010-02-08T11:15:00.000-08:00</published><updated>2010-02-08T11:29:55.944-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SpatiaLite'/><category scheme='http://www.blogger.com/atom/ns#' term='SharpMap'/><title type='text'>SpatiaLite data provider now in SharpMap trunk</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;It was nice to see that sussing out how to use those spatial indexes in SpatiaLite was not in vein. A &lt;/span&gt;&lt;a style="font-family: trebuchet ms;" href="http://geobabble.wordpress.com/2010/02/01/spatialite-provider-now-in-sharpmap-repository/" id="uucx" title="recent post"&gt;post&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt; on bill dollins site prompted me to take a look at the recent changes to the SharpMap trunk, which now includes bills excellent SpatiaLite data provider complete with &lt;/span&gt;&lt;a style="font-family: trebuchet ms;" href="http://epsg27700.blogspot.com/2009/08/adventures-with-spatialite.html" id="pqx." title="spatial index support"&gt;spatial index support&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt;.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-8564042846408783960?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/8564042846408783960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2010/02/spatialite-data-provider-now-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/8564042846408783960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/8564042846408783960'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2010/02/spatialite-data-provider-now-in.html' title='SpatiaLite data provider now in SharpMap trunk'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-6291389236934706042</id><published>2010-01-21T03:13:00.000-08:00</published><updated>2010-01-22T06:54:16.143-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><title type='text'>WPF Header/Multi-Column ListBox Control</title><content type='html'>&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_T06LOmirxsQ/S1g3XX81ZDI/AAAAAAAAAtQ/mHre_kJgXjI/s1600-h/MultiColumnList.png"&gt;&lt;/a&gt;&lt;span class="Apple-style-span"   style="  ;font-family:Verdana;font-size:13px;"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;span class="Apple-style-span"   style="color: rgb(0, 0, 238); -webkit-text-decorations-in-effect: underline; font-family:Georgia, serif;font-size:16px;"&gt;&lt;img src="http://1.bp.blogspot.com/_T06LOmirxsQ/S1g3XX81ZDI/AAAAAAAAAtQ/mHre_kJgXjI/s400/MultiColumnList.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5429150225500824626" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 180px; " /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="color: rgb(0, 0, 238); -webkit-text-decorations-in-effect: underline; font-family:Georgia, serif;font-size:16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;The WPF ListBox control can be used to create a wide variety of user interface elements thanks to templates and styling. However, recently it left me out in the cold...for a while at least.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;We had an existing control, based on a heavily styled ListBox, that contained a bunch or items that could be considered as rows in a table. It all worked fine until some bright spark had the idea of adding column headers.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;Now, at this point you may be thinking that ListBox is not the ideal candidate here. ListView, with its GridView layout, is the control to use if you want to layout column based data with column headers. Right?&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;Well, not always. GridView is fine if you want to apply styles to individual cells or columns. The problem with our particular style was that each conceptual row could be expanded in various ways, making the GridView unsuitable. There were two options as far as i could see: &lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;ol style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;li style="margin-top: 0px; margin-bottom: 0px; "&gt;Write a custom View (based on ViewBase) for ListView&lt;/li&gt;&lt;li style="margin-top: 0px; margin-bottom: 0px; "&gt;Add a header to the ListBox control&lt;/li&gt;&lt;/ol&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;We went with option two. The pain began. &lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;The basic problem is that the header needs to be part of the ListBox so that when the ListBox is scrolled horizontally, the header scrolls too. However, when you scroll it Vertically you want the header to remain visible and not scroll with the rest of the list.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;I started by looking at the style of the ListView control which does something similar to what i wanted to achieve. This gave me a big clue. The ListView uses a custom ScrollViewer that has a child scrollviewer nested inside. This child ScrollViewer contains the header; The scrollbars on the child ScrollViewer are always hidden. Magic.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;I also had a look at this very helpful article: &lt;span style=" ;font-family:Verdana, Arial, Helvetica, sans-serif;"&gt;&lt;a id="ks8o" href="http://blogs.msdn.com/henryh/archive/2005/06/23/431846.aspx" title="Building a Multi-Column ListBox in Avalon" style="color: rgb(85, 26, 139); "&gt;Building a Multi-Column ListBox in Avalon&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;This came close to what i wanted to achieve, but there were a number of problems:&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;ul style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;li style="margin-top: 0px; margin-bottom: 0px; "&gt;It was written before the first release of WPF and would no longer compile&lt;/li&gt;&lt;li style="margin-top: 0px; margin-bottom: 0px; "&gt;Having updated it so that it &lt;i&gt;did&lt;/i&gt; compile, there were several problems with the scrolling resulting in unsatisfactory placement of the vertical scrollbar (not consistent with ListView) and errors causing the content to slide past the header at the extreme right.&lt;/li&gt;&lt;/ul&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;Nevertheless, it gave me a lot of ideas, In-fact the example is based on a lot of the same XAML.&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;Next, I need to work out how to make the header scroll horizontally when the list box is scrolled horizontally. Unfortunately there is no easy way to do this. Ideally you would bind the HorizontalOffset of the header ScrollViewer to that of the main one. However, this is not possible thanks to its read only nature. To overcome this I used an attached behaviour to achieve the same goal by making use of the ScrollToHorizontalOffset method.&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;The resulting XAML for the ScrollViewer looks like this:&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;pre style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; &amp;lt;Style x:Key="HeaderedScrollViewer" TargetType="{x:Type ScrollViewer}"&amp;gt; &lt;br /&gt;  &amp;lt;Setter Property="Template"&amp;gt; &lt;br /&gt;    &amp;lt;Setter.Value&amp;gt; &lt;br /&gt;      &amp;lt;ControlTemplate TargetType="{x:Type ScrollViewer}"&amp;gt; &lt;br /&gt;        &amp;lt;Grid Background="{TemplateBinding Background}"&amp;gt; &lt;br /&gt;          &amp;lt;Grid.ColumnDefinitions&amp;gt; &lt;br /&gt;            &amp;lt;ColumnDefinition Width="*"/&amp;gt; &lt;br /&gt;            &amp;lt;ColumnDefinition Width="Auto"/&amp;gt; &lt;br /&gt;          &amp;lt;/Grid.ColumnDefinitions&amp;gt; &lt;br /&gt;          &amp;lt;Grid.RowDefinitions&amp;gt; &lt;br /&gt;            &amp;lt;RowDefinition Height="*"/&amp;gt; &lt;br /&gt;            &amp;lt;RowDefinition Height="Auto"/&amp;gt; &lt;br /&gt;          &amp;lt;/Grid.RowDefinitions&amp;gt; &lt;br /&gt;          &amp;lt;DockPanel Margin="{TemplateBinding Padding}"&amp;gt; &lt;br /&gt;            &amp;lt;ScrollViewer DockPanel.Dock="Top" &lt;br /&gt;                 local:SetHorizontalOffset.Offset="{Binding  &lt;br /&gt;                    RelativeSource={RelativeSource TemplatedParent},  &lt;br /&gt;                    Path=HorizontalOffset}"  &lt;br /&gt;                 HorizontalScrollBarVisibility="Hidden" &lt;br /&gt;                 VerticalScrollBarVisibility="Hidden" &lt;br /&gt;                 Focusable="false" &lt;br /&gt;                 Content="{StaticResource ListHeader}"&amp;gt;                     &lt;br /&gt;            &amp;lt;/ScrollViewer&amp;gt; &lt;br /&gt;            &amp;lt;ScrollContentPresenter Name="PART_ScrollContentPresenter" &lt;br /&gt;              KeyboardNavigation.DirectionalNavigation="Local"/&amp;gt; &lt;br /&gt;          &amp;lt;/DockPanel&amp;gt; &lt;br /&gt;          &amp;lt;ScrollBar Name="PART_HorizontalScrollBar" &lt;br /&gt;            Orientation="Horizontal" &lt;br /&gt;            Grid.Row="1" &lt;br /&gt;            Maximum="{TemplateBinding ScrollableWidth}" &lt;br /&gt;            ViewportSize="{TemplateBinding ViewportWidth}" &lt;br /&gt;            Value="{TemplateBinding HorizontalOffset}" &lt;br /&gt;            Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/&amp;gt; &lt;br /&gt;          &amp;lt;ScrollBar Name="PART_VerticalScrollBar" &lt;br /&gt;            Grid.Column="1" &lt;br /&gt;            Maximum="{TemplateBinding ScrollableHeight}" &lt;br /&gt;            ViewportSize="{TemplateBinding ViewportHeight}" &lt;br /&gt;            Value="{TemplateBinding VerticalOffset}" &lt;br /&gt;            Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/&amp;gt; &lt;br /&gt;        &amp;lt;/Grid&amp;gt; &lt;br /&gt;      &amp;lt;/ControlTemplate&amp;gt; &lt;br /&gt;    &amp;lt;/Setter.Value&amp;gt; &lt;br /&gt;  &amp;lt;/Setter&amp;gt; &lt;br /&gt;&amp;lt;/Style&amp;gt; &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;And it is applied to the ListBox with this style:&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;pre style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; &amp;lt;Style x:Key="{x:Type ListBox}" TargetType="{x:Type ListBox}"&amp;gt; &lt;br /&gt;  &amp;lt;Setter Property="Template"&amp;gt; &lt;br /&gt;    &amp;lt;Setter.Value&amp;gt; &lt;br /&gt;      &amp;lt;ControlTemplate&amp;gt; &lt;br /&gt;        &amp;lt;ScrollViewer Style="{StaticResource HeaderedScrollViewer}"  &lt;br /&gt;               Grid.IsSharedSizeScope="True"&amp;gt; &lt;br /&gt;          &amp;lt;StackPanel IsItemsHost="true"/&amp;gt; &lt;br /&gt;        &amp;lt;/ScrollViewer&amp;gt; &lt;br /&gt;      &amp;lt;/ControlTemplate&amp;gt; &lt;br /&gt;    &amp;lt;/Setter.Value&amp;gt; &lt;br /&gt;  &amp;lt;/Setter&amp;gt; &lt;br /&gt;&amp;lt;/Style&amp;gt; &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;You can download the full source here: &lt;a id="yjim" href="https://docs.google.com/leaf?id=0B0Bx7wCPtOfZM2FmNzQ0NjgtZGZkZC00YmE3LTk3NGItZjg1YTA4ZjUxNTA2&amp;amp;hl=en" title="MultiColumnList.zip" style="color: rgb(85, 26, 139); "&gt;MultiColumnList.zip&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-6291389236934706042?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/6291389236934706042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2010/01/wpf-headeredmulti-column-listbox_21.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/6291389236934706042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/6291389236934706042'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2010/01/wpf-headeredmulti-column-listbox_21.html' title='WPF Header/Multi-Column ListBox Control'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_T06LOmirxsQ/S1g3XX81ZDI/AAAAAAAAAtQ/mHre_kJgXjI/s72-c/MultiColumnList.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-5204410381433085046</id><published>2009-11-06T10:46:00.001-08:00</published><updated>2009-11-06T10:56:54.333-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='SharpMap'/><title type='text'>Support for Labels and GDAL Rasters in SharpMap.Wpf</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span"  style=" ;font-size:13px;"&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Having finally got around to doing some more work on &lt;a href="http://epsg27700.blogspot.com/2009/09/sharpmapwpf.html"&gt;SharpMap.Wpf&lt;/a&gt; I have at last managed to implement generic versions of both the LabelLayer and GdalRasterLayer. As with VectorLayer, a large body of the code is the same as the GDI+ specific versions however they both derive from the new SharpMap.Wpf.Layers.Layer base class which uses an IRenderContext in its overridable Render method instead of a GDI+ graphics object.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="  ;font-family:Verdana;font-size:13px;"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;There are still a few minor issues to iron out. I haven't gotten around to supporting label rotation yet (although this should not be very difficult) and GdalRasterLayer does not yet do anything with the TransparentColor property. Still, nearly there! Just need a better demo project now. &lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px; "&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Some screenshots below:&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_T06LOmirxsQ/SvRvptD57VI/AAAAAAAAAp4/oR6wx3DShF8/s1600-h/labellayer.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 310px; height: 320px;" src="http://2.bp.blogspot.com/_T06LOmirxsQ/SvRvptD57VI/AAAAAAAAAp4/oR6wx3DShF8/s320/labellayer.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5401064615385361746" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_T06LOmirxsQ/SvRvqLbKM0I/AAAAAAAAAqA/e-bPZvgCwXU/s1600-h/gdallayer.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 309px; height: 320px;" src="http://1.bp.blogspot.com/_T06LOmirxsQ/SvRvqLbKM0I/AAAAAAAAAqA/e-bPZvgCwXU/s320/gdallayer.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5401064623535960898" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-5204410381433085046?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/5204410381433085046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2009/11/support-for-labels-and-gdal-rasters-in.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/5204410381433085046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/5204410381433085046'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2009/11/support-for-labels-and-gdal-rasters-in.html' title='Support for Labels and GDAL Rasters in SharpMap.Wpf'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_T06LOmirxsQ/SvRvptD57VI/AAAAAAAAAp4/oR6wx3DShF8/s72-c/labellayer.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-5959404712522670509</id><published>2009-09-22T11:40:00.000-07:00</published><updated>2009-09-22T12:08:19.092-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='SharpMap'/><title type='text'>SharpMap.Wpf</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;I've been wanting to write a WPF renderer for SharpMap ever since I started using version 0.9 about a year ago. Sure, SharpMap v2 has a few early WPF implementations, but its been in beta for quite some time now.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;Our existing WPF/SharpMap solution involves using the plain old GDI+ stuff and blatting the entire map into a WPF image using Interop Bitmap. It does the job quite well, so why bother doing anything more?&lt;/span&gt;  &lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;Well, mainly cos I wanted to! but also because I like the idea of having true WPF styles and themes. The improved brushes in WPF mean that there is scope for some really pretty maps. Also, the idea of using several WPF images to host transparent layers and animated overlays is quite appealing.&lt;/span&gt;  &lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;So far, I've got a WPF map renderer up and running for vector layers only. I'm currently working on WPFing the LabelLayer and the GdalRasterLayer. Maybe, when its getting to a semi-finished state i'll try and host it on CodePlex. I guess it all depends if anyone is still interested in 0.9 by then!?&lt;/span&gt;  &lt;span style="font-family:trebuchet ms;"&gt;A few interesting points on the current state of play:&lt;/span&gt;  &lt;ul style="font-family: trebuchet ms;"&gt;&lt;li&gt;At first I started to write a dedicated WpfVectorLayer and a corresponding WpfVectorRenderer, but I just couldn't live with the code smell. There was too much redundant duplication. In the end, I refactored the VectorLayer into a new generic class with a templatable style and introduced a new Render method that used an IRenderContext instead of a Graphics object. I now have two concrete implementations of IRenderContext, one for GDI+ and one for WPF. To this end, you can declare concrete instances of the generic VectorLayer&lt;tstyle&gt; that either use the standard VectorStyle or the new WpfVectorStyle, depending upon the type of renderer you wish to use.&lt;/tstyle&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Due to the departure from the original design, all the new stuff is in a separate namespace. The 'legacy' VectorLayer has been left unchanged (yeah, so I've still ended up duplicating code, but at least moving forward you need only implement an IRenderContext)&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The WPF renderer uses the stream geometry classes to draw straight to a WPF DrawingContext. In addition to this, it provides methods to render the entire map, or just a single layer, to a Visual or a BitmapSource.&lt;/li&gt;&lt;/ul&gt; &lt;span style="font-family:trebuchet ms;"&gt;Here is my SharpMap.Wpf 'hello world':&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_T06LOmirxsQ/Srkah3CP6mI/AAAAAAAAAoo/j1MSV_3AXP4/s1600-h/WpfMap.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 395px; height: 340px;" src="http://2.bp.blogspot.com/_T06LOmirxsQ/Srkah3CP6mI/AAAAAAAAAoo/j1MSV_3AXP4/s320/WpfMap.png" alt="" id="BLOGGER_PHOTO_ID_5384363998509525602" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-5959404712522670509?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/5959404712522670509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2009/09/sharpmapwpf.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/5959404712522670509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/5959404712522670509'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2009/09/sharpmapwpf.html' title='SharpMap.Wpf'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_T06LOmirxsQ/Srkah3CP6mI/AAAAAAAAAoo/j1MSV_3AXP4/s72-c/WpfMap.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-3446582687993057738</id><published>2009-09-09T12:05:00.000-07:00</published><updated>2009-09-09T12:23:20.209-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ordnance Survey'/><category scheme='http://www.blogger.com/atom/ns#' term='SharpMap'/><title type='text'>GdalRasterLayer and Ordnance Survey TIFF Files</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:trebuchet ms;"&gt;..or any other raster files that use a colour palette.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;So, having found out that you can use SharpMap's GdalRasterLayer to load and display &lt;/span&gt;&lt;a style="font-family: trebuchet ms;" title="virtual datatsets" href="http://epsg27700.blogspot.com/2009/09/raster-index-datasets-in-sharpmap.html" id="aztp"&gt;virtual datatsets&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt;, I quickly set about trying to get it working with the tiff files provided by Ordnance Survey.&lt;br /&gt;&lt;br /&gt;However, when I actually tried to view the data I was presented with a big black nothing.&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;Turns out there is...not a bug exactly, but more of an 'omission' in the GdalRasterLayer code. At the time of writing both the 0.9 release and the current trunk build of SharpMap contain a version of GdalRasterLayer that cannot handle images that use colour palettes. And yes, all the raster data from Ordnance Survey (or at least, all the tiff files) make use of them.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;I eventually came across a fix in &lt;/span&gt;&lt;a style="font-family: trebuchet ms;" title="this" href="http://sharpmap.codeplex.com/WorkItem/View.aspx?WorkItemId=8873" id="m5sj"&gt;this&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt; post. However, the patch was based on an old version of GdalRasterLayer and the code had moved on significantly. After a bit of head scratching I gave in and tried my hand at porting across the changes.&lt;br /&gt;&lt;br /&gt;Now, the code is not beautiful. It doesn't seem to be a perfect fit. Having said that, I did not want to change the original code too drastically and so it is what it is...and it even seems to work!&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;br /&gt;Anyone who is interested can pick up it up from &lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;a href="http://svn2.xp-dev.com/svn/kev79-epsg27700/GdalRasterLayer/GdalRasterLayer.cs"&gt;here&lt;/a&gt; or download it&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt; from the original post &lt;a href="http://sharpmap.codeplex.com/Project/Download/AttachmentDownload.ashx?ProjectName=SharpMap&amp;amp;WorkItemId=8873&amp;amp;FileAttachmentId=8961"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-3446582687993057738?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/3446582687993057738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2009/09/gdalrasterlayer-and-ordnance-survey.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/3446582687993057738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/3446582687993057738'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2009/09/gdalrasterlayer-and-ordnance-survey.html' title='GdalRasterLayer and Ordnance Survey TIFF Files'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-347805881783103674</id><published>2009-09-07T05:06:00.000-07:00</published><updated>2009-09-07T05:12:19.042-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GDAL'/><category scheme='http://www.blogger.com/atom/ns#' term='SharpMap'/><title type='text'>Raster index datasets in SharpMap</title><content type='html'>I&lt;span style="font-family:trebuchet ms;"&gt;n my previous post I eluded to the fact that it was possible to use SharpMap 'out of the box' to render raster index datasets (tiles). About a year ago I remember trying to get SharpMap to do just that and came to the conclusion that unless i wanted to use some kind of web based tile server, I would have to invest a lot of time creating a new type of layer, perhaps based loosely on the TiledWmsLayer, but specifically for loading large raster tile datasets from disk. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Turns out I didnt need to do any of that.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;GdalRasterLayer supports many different raster formats. One that I was unfamiliar with until recently was its own virtual dataset format. This is basically an xml file that, among other things, can pull together several raster files and treat them as a single dataset. You can build one of these very easily by doing something like: &lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;span style="font-family:courier new;"&gt;gdalbuildvrt rasterIndex.vrt *.tif&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family:trebuchet ms;"&gt;Now, because vrt files are just another format supported by gdal, you can load them straight in using the GdalRasterLayer like so: &lt;/span&gt;&lt;blockquote style="font-family: courier new;"&gt;GdalRasterLayer layer = new GdalRasterLayer("MyRasterIndex", "rasterIndex.vrt");&lt;/blockquote&gt;&lt;span style="font-family:trebuchet ms;"&gt;And because the GdalRasterLayer is pretty smart at what it does, it will only read the pixels that it needs, meaning it's pretty efficient in terms of its speed and memory usage.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-347805881783103674?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/347805881783103674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2009/09/raster-index-datasets-in-sharpmap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/347805881783103674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/347805881783103674'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2009/09/raster-index-datasets-in-sharpmap.html' title='Raster index datasets in SharpMap'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-1197373880877166231</id><published>2009-09-02T04:48:00.000-07:00</published><updated>2009-09-09T12:17:52.260-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ordnance Survey'/><category scheme='http://www.blogger.com/atom/ns#' term='GDAL'/><title type='text'>Processing Ordnance Survey Rasters with GDAL</title><content type='html'>&lt;span style="font-family:Trebuchet MS;"&gt;Ordnance survey produce raster maps of the UK at several resolutions. They are provided as a set of tiles, geographically chunking the whole of the UK according to the British national grid. As with most things Ordnance survey, they seem to go out of their way to make them as hard to use in a standard GIS application as possible.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;The set of raster tiles for the UK at 1:10k comes in at about 26GB. A whopping 10,000+ tiles. They do not come with any geo-referencing and are not made available in any format that includes this information (i.e Geotif). Instead, they are provided as tif, bmp or jpeg files with the option to download the geo-reference files (tfw etc) separately. To add insult to injury, it would seem that, in trying to save disk space, instead of a standard 3 band rgb tif file, what you actually get is a single band tif file with a colour palette. Its not so bad really, just another minor annoyance.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;As I have mentioned before, we use a &lt;/span&gt;&lt;a href="http://www.codeplex.com/SharpMap" id="pgso" style="font-family: Trebuchet MS;" title="SharpMap"&gt;SharpMap&lt;/a&gt;&lt;span style="font-family:Trebuchet MS;"&gt; based WPF control to render our data. This makes rendering OS tiles non-trivial for the following reasons:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol style="font-family: Trebuchet MS;"&gt;&lt;li&gt;     There is a bug in GdalRasterLayer which prevents it from rendering tif files that make use of colour palettes   &lt;/li&gt;&lt;li&gt;     There is no dedicated layer type for rendering a raster tile index/set unless you want to serve them up over a WMS   &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;Now, I was actually able to &lt;a href="http://epsg27700.blogspot.com/2009/09/gdalrasterlayer-and-ordnance-survey.html"&gt;fix the problem&lt;/a&gt; in (1) and because of this (and with a better understanding of GDAL) I was able to render a raster tile set using nothing but a single GdalRasterLayer. However, maybe that's something I'll come back to in another post. For now, I want to talk about our original solution, which was to convert the tiles to ECW's using GDAL.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;For 1:250k, 1:50k and 1:25k we found it was possible to create a single ECW for the whole of the UK. For 1:10k the huge number of tiles involved really put a strain on the memory. I don't know if it is achievable or not but one thing is for sure..it would take a very very long time (somewhere in the region of 1-2 weeks of solid processing). In the end, for the 1:10k stuff, we decided to create a single ECW for each &lt;/span&gt;&lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/gi/nationalgrid/nationalgrid.pdf" id="k..x" style="font-family: Trebuchet MS;" title="top level square"&gt;top level square&lt;/a&gt;&lt;span style="font-family:Trebuchet MS;"&gt; of the British national grid, giving us something like 50 ecw's in all. The time taken to process each of these regions varied between a few minutes and a few hours.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;So, here are the steps involved to convert a set ordnance survey rasters into a single ECW:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol style="font-family: Trebuchet MS;"&gt;&lt;li&gt;     Copy all the tiles at a particular resolution (say 1:250k) into their own directory. e.g C:\250k\   &lt;/li&gt;&lt;li&gt;     Download the &lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/products/georeferencing/aboutpopup.html" id="lj_t" title="geo-reference files"&gt;geo-reference files&lt;/a&gt; from ordnance survey and copy them into the same directory as (1)   &lt;/li&gt;&lt;li&gt;     Using the &lt;a href="http://fwtools.maptools.org/" id="ucz_" title="fwtools"&gt;fwtools&lt;/a&gt; shell, cd to the directory with the raster tiles and the geo-reference files in.   &lt;/li&gt;&lt;li&gt;     Build a virtual raster file(an xml file) of the entire set using:&lt;span style="font-family:Courier New;"&gt; &lt;blockquote&gt;gdalbuildvrt 250k.vrt *.tif   &lt;/blockquote&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;     Use gdal_translate on the virtual raster file to convert the entire set of tiles into a single ECW: &lt;blockquote&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;span style="font-family:Courier New;"&gt;gdal_translate -of ECW -co LARGE_OK=YES -expand rgb -a_srs EPSG:27700 250k.vrt 250k.ecw&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style="font-family: Trebuchet MS;"&gt; &lt;/b&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;font-family:Trebuchet MS;" &gt;Issues, workarounds and a handy bit of C#&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;Generally speaking, this worked well. The only real problem I faced was when dealing with the 10k national set. When trying to create a virtual raster of a top level grid square with a command like: &lt;span style="font-family:Courier New;"&gt;&lt;blockquote&gt;gdalbuildvrt SU.vrt SU*.tif&lt;/blockquote&gt;&lt;/span&gt;occasionally the command would fail. This would happen if the tiles in question had differing colour palettes or a differing number of bands.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;The solution was to introduce an intermediate stage whereby the source rasters were 'normalised' to 3 band rgb tif files. I achieved this by using the following command on each file:&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt; &lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:Courier New;"&gt;gdal_translate -co COMPRESS=DEFLATE -co TFW=YES -expand rgb HP60NE.tif Expanded\HP60NE.tif&lt;/span&gt;&lt;/blockquote&gt; &lt;span style="font-family:Trebuchet MS;"&gt;Then, when it came to making the final ECW the &lt;span style="font-family:Courier New;"&gt;-expand&lt;/span&gt; option had to be left out, due to the palette expansion having already happened in the previous stage. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt;I wrapped all of this up into a neat little C# program (mainly because I couldn't be bothered to work out the java script or batch file commands) that checked the integrity of the files, 'normalised' their palettes if necessary, built the vrt and finally, converted the raster tiles into a single ECW file, logging all the results into a separate file to record timings and errors.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;The resulting tiles2ecw utility can be downloaded from &lt;a href="http://svn2.xp-dev.com/svn/kev79-epsg27700/tiles2ecw/"&gt;here&lt;/a&gt;. You can either compile it into a console application or run it directly from the command line using the rather brillient &lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;a href="http://www.csscript.net/"&gt;cs-script&lt;/a&gt;&lt;/span&gt;.&lt;br /&gt;&lt;span style="font-family:Trebuchet MS;"&gt; &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-1197373880877166231?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/1197373880877166231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2009/09/processing-ordnance-survey-rasters-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/1197373880877166231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/1197373880877166231'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2009/09/processing-ordnance-survey-rasters-with.html' title='Processing Ordnance Survey Rasters with GDAL'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-493320205671811129</id><published>2009-08-28T06:56:00.001-07:00</published><updated>2009-09-09T12:28:38.813-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SpatiaLite'/><category scheme='http://www.blogger.com/atom/ns#' term='Mastermap'/><category scheme='http://www.blogger.com/atom/ns#' term='SharpMap'/><title type='text'>Adventures with SpatiaLite</title><content type='html'>&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;A while ago I came across &lt;a href="http://www.gaia-gis.it/spatialite/"&gt;SpatiaLite&lt;/a&gt;. Its particularly interesting to me as we (the company I work for) need to deploy vast amounts of mapping data on machines where it is not always possible to connect to a dedicated mapping server. For us, this means installing &lt;a href="http://postgis.refractions.net/"&gt;PostGIS &lt;/a&gt;onto every client and restoring 20+GB of spatial data onto each one.&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;I wanted to use SpatiaLite instead of PostGIS. That way, deploying the mapping data onto the client would become as simple as copying across a flat file. It sounded like the perfect tool for the job. However, as with all things, nothing is ever easy. Here are a couple of the problems I faced:&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;We deal mainly with &lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/products/osmastermap/layers/topography/"&gt;mastermap &lt;/a&gt;data and use a proprietary database loader to upload it to PostGIS. This loader does not support SpatiaLite so I had to figure out how I was going to get it into the SpatiaLite format.&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;We use the &lt;a href="http://www.codeplex.com/SharpMap"&gt;SharpMap&lt;/a&gt; library to render our mapping data, which has extensions to support PostGIS. I would have to find or write a custom data provider if I wanted to use SpatiaLite instead.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b style="font-family: trebuchet ms;"&gt;Converting Ordnance Survey Mastermap data to SpatiaLite&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;i style="font-family: trebuchet ms;"&gt;First the easy (but less than satisfactory) way...&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;As we already had our data in PostGIS, I was able to use the latest version of &lt;a href="http://fwtools.maptools.org/"&gt;fwtools&lt;/a&gt; to convert the existing database to SpatiaLite. This was surprisingly easy once i'd figured out all the arguments. It preserved our existing schema and was reasonably efficient. The command I used can be seen below:&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style=";font-family:trebuchet ms;font-size:85%;"  &gt;ogr2ogr -f SQLite -dsco "SPATIALITE=yes" london.sqlite PG:"host=localhost user=postgres dbname=london password=postgres" mastermap&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;I had three main issues with this approach. Firstly, the latest version of fwtools (2.4.2) is not linked against libspatialite, meaning I was unable to create the spatial index from the command line and had to use the spatialite tools to do this as another manual step. Secondly, and more importantly, I had no way to apply change only updates (COU's) to the SpatiaLite database. I would have to apply them to PostGIS and then re-convert the whole lot. Thirdly, its just plain painful. encoding/uploading the data to PostGIS can take a long time. Converting it to SpatiaLite as a secondary stage doubles the time involved. Wouldn't it be nice if you could go straight from the original mastermap GML to the SpatiaLite database and handle COU's as well...&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;i style="font-family: trebuchet ms;"&gt;A Better Approach...&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;I'd had my eye on an &lt;a href="http://www.edonica.com/MMImport/index.html"&gt;open source converter&lt;/a&gt; for a while. After several experiments I had managed to get it translating and uploading the mastermap GML to a PostGIS database according to our schema (the tool uses a schema recommended by Ordnance Survey but, sadly, very different to the one our proprietry tool uses). Due to the foresight of the author, all this involved in the end was tweaking the xsd and xslt files (Actually that's not quite true, i had to change the source a bit as well so that it created the PostGIS tables in a slightly different way..but that's by the by).&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;After playing around with the 'Ogr converter' option, I finally bit the bullet and decided to have a crack at extending the tool to output directly to SpatiaLite. A few hours later (and after much reading up) I had a working converter. It could handle bulk loads, COU's and spatial index creation. It was fast and, thanks to its use of xsd/xslt, very flexible. I must take my hat of to the author of this tool for making it so extensible. Great job. &lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;Now, just how was I going to plug this into our rendering engine? Read on...&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;&lt;span style="font-family:trebuchet ms;"&gt;Rendering SpatiaLite data using SharpMap&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;Bill dollins posted a &lt;a href="http://geobabble.wordpress.com/2009/04/11/spatialite-provider-code-for-sharpmap-09/"&gt;SpatiaLite data provider&lt;/a&gt; on his blog a while back. Just the job. However, when I came to put it all together I was left twiddling my thumbs. It was taking an absolute age to render. The problem was that SpatiaLite does not automatically use the spatial index. Instead, you have to build a special query to make use of it...and the data provider I'd nabbed from Bill's site didn't make any use of it. &lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;I ended up making a few changes to allow the data provider to be constructed with information about the spatial index table (yes, its implemented as a table, not a true index) and then modified the spatial query to make use of it. The main change was to the GetBoxClause method which can be seen below:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(204, 204, 204); padding: 0px; background: rgb(240, 240, 240) url(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif) repeat scroll 0% 0%; overflow: auto; font-family: arial; font-size: 12px; width: 99%; height: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; color: rgb(0, 0, 0); text-align: left; line-height: 20px;"&gt;&lt;code style="color: rgb(0, 0, 0);"&gt; private string _SpatialIndex;&lt;br /&gt;&lt;br /&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// Name of the spatial index table&lt;br /&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;public string SpatialIndex&lt;br /&gt;{&lt;br /&gt;get { return _SpatialIndex; }&lt;br /&gt;set { _SpatialIndex = value; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private string GetBoxClause(SharpMap.Geometries.BoundingBox bbox)&lt;br /&gt;{&lt;br /&gt;if (!string.IsNullOrEmpty(SpatialIndex))&lt;br /&gt;{&lt;br /&gt;StringBuilder sql = new StringBuilder("ROWID IN ( ");     &lt;br /&gt;sql.Append("SELECT pkid FROM ");&lt;br /&gt;sql.Append(SpatialIndex);&lt;br /&gt;sql.Append(" WHERE ");&lt;br /&gt;sql.AppendFormat(SharpMap.Map.numberFormat_EnUS,&lt;br /&gt;"xmin &amp;lt; {0} AND xmax &amp;gt; {1} AND ymin &amp;lt; {2} AND ymax &amp;gt; {3} )",&lt;br /&gt; bbox.Max.X, bbox.Min.X, bbox.Max.Y, bbox.Min.Y);&lt;br /&gt;&lt;br /&gt;return sql.ToString();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;string wkt = SharpMap.Converters.WellKnownText.GeometryToWKT.Write(LineFromBbox(bbox));&lt;br /&gt;return "MBRIntersects(GeomFromText('" + wkt + "')," + _GeometryColumn + ")=1";        &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=";font-family:trebuchet ms;font-size:100%;"  &gt;After making the changes, everything performed blisteringly fast. Perhaps even slightly faster than it did with PostGIS. So there you have it. A zero configuration GIS database for storing mastermap thats as easy to deploy as copying a file. All thanks to SpatiaLite (and a bit of work here and there). &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-493320205671811129?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/493320205671811129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2009/08/adventures-with-spatialite.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/493320205671811129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/493320205671811129'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2009/08/adventures-with-spatialite.html' title='Adventures with SpatiaLite'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-785523881057002641.post-8196681246877054332</id><published>2009-08-27T12:12:00.000-07:00</published><updated>2009-08-28T09:35:17.825-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ordnance Survey'/><title type='text'>To blog or not to blog...</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;I've never really understood blogging. I mean, blogs are great for finding things out but actually writing one...now why would you want to do that?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;Well, i guess maybe its time to give something back. Or maybe, its just time to start recording some of the nerdy little gems that make life as a software engineer just that bit sweeter.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;So here it is. A blog. Written by me. Who would have thought?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;My intention is to start writing a series of posts dealing with &lt;/span&gt;&lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/" style="font-family: trebuchet ms;"&gt;Ordnance Survey&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt; mapping data and Open Source GIS (undoubtedly paying much attention to &lt;/span&gt;&lt;a href="http://www.codeplex.com/SharpMap" style="font-family: trebuchet ms;"&gt;SharpMap&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt; along the way). Anyone who has to work with Ordnance Survey data may well understand the headache that can ensue from the vast amount of data processing and storage involved. Its often difficult to know where to start if your not buying into an enterprise GIS solution. So, if you don't want to splash out on proprietary software for dealing with all that GML...well you might just have come to the right place.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/785523881057002641-8196681246877054332?l=epsg27700.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://epsg27700.blogspot.com/feeds/8196681246877054332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://epsg27700.blogspot.com/2009/08/to-blog-or-not-to-blog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/8196681246877054332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/785523881057002641/posts/default/8196681246877054332'/><link rel='alternate' type='text/html' href='http://epsg27700.blogspot.com/2009/08/to-blog-or-not-to-blog.html' title='To blog or not to blog...'/><author><name>Kev</name><uri>http://www.blogger.com/profile/12481745416073495511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
