<?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-30644746</id><updated>2011-09-19T15:02:23.335+01:00</updated><category term='GIS'/><category term='W3G'/><category term='Dojo'/><category term='Complexity'/><category term='Usability'/><category term='LocalView'/><category term='Visualisation'/><category term='Agile'/><category term='web'/><category term='LocalGovCamp'/><category term='Watermarking'/><category term='JavaScript'/><category term='Lincoln'/><category term='ESRI'/><category term='Data Quality'/><category term='Testing'/><title type='text'>Boiler Wadding</title><subtitle type='html'>A Londoner in Lincoln. And Aylesbury. And on the M1 a lot.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>11</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-30644746.post-5868798767928177850</id><published>2010-12-22T10:16:00.001Z</published><updated>2010-12-22T10:16:57.786Z</updated><title type='text'>400 million maps in a month? Well, why not?</title><content type='html'>&lt;p&gt;I am surprised to hear that so much is being made of the &lt;a href="http://twitter.com/#!/timoreilly/statuses/17303935115071488" target="_blank"&gt;claim by Tim O’Reilly&lt;/a&gt;, whilst on a visit to ESRI, that ArcGIS.com handled 400 millions maps in October.&lt;/p&gt;  &lt;p&gt;Particularly odd are the comparisons too Flickr’s 200 million user uploads a month. Not just because two of the blog posts doing so, from &lt;a href="http://www.geocomrade.com/2010/12/22/arcgis-com-bigger-than-flickr/" target="_blank"&gt;@anderitr&lt;/a&gt; and &lt;a href="http://ianhaynes.blogspot.com/2010/12/arcgiscom-bigger-than-flickr.html" target="_blank"&gt;@ianhaynes&lt;/a&gt;, contain identical text!&lt;/p&gt;  &lt;p&gt;A Flickr user is not doing anything remotely like an ArcGIS.com user. A map request from ArcGIS.com is not anything like a user upload to Flickr. ArcGIS.com users are not uploading 400 million maps a month, they are requesting them.&lt;/p&gt;  &lt;p&gt;Unique visitors to ArcGIS.com consist in a large part of professional desktop and web GIS users, who will spend most of their working day looking at maps, some of which will have a basemap or other overlay requested from ArcGIS.com.&lt;/p&gt;  &lt;p&gt;In that context, assume the &lt;a href="http://siteanalytics.compete.com/flickr.com+arcgis.com/" target="_blank"&gt;30,000 or so unique visitors&lt;/a&gt; are GIS professionals, working on average 22 days a month, for 7 hours a day.&lt;/p&gt;  &lt;p&gt;400 million maps divided by 33,000 visitors is just over 12,000 each. But if each visitor visits every working day for 22 days a month, that’s only 550 maps a day each. In a 7 hour working day, that’s requesting 1.3 maps from ArcGIS.com per minute on average.&lt;/p&gt;  &lt;p&gt;In my performance testing I work with a long-held assumption that a GIS user will average 6 maps per minute, not 1.3. So this doesn’t seem hugely unreasonable to me.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30644746-5868798767928177850?l=warblingdiode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/5868798767928177850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warblingdiode.blogspot.com/2010/12/400-million-maps-in-month-well-why-not.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/5868798767928177850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/5868798767928177850'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/2010/12/400-million-maps-in-month-well-why-not.html' title='400 million maps in a month? Well, why not?'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30644746.post-5262601645723463376</id><published>2010-10-01T11:18:00.002+01:00</published><updated>2010-10-01T11:20:36.526+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='W3G'/><category scheme='http://www.blogger.com/atom/ns#' term='Data Quality'/><category scheme='http://www.blogger.com/atom/ns#' term='Usability'/><category scheme='http://www.blogger.com/atom/ns#' term='GIS'/><category scheme='http://www.blogger.com/atom/ns#' term='Visualisation'/><category scheme='http://www.blogger.com/atom/ns#' term='Complexity'/><title type='text'>Points &amp; Pointlessness: W3G lessons in GeoUsability</title><content type='html'>&lt;p&gt;This year’s inaugural AGI &lt;a href="http://www.w3gconf.com/" target="_blank"&gt;W3G unconference&lt;/a&gt; – “The Three Ws of Geography” was a breath of fresh air on the Geo-related conference circuit, which I am afraid to say I have happily ignored for some years now. There are only so many vendor pitches and PR presentations a man can take before deciding it’d be time better spent to go into the office and do some work instead.&lt;/p&gt;  &lt;p&gt;The unconference format promises to cut to the chase. People present, not organisations, and the format is more social, open and democratic. This of course makes the content difficult to predict, but I found that despite the apparent potential for a chaotic day of unrelated sessions, in fact W3G had some really strong themes running through it. Most of these touch on my “pet subjects”: pushpin overkill, poor usability, maps for the sake of it.&lt;/p&gt;  &lt;h2&gt;1. Your data is rubbish&lt;/h2&gt;  &lt;p&gt;This came up in &lt;a href="http://knowwhereconsulting.co.uk/" target="_blank"&gt;Steven Feldman&lt;/a&gt;, &lt;a href="http://www.flickr.com/photos/paul_clarke/5032482485/in/set-72157624926808787/" target="_blank"&gt;Charles Kennelly&lt;/a&gt; and &lt;a href="http://geothought.blogspot.com/" target="_blank"&gt;Peter Batty’s&lt;/a&gt; talks, albeit in subtly different ways:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Your data doesn’t always need to be mapped: think first: does it say anything useful? &lt;/li&gt;    &lt;li&gt;Your data is not sufficiently self-describing. Don’t waste time and money thinking you can manage metadata as a separate task – tell your users more about your data’s provenance IN the dataset. &lt;/li&gt;    &lt;li&gt;Publishing meaningless data - even in a pretty iPhone or iPad app - is a serious usability issue. Do more user testing first! &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;2. The Usability of your geo-app is poor&lt;/h2&gt;  &lt;p&gt;Consumer geo applications beat old-school GIS ones in terms of usability, because of the mantra to simplify, and then simplify again. Peter Batty quoted from Krug and make Jacob Nielsen’s 20-year-old point about usability testing: get anyone to do it, tell them nothing, and shut up and watch. 5 to 7 users will find 80% of your defects this way, as well as telling you way more about usability than you could ever guess as the designer or developer of an application.&lt;/p&gt;  &lt;p&gt;Why is this? Why do GIS applications come across so poorly? I have a theory here – it’s one of my pet subjects after all. Because GIS applications are usually sold to GIS people, they have one template in mind of what the UI should be: ArcVIew 3 effectively. &lt;/p&gt;  &lt;p&gt;&lt;img alt="ArcView 3 screenshot from ESRI" src="http://www.esri.com/news/arcuser/0701/graphics/avconvert4.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;Fill the screen with icons on tool bars and GIS people will want to buy it. Make it more simple or appear to “do less” and you may well sell fewer. GIS teams may then want the same thing as a web application to show off their lovely 250 datasets. But the people who &lt;em&gt;use&lt;/em&gt; the application will suffer: the “toolbox” approach doesn’t tell you where to start or what to do: it forces the average user to have to think too much, and on the web, attention spans are too short to guarantee any sort of success. If you’re used to using desktop GIS, or even the legacy web GIS applications, then you won’t spot this. GIS apps need to focus far more on focussed, simpler workflows, not lists of data and tools, if they are to be used successfully by large amounts of ordinary users. In essence, they should not bear any visual resemblance to a GIS app, I’d say.&lt;/p&gt;  &lt;h2&gt;3. Make the complex simple&lt;/h2&gt;  &lt;p&gt;I especially liked &lt;a href="http://googleearthdesign.blogspot.com/" target="_blank"&gt;Richard Treves’&lt;/a&gt; presentation, coming from a design and visualisation aspect, but touching on the age-old cartographic problem of how to present millions of points in a clear and readable way, without distorting the pattern or introducing bias.&lt;/p&gt;  &lt;p&gt;For my money I’d offer the user a choice of settings wherever a design decision has been made that could affect the interpretation. If you use a heatmap at small scales, say something about how grid size affects the pattern, and even allow the user to change it. IF you use point clusters, explain that you cannot tell what the distribution of the points is – allow teh raw data to be switched on, colour coded to show which cluster they represent. But don’t avoid these techniques just because of potential ambiguity, the alternative is the full extent map with one million markers that says absolutely nothing.&lt;/p&gt;  &lt;h3&gt;The Big Deal about W3G&lt;/h3&gt;  &lt;p&gt;So what made it such a different experience? I think for me, the fact that organisations such as Google, Nokia,  and Yahoo were present and actively contributing put what can otherwise be a parochial, academic, insular sort of event into a much wider context. And made the point, repeatedly, that location is a feature – not the be all and end all of any application. Even a hardcode GIS one! Well, so say I.&lt;/p&gt;  &lt;p&gt;Many of the points that were made – about geographic visualisation and analysis –were made by people who don’t come from the GIS tradition, but instead have expertise in usability, design, non-geographic visualisation: as a GIS professional I can benefit from extremely relevant experience from outside my field, that a traditional GIS conference cannot offer.&lt;/p&gt;  &lt;p&gt;Compare this to the GeoCommunity sessions: what’s the difference, at first glance at least? Well, to me the major contrast was the focus on consumer applications of geotechnology, and the huge emphasis this inevitably places on usability (meaning many things, but including data quality, a tested application, simple rendering of complex data – making the user have to think less). The “traditional” GIS community is usually far more preoccupied with a business-to-business or academic  focus, where standards and data interoperability and dry discussion of formats and functionality and features will necessarily dominate. The danger for me is that the the huge convergence of the two approaches, and the lessons each can teach to the other, are in danger of being ignored by “traditional” Geo community events. This could perhaps risk missing an enormous opportunity to reach a new consumer audience who now want to do a bit more with their location than spray it around Twitter in Foursquare spam-tweets, and may well want to take advantage of a bit of old-skool GIS analyis, if only it can be presented to them without them realising that that is what it is.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30644746-5262601645723463376?l=warblingdiode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/5262601645723463376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warblingdiode.blogspot.com/2010/10/points-pointlessness-w3g-lessons-in.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/5262601645723463376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/5262601645723463376'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/2010/10/points-pointlessness-w3g-lessons-in.html' title='Points &amp;amp; Pointlessness: W3G lessons in GeoUsability'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30644746.post-4631763300342908497</id><published>2010-08-23T22:34:00.001+01:00</published><updated>2010-08-23T22:38:39.375+01:00</updated><title type='text'>A Century-old Map Tiling Scheme</title><content type='html'>&lt;p&gt;I love it when my interests collide in unexpected ways. I spend a lot of my professional life thinking about &lt;a href="http://www.arcgis.com/help/help_Left.htm#CSHID=esri%2Ftiling.htm%23|StartTopic=content%2Fesri%2Ftiling.htm%23|SkinName=agos" target="_blank"&gt;web map tiling schemes for ESRI ArcGIS Server web mapping applications&lt;/a&gt;: tile size, map projection, levels of detail, image format and so on. Outside of work I indulge my childish fascination with &lt;a href="http://www.flickr.com/photos/boilerwadding/4770325159/" target="_blank"&gt;big, loud, fast moving machines&lt;/a&gt;. On a recent holiday to North Yorkshire I couldn’t resist &lt;strike&gt;dragging&lt;/strike&gt; taking the family to the spectacular &lt;a href="http://www.nymr.co.uk/" target="_blank"&gt;North Yorkshire Moors Railway&lt;/a&gt; where I came upon a really rather beautiful map.&lt;/p&gt;  &lt;p&gt;&lt;a title="Ceramic tiled map by Balding Wierdo, on Flickr" href="http://www.flickr.com/photos/boilerwadding/4921414428/" target="_blank"&gt;&lt;img alt="Ceramic tiled map" src="http://farm5.static.flickr.com/4094/4921414428_195feb8302.jpg" width="279" height="300" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The map in question is a &lt;a href="http://www.northeasterntilecompany.co.uk/TheNewMaps/tabid/55/Default.aspx" target="_blank"&gt;reproduction of an early twentieth century original&lt;/a&gt;,one of twenty or so produced by the North Eastern railway to show off its impressive railway network – now long since reduced to &lt;a href="http://www.trailways.info/" target="_blank"&gt;cycleways&lt;/a&gt; and overgrown embankments.&lt;/p&gt;  &lt;p&gt;By itself it’s a thing of beauty, but as a geography nerd and lover of maps I rather like the unexpected parallels with modern web mapping techniques: tile size (8” square), levels of detail (special tiles for greater detail) and image format (ceramic tiles!) were all considerations for the railway cartographers of 1903 just as they are for the GIS developer in 2010. The final product is just a little more static and permanent than its modern equivalent. Thanks to a little photoshoppery by the ever-obliging &lt;a href="http://www.mapspersecond.com/blog/" target="_blank"&gt;Matt Toon&lt;/a&gt; at Google we can see how the North Eastern Railway might have approached the task today:&lt;/p&gt;  &lt;p&gt;&lt;a title="Google tiled railway map" href="http://www.mapspersecond.com/images/g_railway.jpg" target="_blank"&gt;&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" title="Google Tile map" alt="Google zoom controls on 1903 tile map" src="http://www.mapspersecond.com/images/g_railway.jpg" width="279" height="300" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I was also impressed by the implicit supreme confidence in the permanence of not just the map but the railways it showed: ironic considering the surviving originals (examples remain at &lt;a href="http://www.eskvalleyrailway.co.uk/stations/whitby.html" target="_blank"&gt;Whitby&lt;/a&gt; and &lt;a href="http://www.scarborough-heritage.org/objects/TileMap.asp" target="_blank"&gt;Scarborough&lt;/a&gt;) have long outlived the lines they depict. If only I could say the same of the maps I work on whose life expectancy is usually 3 years at best, and of which no trace remains when they get decommissioned.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30644746-4631763300342908497?l=warblingdiode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/4631763300342908497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warblingdiode.blogspot.com/2010/08/century-old-map-tiling-scheme.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/4631763300342908497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/4631763300342908497'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/2010/08/century-old-map-tiling-scheme.html' title='A Century-old Map Tiling Scheme'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4094/4921414428_195feb8302_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30644746.post-8305133952614709632</id><published>2010-08-13T16:58:00.001+01:00</published><updated>2010-08-13T16:58:08.486+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='GIS'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><category scheme='http://www.blogger.com/atom/ns#' term='LocalView'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>FuncUnit: Getting Funky with automated JavaScript testing</title><content type='html'>&lt;p&gt;I’ve recently been attempting to make the testing of the software I’m working more agile, as the team I work with use Scrum as the development methodology. The problems could be summarised as:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;There is always a lag between development and testing: the software isn’t ready enough to test until late in the sprint, so sprints either overrun, or a “clean up” sprint is required to finish the testing, or fix bugs found very late. &lt;/li&gt;    &lt;li&gt;JavaScript functional testing (as opposed to unit testing) has traditionally been hard, especially with the kind of UI we typically build: a web GIS with lots of map interaction:pan, zoom, click to query, draw shapes. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The holy grail of my search has been to reduce the amount of manual regression testing we do, and increase the amount of unit testing. To make any impact this requires automation of complex UI tests in multiple browsers, linked to our Continuous Integration system (a hybrid of Cruise Control, nAnt, MSBuild and Team Foundation Server). Achieving this will allow the team to focus on more exploratory testing, and reduce sprint overruns. It should also highlight bugs at or shortly after check in time, so we don’t find them only after a huge round of manual regression tests.&lt;/p&gt;  &lt;p&gt;This week I came across a new tool, &lt;a href="http://jupiterjs.com/news/funcunit-fun-web-application-testing" target="_blank"&gt;FuncUnit&lt;/a&gt;. This is created by an outfit called &lt;a href="http://jupiterit.com/" target="_blank"&gt;Jupiter IT&lt;/a&gt;, who also produce &lt;a href="http://v3.javascriptmvc.com/index.html#&amp;amp;search=*&amp;amp;who=index" target="_blank"&gt;JavaScriptMVC&lt;/a&gt;. I liked the look of it straight away because it ties together existing frameworks I am familiar with: jQuery, qUnit, Selenium – but offers automated functional tests of modern, whizzy JavaScript map UIs – i.e. not just unit tests of static components (no bad thing in themselves of course). You even write the tests in jQuery-like syntax – perfect for our development team who are fluent in jQuery and Dojo. Best of all it allows the specification of user interactions like drag – so we can automate scripts to pan our maps and draw zoom boxes or sketch shapes, something that has always eluded us.&lt;/p&gt;  &lt;p&gt;I shan’t repeat too much detail on &lt;a href="http://jupiterjs.com/news/funcunit-fun-web-application-testing#news/how-funcunit-works" target="_blank"&gt;how FuncUnit works&lt;/a&gt; – you can go and read this for yourself. But an example might be useful to indicate how powerful and yet simple to implement this is. I had my first tests running within 15 minutes, performing an address look up using our Gazetteer client (running via a REST service against a remote web service), drilling down through a pick list of potential address matches, selecting one from the list, zooming to it on the map and kicking off a map search. The automation of this test is almost no further effort: create a batch file to call it from the command line instead of opening the test harness in a browser, and set up a scheduled task to run it after our nightly staging server deployment.&lt;/p&gt;  &lt;h2&gt;Installing FuncUnit&lt;/h2&gt;  &lt;p&gt;You can &lt;a href="http://funcunit.com/" target="_blank"&gt;get the latest download here&lt;/a&gt;. Installation is just a matter of extracting the files. I put them in a web folder so I can set up a server that the whole team can access.&lt;/p&gt;  &lt;p&gt;For my first test suite I used the template HTML file and copied the contents of the demo folder to a new folder, replacing the demo test page and JS file with my own.&lt;/p&gt;  &lt;p&gt;Copying the demo scripts and changing to find the HTML elements in my application, I ended up with the following script:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font size="1" face="Courier New"&gt;module(&lt;font color="#800000"&gt;&amp;quot;wp&amp;quot;&lt;/font&gt;,{         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#008040"&gt;//Set up: Open the map page&lt;/font&gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; setup : &lt;font color="#0000ff"&gt;function&lt;/font&gt;(){         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; S.open&lt;font color="#800000"&gt;(&lt;/font&gt;&lt;font color="#804000"&gt;&amp;quot;/LocalViewWeb/Sites/LV/&amp;quot;&lt;/font&gt;)         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;}) &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#008040"&gt;//Main test. NB each test reloads the application being tested, so all my logic is in a single test.&lt;/font&gt;           &lt;br /&gt;test(&lt;font color="#804000"&gt;&amp;quot;Address Search&amp;quot;&lt;/font&gt;, &lt;font color="#0000ff"&gt;function&lt;/font&gt;(){           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#008040"&gt;//wait for the Gazetteer search box to become visible.&lt;/font&gt;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; S(&lt;font color="#804000"&gt;&amp;quot;#partialAddress&amp;quot;&lt;/font&gt;).visible(&lt;font color="#0000ff"&gt;function&lt;/font&gt;(){           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#008040"&gt;//Click to clear the hint. Type a street name.&lt;/font&gt;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; S(&lt;font color="#804000"&gt;&amp;quot;#partialAddress&amp;quot;&lt;/font&gt;).click().type(&amp;quot;Walton Way&amp;quot;);           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#008040"&gt;//Click the &amp;quot;Search&amp;quot; button.&lt;/font&gt;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; S(&lt;font color="#804000"&gt;&amp;quot;#searchButton&amp;quot;&lt;/font&gt;).click(&lt;font color="#0000ff"&gt;function&lt;/font&gt;(){           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#008040"&gt;//Wait for the results container show.&lt;/font&gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; S(&lt;font color="#804000"&gt;&amp;quot;#resultsContainer&amp;quot;&lt;/font&gt;).visible(&lt;font color="#0000ff"&gt;function&lt;/font&gt;(){&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#008040"&gt;//check for at least 1 result            &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;var&lt;/font&gt; items = S(&lt;font color="#804000"&gt;&amp;quot;.picklist_row&amp;quot;&lt;/font&gt;).size();           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#008040"&gt;//use a qUnit assertion&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ok(items &amp;gt; 0, &lt;font color="#804000"&gt;&amp;quot;pick list has items&amp;quot;&lt;/font&gt;);           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; })           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; });           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#008040"&gt;//Now look in the results list.&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; //use jQuery syntax to click the first in the list             &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160; S(&lt;font color="#804000"&gt;&amp;quot;.picklist_row:first&amp;quot;&lt;/font&gt;).click(&lt;font color="#0000ff"&gt;function&lt;/font&gt;(){           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#008040"&gt;//When selected address is displayed, check the text            &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; S(&lt;font color="#804000"&gt;&amp;quot;#selectedAddress&amp;quot;&lt;/font&gt;).visible(&lt;font color="#0000ff"&gt;function&lt;/font&gt;(){           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;var&lt;/font&gt; a = S(&lt;font color="#804000"&gt;&amp;quot;#selectedAddressText &amp;gt; a&amp;quot;&lt;/font&gt;).text();           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#008040"&gt;//assert it's not an empty string            &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ok(a!=&lt;font color="#804000"&gt;&amp;quot;&amp;quot;&lt;/font&gt;, &lt;font color="#804000"&gt;&amp;quot;Selected address: &amp;quot;&lt;/font&gt; + a);           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; });           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;font size="1"&gt;&lt;font face="Courier New"&gt;&lt;font color="#008040"&gt;//Now choose a map search to run.            &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160;&amp;#160; S(&lt;font color="#804000"&gt;&amp;quot;#searchHeader&amp;quot;&lt;/font&gt;).visible(&lt;font color="#0000ff"&gt;function&lt;/font&gt;(){           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; S(&lt;font color="#804000"&gt;&amp;quot;#searchHeader&amp;quot;&lt;/font&gt;).click(&lt;font color="#0000ff"&gt;function&lt;/font&gt;(){           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#008040"&gt;//this only appears when results have been found&lt;/font&gt;           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; S(&lt;font color="#804000"&gt;&amp;quot;.result_row&amp;quot;&lt;/font&gt;).visible(&lt;font color="#0000ff"&gt;function&lt;/font&gt;(){           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;var&lt;/font&gt; divs = S(&lt;font color="#804000"&gt;&amp;quot;#resultPanel &amp;gt; div&amp;quot;&lt;/font&gt;).size();           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ok(divs&amp;gt;1, &lt;font color="#804000"&gt;&amp;quot;Feed search results found&amp;quot;&lt;/font&gt;);           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; });           &lt;br /&gt;})&lt;/font&gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The results are displayed in the test page.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_V2NgMSXwAyE/TGVrjf3SmLI/AAAAAAAACVU/XlIhzHYxjf4/s1600-h/FuncUnit%20Test%20page%5B6%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="FuncUnit Test page" border="0" alt="FuncUnit Test page" src="http://lh6.ggpht.com/_V2NgMSXwAyE/TGVrj7xZOfI/AAAAAAAACVY/5DyAQlxG1bQ/FuncUnit%20Test%20page_thumb%5B2%5D.png?imgmax=800" width="244" height="81" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Running this is just a matter of opening the test harness in a browser. Automating it is just a matter of using EnvJs to run it from the command line, supplying the browser(s) you wish to test with. In about 30 minutes I’ve got to a state where as of tomorrow, I no longer need to regression test address searching, zooming to the address on a map or running a geographic search. In another 30 minutes I can get map zooming and panning covered off and have a stab at a map-based click-to-identify-features test. Hurrah – this saves me and the whole team days of time each sprint!&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;ShortcominGS&lt;/h2&gt;  &lt;p&gt;So far so good, but to get this to be as useful as possible I need a bit more:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Alerts when the tests fail – run tests from Cruise Control server instead &lt;/li&gt;    &lt;li&gt;Ability to test multiple IE versions – create new VMs for IE6 and IE7 &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I’m really impressed at how far I’ve got so quickly though – it’s going to have an immediate impact. I’ll post more examples as I go along.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30644746-8305133952614709632?l=warblingdiode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/8305133952614709632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warblingdiode.blogspot.com/2010/08/funcunit-getting-funky-with-automated.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/8305133952614709632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/8305133952614709632'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/2010/08/funcunit-getting-funky-with-automated.html' title='FuncUnit: Getting Funky with automated JavaScript testing'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_V2NgMSXwAyE/TGVrj7xZOfI/AAAAAAAACVY/5DyAQlxG1bQ/s72-c/FuncUnit%20Test%20page_thumb%5B2%5D.png?imgmax=800' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30644746.post-8200911884093386829</id><published>2010-02-12T21:44:00.005Z</published><updated>2010-02-12T22:19:30.837Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Watermarking'/><category scheme='http://www.blogger.com/atom/ns#' term='GIS'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='ESRI'/><title type='text'>Watermarking your maps with the ESRI ArcGIS Server JavaScript API</title><content type='html'>&lt;p face="georgia" class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p face="georgia" class="MsoNormal"&gt;If you work with digital maps on the web outside the USA then the chances are you use copyright-protected data that must meet certain conditions for display on the web or printed page. Often this can be a combination of copyright statement and watermarking.&lt;/p&gt;  &lt;p face="georgia" class="MsoNormal"&gt;There are a number of ways to implement watermarking on your maps when you are working with the &lt;a href="http://resources.esri.com/arcgisserver/apis/javascript/arcgis/index.cfm?fa=home"&gt;ESRI ArcGIS Server JavaScript API&lt;/a&gt;. In this article I am going to discuss the options and describe the implementation I have chosen.&lt;/p&gt;  &lt;p face="georgia" class="MsoNormal"&gt;Watermarking involves displaying an image and/or some text over the map in a way that permits the data owner or map producer to be identified and prevents the map image being reused in a way that circumvents the data license. So, the trick is to get a transparent image to display over the map in a way that the map consumer cannot circumvent. This could be achieved in the following ways:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;Stamping dynamically created images with a watermark when they are written to disk, using a server technology such as Java or .Net.&lt;/li&gt;&lt;li&gt;Adding a “watermark layer” to the map service, for example a large polygon that covers the full extent of the map, symbolised with a raster fill symbol.&lt;/li&gt;&lt;li&gt;Drawing a watermark image over the map on the client, overlaying it using HTML and CSS.&lt;/li&gt;&lt;/ul&gt;      &lt;p face="georgia" class="MsoNormal"&gt;Each approach has its potential drawbacks, and the “correct” approach will depend on the nature of your application and the type of map data you are working with.&lt;/p&gt;  &lt;h2 style="font-family: georgia;"&gt;Which option works best?&lt;/h2&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;With the JavaScript API, we typically want base mapping to come from a tiled, cached source, as it is static data, and user expectation is of Google and Bing-like map performance. In this scenario we can’t stamp a watermark when each map is requested (Option 1), but we could when each map image is written to the cache folder. The folder structure may be a bit too complex to make this practical. So, we could add a watermark layer (Option 2) above at the point of map creation, when the cache is generated. This is robust as the user cannot turn it off, but there can be display issues – what if your application displays other data over the top? The watermark will not be the top level layer. What if your maps are overlaid with other watermarked maps? The overlay of several repeated transparent logos could get messy.&lt;/p&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;If we’re working with dynamic map services only, then there are plenty of opportunities to include a watermark, but we need a server implementation (such as a Windows Service that watches an output folder) to stamp the image when it’s written to disk – which won’t work if we’re streaming the image as MIME data – or, we have to include the watermark as a layer, which the user could turn off with a simple JavaScript call.&lt;/p&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;Alternatively we could use a proxy to intercept all map requests and stamp a watermark before passing to the client. This could be done at the map server level using a technique such as an HTTP Module for IIS –intercepting the request and adding a watermark to the image when it is streamed in the response. But, in my case, I am building a web application that consumes data from many sources, so I need to have an option to add a watermark in the browser for those situations where the map service doesn’t contain a watermark layer, or where multiple map sources are combined, or where I have no access to the map server to add watermarking to the HTTP pipeline.&lt;/p&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;So, it looks like option 3 may have a role to play where the base maps are coming from a tiled, cached source, or where we don’t have the access or maybe &lt;span style=""&gt; &lt;/span&gt;technical resources to develop a server-side watermarking application, or where a map watermark layer could be easily turned off by someone with basic JavaScript skills.&lt;/p&gt;  &lt;h2 style="font-family: georgia;"&gt;Implementing simple client-based watermarking&lt;/h2&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;Given that we now think a client-based solution is worth considering, how might we go about it?&lt;/p&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;With an ArcIMS application we’d use the Acetate layer, and with a Web ADF application we could add a Graphics Layer – does this work for the JavaScript API? Well, kind of. But JS API Graphics draw as Vector graphics in the browser – Web ADF ones render as transparent PNGs. So we’d need to bubble any mouse events that the graphics captured to ensure that map navigation through mouse interaction still works, and that other map graphics could still be drawn over the watermark. I have to say I don’t like the feel of this approach.&lt;/p&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;So, that leaves us with the need to tile or centre an image over the map (the image could contain text and/or a logo). What is the best way to achieve this?&lt;/p&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;Well, one relatively easy way is to add the watermark as if it were a map service “layer” (the JS API treats services as Layers within the map – each map Layer also has Layers of its own, potentially. I had a read of &lt;a href="http://arkblog.wordpress.com/"&gt;Sathya Prasad’s&lt;/a&gt; excellent articles on extending the &lt;a href="http://arcscripts.esri.com/details.asp?dbid=16258"&gt;DynamicMapServiceLayer&lt;/a&gt; and &lt;a href="http://resources.esri.com/arcgisserver/apis/javascript/arcgis/index.cfm?fa=codeGalleryDetails&amp;amp;scriptID=16585"&gt;TiledMapServiceLayer&lt;/a&gt; objects, and thought that if the methods that returned a URL just loaded a watermark, then it’d be relatively easy to add watermarks from a static image as if they were coming from a map layer. And it was. Here are two examples of watermark layers; implemented as a Dynamic layer (that gets one image that fits the map size) and a Tiled layer (that tiles the watermark in rows and columns).&lt;/p&gt;  &lt;h3 style="font-family: georgia;"&gt;Dynamic watermark layer:&lt;/h3&gt;  &lt;div style="border: 1pt solid windowtext; padding: 1pt 4pt; background: none repeat scroll 0% 0% rgb(217, 217, 217);"&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;dojo.provide(&lt;span style="color: rgb(163, 21, 21);"&gt;"myScripts.WatermarkLayer"&lt;/span&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style=";font-family:&amp;quot;;font-size:85%;"  &gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt; &lt;span style=";font-family:&amp;quot;;font-size:85%;"  &gt;dojo.declare(&lt;span style="color: rgb(163, 21, 21);"&gt;"myScripts.WatermarkLayer"&lt;/span&gt;, esri.layers.DynamicMapServiceLayer, {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;    &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    startExtent: &lt;span style="color:blue;"&gt;new&lt;/span&gt; esri.geometry.Extent({ xmin: 0, ymin: 0, xmax: 700000, ymax: 1300000, spatialReference: { wkid: 27700} }),&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;&lt;span style="color:green;"&gt;//construct the layer&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;constructor: &lt;span style="color:blue;"&gt;function&lt;/span&gt;(args) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;              &lt;/span&gt;&lt;span style="color:blue;"&gt;this&lt;/span&gt;.initialExtent = &lt;span style="color:blue;"&gt;this&lt;/span&gt;.fullExtent = &lt;span style="color:blue;"&gt;this&lt;/span&gt;.startExtent;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;              &lt;/span&gt;&lt;span style="color:blue;"&gt;this&lt;/span&gt;.spatialReference = &lt;span style="color:blue;"&gt;this&lt;/span&gt;.initialExtent.spatialReference;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;              &lt;/span&gt;dojo.mixin(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, args);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;              &lt;/span&gt;&lt;span style="color:green;"&gt;//set layer loaded property and fire onLoad event&lt;/span&gt;&lt;span style="color:blue;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; text-indent: 36pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;span style=""&gt; &lt;/span&gt;this&lt;/span&gt;&lt;span style="font-size:85%;"&gt;.loaded = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;              &lt;/span&gt;&lt;span style="color:blue;"&gt;this&lt;/span&gt;.onLoad(&lt;span style="color:blue;"&gt;this&lt;/span&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;},&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;getImageUrl: &lt;span style="color:blue;"&gt;function&lt;/span&gt;(extent, width, height, callback) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;              &lt;/span&gt;&lt;span style="color:blue;"&gt;try&lt;/span&gt; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;            &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;                    &lt;/span&gt;callback(&lt;span style="color:blue;"&gt;this&lt;/span&gt;.url);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;              &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;              &lt;/span&gt;&lt;span style="color:blue;"&gt;catch&lt;/span&gt; (ex) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;                    &lt;/span&gt;console.debug(&lt;span style="color: rgb(163, 21, 21);"&gt;"Error getting Watermark image. "&lt;/span&gt; + ex.message);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;              &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;},&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;_errorCallback: &lt;span style="color:blue;"&gt;function&lt;/span&gt;(err) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;              &lt;/span&gt;console.error(err.message);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;"&gt;&lt;span style="line-height: 115%;font-family:&amp;quot;;font-size:9pt;"  &gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;});&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="line-height: 115%;font-family:&amp;quot;;font-size:12pt;"  &gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h3 style="font-family: georgia;"&gt;Tiled Watermark Layer:&lt;/h3&gt;  &lt;div style="border: 1pt solid windowtext; padding: 1pt 4pt; background: none repeat scroll 0% 0% rgb(217, 217, 217);"&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;dojo.provide(&lt;span style="color: rgb(163, 21, 21);"&gt;"myScripts.WatermarkTiledLayer"&lt;/span&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;dojo.declare(&lt;span style="color: rgb(163, 21, 21);"&gt;"myScripts.WatermarkTiledLayer"&lt;/span&gt;, esri.layers.TiledMapServiceLayer, {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;watermarkUrl: &lt;span style="color: rgb(163, 21, 21);"&gt;""&lt;/span&gt;,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;&lt;span style="color:green;"&gt;//construct the layer&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;constructor: &lt;span style="color:blue;"&gt;function&lt;/span&gt;(args) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;                  &lt;/span&gt;dojo.mixin(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, args);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;            &lt;/span&gt;&lt;span style="color:green;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;                  &lt;/span&gt;&lt;span style="color:green;"&gt;//set layer loaded property and fire onLoad event&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;span style=""&gt;       &lt;/span&gt;&lt;span style=""&gt;             &lt;/span&gt;&lt;span style=""&gt;  &lt;/span&gt;this&lt;/span&gt;&lt;span style="font-size:85%;"&gt;.loaded = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;                  &lt;/span&gt;&lt;span style="color:blue;"&gt;this&lt;/span&gt;.onLoad(&lt;span style="color:blue;"&gt;this&lt;/span&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;            &lt;/span&gt;},&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;            &lt;/span&gt;getTileUrl: &lt;span style="color:blue;"&gt;function&lt;/span&gt;(level, row, col) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;                  &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.watermarkUrl;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;            &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;"&gt;&lt;span style="line-height: 115%;font-family:&amp;quot;;font-size:9pt;"  &gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;    &lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;});&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="line-height: 115%;font-family:&amp;quot;;font-size:12pt;"  &gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;h3 style="font-family: georgia;"&gt;Usage&lt;/h3&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;This sample code checks to see if the map’s base layer is tiled, and if so, creates a tiled watermark. If not, it creates a dynamic one.&lt;/p&gt;&lt;p style="font-family: georgia;" class="MsoNormal"&gt;   &lt;/p&gt;&lt;p class="MsoNormal" style="margin: 0cm 0cm 0.0001pt 36pt; line-height: normal; background: none repeat scroll 0% 0% white;"&gt;&lt;span style=";font-family:&amp;quot;;font-size:12pt;color:blue;"   &gt;&lt;span style=""&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:&amp;quot;;font-size:12pt;"  &gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid windowtext; padding: 1pt 4pt; background: none repeat scroll 0% 0% rgb(217, 217, 217);"&gt;  &lt;p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;"&gt;&lt;span style=";font-family:&amp;quot;;font-size:9pt;"  &gt;&lt;span style=""&gt;   &lt;span style="font-family:courier new;"&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;color:blue;"   &gt;var&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt; wm;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; text-indent: 36pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;   &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; base = map.getLayer(map.layerIds[0]);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (base.tileInfo == &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;            &lt;/span&gt;wm = &lt;span style="color:blue;"&gt;new&lt;/span&gt; myScripts.WatermarkLayer({ url: “http://www.mydomain.com/somefolder/images/watermark.png” });&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;&lt;span style="color:blue;"&gt;else&lt;/span&gt; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;            &lt;/span&gt;wm = &lt;span style="color:blue;"&gt;new&lt;/span&gt; myScripts.WatermarkTiledLayer({&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;             &lt;/span&gt;&lt;span style=""&gt;       &lt;/span&gt;watermarkUrl: “http://www.mydomain.com/somefolder /images/watermark.png”,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;                    &lt;/span&gt;tileInfo: base.tileInfo,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;                    &lt;/span&gt;initialExtent: base.initialExtent,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;                    &lt;/span&gt;fullExtent: base.fullExtent,&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;                    &lt;/span&gt;spatialReference: base.spatialReference&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt;               &lt;/span&gt;});&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="margin-bottom: 0.0001pt; line-height: normal; background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;wm.setOpacity(0.15);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="background: none repeat scroll 0% 0% rgb(217, 217, 217); border: medium none; padding: 0cm;font-family:courier new;"&gt;&lt;span style="line-height: 115%;font-size:85%;" &gt;&lt;span style=""&gt;        &lt;/span&gt;map.addLayer(wm);&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p&gt;&lt;/p&gt;&lt;span style="font-size:130%;"&gt;What’s going on here then?&lt;/span&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;Basically, the Dynamic watermark layer is requesting an image from a static URL each time the map is redrawn. Browser caching means this image is only downloaded once, so it performs well. But unless you know what size the map image is, the watermark may get stretched or squashed.&lt;/p&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;The Tiled layer implementation works a bit better. When the layer object is created, it copies the tileInfo property from the base layer (read: base map service) of the map control. So the watermarkimage assumes the dimensions of each tile image, and is neatly tiled across the screen in rows. You will often know or be able to predict the tile image sizes: 256 x 256 is pretty common, so you can get the watermarks looking a lot better than with the Dynamic layer approach.&lt;/p&gt;    &lt;p style="font-family: georgia;" class="MsoNormal"&gt;When the map is loaded, we just add a layer on top of any others in the stack of services we’re using, and hey presto – we get watermarking over the top of them all.&lt;/p&gt;  &lt;h1 style="font-family: georgia;"&gt;Drawbacks&lt;/h1&gt;  &lt;p style="font-family: georgia;" class="MsoNormal"&gt;This approach is clearly not without its limitations. Here are the main ones I can think of:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;Dynamic images will stretch the watermark and distort it, unless your map application has a fixed viewport size.&lt;/li&gt;&lt;li&gt;Tiled images will only work if your base map layer is also tiled, otherwise you’ll need to invent a tiling scheme for the map, and it will behave as if it’s using a cached, tiled map source.&lt;/li&gt;&lt;li&gt;Any JavaScript developer worth their salt will be able to traverse your map object’s layers collection, find the watermark layer, and switch it off. So it’s your decision whether this approach is robust enough for the application you’re developing.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30644746-8200911884093386829?l=warblingdiode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/8200911884093386829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warblingdiode.blogspot.com/2010/02/watermarking-your-maps-with-esri-arcgis.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/8200911884093386829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/8200911884093386829'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/2010/02/watermarking-your-maps-with-esri-arcgis.html' title='Watermarking your maps with the ESRI ArcGIS Server JavaScript API'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30644746.post-5290275919901111224</id><published>2009-11-24T07:41:00.002Z</published><updated>2009-11-24T08:11:53.671Z</updated><title type='text'>Performance Testing with Visual Studio 2008</title><content type='html'>I'm back at the controls of Visual Studio Team Test edition (2008 this time, woo hoo) loading and running performance tests against some software I'm developing. This time round I am doing basic analysis to see where potential bottlenecks lie, and to spot any memory issues whilst there is still plenty of time to fix these.&lt;br /&gt;&lt;br /&gt;However, I had some difficulty getting my tests recorded - turns out there are a few things you need to bear in mind if your test client is Windows 7, Server 2008 or Vista, mainly around the enhanced security configuration (Server 2008) and IE security. Basically, if during your test you switch from one internet "zone" to another - for example, from "about:blank" to an actual website - then IE will kill the original iexplore process and launch a new one. Very secure, but it kills the ability to record web tests until you sort it out.&lt;br /&gt;&lt;br /&gt;I found a great blog site run by Michael Taute that lists pretty much all the reasons why this behaviour can happen, and what to do about it. In my case I switched off the enhanced security configuration for administrators, and added "about:blank" to the same internet "zone" as the site I was testing.&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://blogs.msdn.com/mtaute/archive/2007/11/09/diagnosing-and-fixing-web-test-recorder-bar-issues.aspx"&gt;Michael's blog page&lt;/a&gt; for the full list of issues and fixes.&lt;br /&gt;&lt;br /&gt;Oh, and if, like me, you're an idiot, you'll find your load test doesn't work if you don't create the load test database before you start. There are a few steps to remember before you start testing, &lt;a href="http://blogs.catapultsystems.com/tlingenfelder/archive/2009/06/18/step-by-step-configure-performance-testing-using-visual-studio-2008.aspx"&gt;as detailed by Travis Lingenfelder&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30644746-5290275919901111224?l=warblingdiode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/5290275919901111224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warblingdiode.blogspot.com/2009/11/performance-testing-with-visual-studio.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/5290275919901111224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/5290275919901111224'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/2009/11/performance-testing-with-visual-studio.html' title='Performance Testing with Visual Studio 2008'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30644746.post-3618857658939551597</id><published>2009-10-26T17:54:00.007Z</published><updated>2009-10-28T13:59:40.691Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='GIS'/><category scheme='http://www.blogger.com/atom/ns#' term='LocalGovCamp'/><category scheme='http://www.blogger.com/atom/ns#' term='LocalView'/><category scheme='http://www.blogger.com/atom/ns#' term='Lincoln'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>RAW DATA NOW! My first LocalGovCamp</title><content type='html'>And so to Lincoln's multi-coloured new Innovation Centre, the &lt;a href="http://www.lincolnthinktank.co.uk/"&gt;Think Tank&lt;/a&gt;, for my first ever &lt;a href="http://lgclincoln.wordpress.com/"&gt;LocalGovCamp&lt;/a&gt;. Wow, what a way to run a conference - spread the word on Twitter, allow delegates to set the agenda, and let the group sessions moderate themselves. It was a world away from the sleeping delegates on a day away from work who attend most of the presentations I've given at user conferences and technical workshops over the years. With about 45 people there it's a good deal smaller too, and all the more effective for it.&lt;br /&gt;&lt;br /&gt;Why was it so good? For me, it was a combination of factors:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A pretty unique mix of delegates, not the usual corporate conference crowd at all&lt;br /&gt;&lt;/li&gt;&lt;li&gt;No big corporate presence, just open discussion (I wondered - unnecessarily as it turned out - if being an ESRI employee would actually upset people)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Great presentations, especially &lt;a href="http://www.pezholio.co.uk/"&gt;Stuart Harrison&lt;/a&gt;'s &lt;a href="http://jadu.co.uk/localgovcamp"&gt;Easy Mapping demo&lt;/a&gt;, and &lt;a href="http://paulcanning.blogspot.com/"&gt;Paul Canning's&lt;/a&gt; reworking of Jakob Nielsen's still-relevant &lt;a href="http://www.useit.com/alertbox/discount-usability.html"&gt;Discount Usability&lt;/a&gt; ideas (well, 20 years after the original was published, only one person in the room had done any user testing of any sort!)&lt;/li&gt;&lt;li&gt;The chance to get past the GIS departments and speak to the webmasters, PR people, and a whole slew of innovative minds - who are now busily filling the web with maps and spatial data, often without a GIS system in sight.&lt;/li&gt;&lt;/ul&gt;I think the key lessons for me were related to what I do, i.e. web mapping and GIS:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Simple is good. By and large the public don't want really complex map data like &lt;a href="http://www.ordnancesurvey.co.uk/oswebsite/products/osmastermap/"&gt;OS MasterMap&lt;/a&gt;, they want pushpins on a Google map. MasterMap has a place though, for marking up planning applications for example.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;GIS Data needs to be indexable and mashable. Webmasters want embeddable maps and raw data: as KML or GeoRSS, not in a black-box, closed system that runs as a standalone web page. At one point the whole room was shouting "Raw data now!"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Usability of old-school web maps, based on GIS systems, is poor. Usability analysis has been neglected for too long, but with just 5-7 users testing, you can find 80% of your site's defects.&lt;/li&gt;&lt;/ul&gt;So, kudos to Andrew Beeken for organising it, to Stuart Harrison for showing us how to just get on with getting the data out there (and for some constructive criticism of LocalView :-)), and to the whole LocalGovCamp crowd for making it happen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30644746-3618857658939551597?l=warblingdiode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/3618857658939551597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warblingdiode.blogspot.com/2009/10/raw-data-now-my-first-localgovcamp.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/3618857658939551597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/3618857658939551597'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/2009/10/raw-data-now-my-first-localgovcamp.html' title='RAW DATA NOW! My first LocalGovCamp'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30644746.post-3788361956735914373</id><published>2008-06-06T11:12:00.002+01:00</published><updated>2008-06-06T11:16:29.371+01:00</updated><title type='text'>More RAF connections</title><content type='html'>Looks like there's a Boiling connection up the road at RAF Winthorpe (now Newark showground and Air Museum):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.worldwar2exraf.co.uk/Aircrew%20Notice%20Board/aircrew%20notice%20board%2077.htm"&gt;http://www.worldwar2exraf.co.uk/Aircrew%20Notice%20Board/aircrew%20notice%20board%2077.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Sergeant S C Boiling was based there in 1945 and survived a crash of the Lancaster in which he was a crewman, for the 1661 Heavy Conversion Unit (HCU). The details on the post are wrong, it crashed at Hall Farm, Oxton (near Southwell, a few miles from Winthorpe).&lt;br /&gt;&lt;br /&gt;An S C Boiling of Derby reportedly died in November 2007 - maybe the same one?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30644746-3788361956735914373?l=warblingdiode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/3788361956735914373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warblingdiode.blogspot.com/2008/06/more-raf-connections.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/3788361956735914373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/3788361956735914373'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/2008/06/more-raf-connections.html' title='More RAF connections'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30644746.post-115374560147863208</id><published>2006-07-24T13:50:00.000+01:00</published><updated>2006-07-24T13:53:21.486+01:00</updated><title type='text'>Spacemen 3 and Loop on YouTube</title><content type='html'>Relive the halcyon days of indie hypnomonotony through the wonder of YouTube:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=4mfgZNuheYc&amp;search=loop%20collision"&gt;Loop - Collision&lt;/a&gt;&lt;br /&gt;A nice collection of &lt;a href="http://www.youtube.com/results?search=spacemen+3&amp;amp;search_type=search_videos&amp;search=Search"&gt;Spacemen 3 videos&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30644746-115374560147863208?l=warblingdiode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/115374560147863208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warblingdiode.blogspot.com/2006/07/spacemen-3-and-loop-on-youtube.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/115374560147863208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/115374560147863208'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/2006/07/spacemen-3-and-loop-on-youtube.html' title='Spacemen 3 and Loop on YouTube'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30644746.post-115202655630051595</id><published>2006-07-04T16:19:00.000+01:00</published><updated>2006-07-04T16:22:36.300+01:00</updated><title type='text'>RT Ponting  lbw  b Boiling  1</title><content type='html'>One of many international batsmen to fall to the wily offspin of James Boiling - Ricky Ponting lasted &lt;a href="http://usa.cricinfo.com/db/ARCHIVE/1992-93/ENG-A_IN_AUS/ENG-A_TAS_08-10FEB1993.html"&gt;a mere 6 balls&lt;/a&gt; in 1993.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30644746-115202655630051595?l=warblingdiode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/115202655630051595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warblingdiode.blogspot.com/2006/07/rt-ponting-lbw-b-boiling-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/115202655630051595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/115202655630051595'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/2006/07/rt-ponting-lbw-b-boiling-1.html' title='RT Ponting  lbw  b Boiling  1'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-30644746.post-115202610498363720</id><published>2006-07-04T16:02:00.000+01:00</published><updated>2006-07-04T16:15:04.990+01:00</updated><title type='text'>Secret Students On Parade</title><content type='html'>Hot off the press...Graham Boiling's memoir of life as a Cold War National Serviceman in the RAF, learning Russian at Crail in Fife. Read the background to the book on the &lt;a href="http://www.thecourier.co.uk/output/2005/10/05/featuresstory7607778t0.asp"&gt;Dundee Courier website&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can get the book from &lt;a href="http://www.amazon.co.uk/gp/product/1842941690/202-9970810-6643802?v=glance&amp;n=266239"&gt;Amazon&lt;/a&gt;  or better still, direct from the &lt;a href="http://www.planetree.com/book.cfm/bookid/213/custno/0"&gt;publisher&lt;/a&gt; (Plane Tree): .&lt;br /&gt;&lt;br /&gt;Or you can go to Crail airfield to look at the &lt;a href="http://www.controltowers.co.uk/C/Crail.htm"&gt;control tower &lt;/a&gt;, or even &lt;a href="http://www.crailraceway.co.uk/index.asp"&gt;have a race&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30644746-115202610498363720?l=warblingdiode.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://warblingdiode.blogspot.com/feeds/115202610498363720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://warblingdiode.blogspot.com/2006/07/secret-students-on-parade.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/115202610498363720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/30644746/posts/default/115202610498363720'/><link rel='alternate' type='text/html' href='http://warblingdiode.blogspot.com/2006/07/secret-students-on-parade.html' title='Secret Students On Parade'/><author><name>Ed Boiling</name><uri>http://www.blogger.com/profile/11306871482390994434</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://1.bp.blogspot.com/_V2NgMSXwAyE/SuXy_mk_nQI/AAAAAAAAB30/bOiVidC4wcE/S220/eddie09.jpg'/></author><thr:total>0</thr:total></entry></feed>
