Chrome Problems

September 4th, 2008

Fig 1 IE with Silverlight ve:Map component

With the introduction of Chrome, Google has thrown down the gauntlet to challenge IE and Firefox. Out of curiosity I thought it would be interesting to download the current Chrome Beta and see what it could do with some of the interfaces I’ve worked on. Someone had recently quipped, “isn’t all of Google Beta?” I guess the same could be said of Amazon AWS, but then again in the “apples to apples” vein, I decided to compare IE8 Beta and Chrome Beta. The above screen shot shows an example of the new Silverlight ve:Map component in an ASP Ajax running on II6. The browser is IE8 beta in Vista, and surprise, not, it all works as expected.


Fig 2 Chrome with Silverlight ve:Map component

Also not surprisingly, the same Silverlight ve:Map component in an ASP Ajax site fares poorly in Chrome. In fact the component appears not at all, while curiously the menu asp:MenuItems act oddly. Instead of the expected drop down I get a refresh to a new horizontal row?


Fig 3 IE with Silverlight ve:Map component

Moving on to a Google Map Component embedded in the same ASP page, IE8 beta displays the map component including the newer G_SATELLITE_3D_MAP map type. ASP drop down menu and tooltips all work.


Fig 4 Chrome with Silverlight ve:Map component

Since this is a Google Map Component I would be disappointed if it did not work in Chrome, and it does. Except, I noticed the G_SATELLITE_3D_MAP control type is missing? I guess Chrome Beta has not caught up with Google Map Beta. Again the ASP Menu is not functional.


Fig 5 IE Google Map Control with Earth Mode - G_SATELLITE_3D_MAP

Back to IE to test the 3D Earth mode of my Google Map Component.As seen above it all works fine.


Fig 6 IE Silverlight Deep Earth

Now to check the new Silverlight DeepEarth component in IE. DeepEarth is a nice little MultiScaleTile source library for smoothly spinning around the VE tile engines. It works as amazingly smooth as ever.


Fig 7 Google Chrome Deep Earth

However, in Chrome, no luck, just a big white area. I suppose that Silverlight was not a high priority with Chrome.


Fig 8 IE SVG hurricane West Atlantic weather clip

Switching to some older SVG interfaces, I took a look at the Hurricane clips in the West Atlantic. It looks pretty good, Hanna is deteriorating to a storm and Ike is still out east of the Bahamas.


Fig 9 Chrome SVG hurricane West Atlantic weather clip

On Chrome it is not so nice. The static menu side of the svg frames shows up but the image and animation stack is just gray. Clicking on menu items verifies that events are not working. Of course this SVG is functional only in the Adobe SVG viewer, but evidently Chrome has some svg problems.


Fig 10 IE ASP .NET 3.5

Moving back to IE8, I browsed through a recent ASP .NET 3.5 site I built for an Energy monitoring service. This is a fairly complete demonstration of ListView and Linq SQL and it of course works in IE8 beta.


Fig 11 Chrome ASP .NET 3.5

Surprisingly, Chrome does a great job on the ASP .NET 3.5. Almost all the features work as expected with the exception of the same old Menu problems.


Fig 12 IE SVG OWS interface

Finally I went back down memory lane for an older OWS interface built with the SVG, using the Adobe Viewer variety. There are some glitches in IE8 beta. Although I can still see WMS and WFS layers and zoom around a bit , some annoying errors do pop up here and there. Adobe SVG viewer is actually orphaned, ever since Adobe picked up Macromedia and Flash, so it will doubtless receed into the distant past as the new browser generations arrives. Unfortunately, there is little Microsoft activity in SVG, in spite of competition from the other browsers, Safari, Firefox, and Opera. It will likely remain a 2nd class citizen in IE terms as SIlverlight’s intent is to replace Flash, which itself is a proprietary competitor to SVG.


Fig 13 Chrome SVG OWS interface

Chrome and Adobe SVG are not great friends. Rumor has it that Chrome intends to fully support SVG, so if I ever get around to it, I could rewrite these interfaces for Firefox, Opera, Chrome 2.0.

Summary:
Chrome is beta and brand new. Although it has a lot of nice features and a quick clean tabbed interface, I don’t see anything but problems for map interfaces. Hopefully the Google Map problems will be ironed out shortly. There is even hope for SVG at some later date. I imagine even Silverlight will be supported grudgingly since I doubt that Google has the clout to dictate useage on the ineternet.

Virtual Earth - DeepEarth - Deep Pockets

August 30th, 2008

Fig 1 Browser Virtual Earth Map control with KML overlay in 3D

Microsoft has released a new set of controls with Silverlight 2.0Beta, including the Virtual Earth Map control, Microsoft.Live.ServerControls.VE. This makes it even easier for cross browser map interface solutions. Silverlight like Flash requires a client side code download, which is available for IE, FireFox, Opera, and Safari. This control introduces VE Map to Microsoft’s version of declarative xml vector graphics in the browser, building on the older work of SVG. Having a VE Map control available cross browser makes VE more competitive with Google Map API. Having a Map control with C# event coding rather than javascript makes life for developers more interesting.

The release of SQL Server 2008 and its spatial extensions makes this control even better from a developers perspective. I am looking forward to seeing how to use Linq Sql to tie together spatial Sql Server datasets and VE map controls.

In order to use this control you must register both a Silverlight and a VE Assembly:

<%@ Register Assembly=”System.Web.Silverlight”
Namespace=”System.Web.UI.SilverlightControls”
TagPrefix=”asp” %>

<%@ Register assembly=”Microsoft.Live.ServerControls.VE”
namespace=”Microsoft.Live.ServerControls.VE”
tagprefix=”ve” %>

Once these are added to your aspx page the control element itself looks like this:

<ve:Map ID=”Map1″ runat=”server”
Height=”100%” Width=”100%”
ZoomLevel=”5″ Center-Latitude=”38″ Center-Longitude=”-105″
MapStyle=”Shaded” MiniMap=”True”
MiniMapYoffset=”150″ MiniMapXoffset=”10″
ShowFindControl=”False” DashboardSize=”Normal” />

This Map1 element has a host of properties and methods as this subset snapshot shows:


Fig 2 Sampling of <ve:Map> properties in the Visual Studio 2008 properties frame

Code behind cs can include any of the Map1 behaviors:

using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; using Microsoft.Live.ServerControls.VE; public partial class display_displayVE : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e)···· { if (!Page.IsPostBack)········ {··········· Map1.Clear();······ ShapeLayer shplayer = new ShapeLayer();·· Map1.AddShapeLayer(shplayer);········· ShapeSourceSpecification shapeSpec = new ShapeSourceSpecification(DataType.ImportXML, “http://localhost/brat/kml/Track.kml”, shplayer);············ Map1.ImportShapeLayerData(shapeSpec, “”, true);········ }···· } }

Listing 1 sample C# use of Map1 control in code behind

All of the previous VE Javascript SDK Javascript SDK should now have their equivalent in C#. I can use C# to interact with the VE map object including 3D mode, Traffic overlays, Routing, Geocoding, and Location Find, which means a quick easy way to add full featured maps to any business app. This map object is part of the Silverlight 2.0Beta.

Another interesting part of 2.0Beta is the MultiScaleImage or DeepZoom. I played with this earlier in a simplistic fashion but there is a nice feature I didn’t notice, MultiScaleTileSource. This lets a user add an alternative tile source which has lots of applications. Here is a pretty one by Mike Ormund, coding the Mandelbrot Set as a MultiScaleImage with a custom MultiScaleTileSource:


Fig 3 Mandelbrot Set with DeepZoom MultiScaleTileSource

 

 

 

 

Here is another blog with some details on using the Silverlight MultiScaleImage with MultiScaleTileSource: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/06/25/10536.aspx

The logical extension of this from a GIS perspective is DeepEarth. DeepEarth is a CodePlex project that applies the MultiScaleTileSource to a Silverlight Map interface. The current version supports the Microsoft Virtual Earth Engine which is interesting in its own right, but can be modified to use other tile source such as Google Map, or any WCS source of your choice. DeepEarth is a fascinating interface. The mousewheel spin zoom and pan is addictive with all the fade in/out animation. This project also has a beautiful little navigation tool, seen in the upper left corner. Clicking on the navigation tool does a little spin sprocket animation to open and close the tool set. However, the real fun is just wheel spin zooming.


Fig 4 Deep Earth Silverlight with MulticaleImage tile sourced to the VE engine. A static image does not do it justice. Deep Earth really invites playing!

 

 

 

 

Because this directly accesses the VE tile engine it of course will not be legitimate without changes to the Microsoft license restrictions. Here is a quick summary of the commercial VE license:

Standard version license is $8000 for 1,000,000/year transactions = 8,000,000/year tile renders. Note: no routing in standard
Advanced version license is $15,000 for 1,500,000/year transactions = 12,000,000/year tiles. Includes routing capability

8,000,000 annual tile renders sounds like a lot of tiles, but playing with the DeepEarth interface and watching tiles roam in and out of view made me wonder. If you put up a public site, for example, what would be an average transaction number per view? I tested a zoom from world down to my house rooftop. Checking against the cached tiles C:\Users\user\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5 gave 540 tile images. This is just a little bitty zoom though, and I can see an average user stacking up even ten times this amount, but for sake of argument, let’s assume a mere 1000 tile rendering count per site view. Gulp, this leads to only about 8000 user views per year or 22 per day before the overage rates kick in:

An overage rate (generally $0.01 per transaction) is listed for exceeding the preset number of transactions for use during the term.
Recalling there are 8 render tiles per transaction 0.01/8*1000 = $1.25 per viewer use of the interface!

Even if the Microsoft license were to allow direct VE access, I wonder what will be the chances of a commercial version of this type of interface. It also makes me wonder what kinds of tile rendering counts are generated on the Virtual Earth control? Checking the tile cache after using ve:Map reveals 320 tiles. So roughly 2/3 the count but still $0.80 per view. Seems to be a very useful metric to have before committing to a public website. If my rough calculations are correct then ve:Map could lead to DeepPockets more than DeepEarth.

An alternative to the VE Map control is the now venerable Google Map API recently updated with the Earth mode which gives the browser a bit of the Google Earth 3D view. The license is different:

Google license: $10,000 annual license fee + page views over 2,000,000/annual

I guess I would like some clarification on the ‘render transactions’ license of Virtual Earth versus the Google Map license of ‘page views’, but the Google license seems to compare rather favorably based on page views rather than tile renders. I checked the tile cache for a similar navigation using the Google GMap2 object and get about 600 tiles. However, for GMap2 objects this is irrelevant, since there is just a single page view regardless of the navigation tiles downloaded. In this light GMap2 looks really good at $0.005 per user view versus ve:Map at $0.50-$1.00 per user view. This is a 100:1 cost ratio so VE MAP team might need to revisit their pricing. I hope Microsoft can be more competitive eventually, since ve:Map is a nice Silverlight control. It would also be nice to have some real use metrics for a reality check.


Fig 5 Google Map api control with the new Earth view

Summary:
DeepEarth is a beautiful interface and shows the power of the MultiScaleTileSource, but even if licensing allowed direct access to the VE tile engine or Googles tile engine, it appears cost would make it prohibitive. However, MultiScaleTileSource can be tied to much less ambitious tile engines (free). I am thinking about the WCS ImageMosaic Plugin of the GeoServer project. I imagine adequate performance would require prebuilding a GeoWebCache tile cache. In this scenario the webservice MultiScaleImage can tie into proprietary WCS imagery and still provide the beautiful interactivity of DeepEarth on a more limited scale. Not a bad interface for 6″ GDS aerial imagery.

A quick look at GoGrid

August 14th, 2008

Fig 1 a sample ASP .NET 3.5 website running on a GoGrid server instance

GoGrid is a cloud service similar to AWS.( http://www.gogrid.com ) Just like Amazon’s AWS EC2, the user starts a virtual server instance from a template and then uses the instance like a dedicated server. The cost is similar to AWS, starting at about $0.10 per hour for a minimal server. The main difference from a user perspective is the addition of Windows servers and an easy to use control panel. The GoGrid control panel provides point and click setup of server clusters with even a hardware load balancer .

The main attraction for me is the availability of virtual Windows Servers. There are several Windows 2003 configuration templates as well as sets of RedHat or CentOS Linux templates:
· Windows 2003 Server (32 bit)/ IIS
· Windows 2003 Server (32 bit)/ IIS/ASP.NET/SQL Server 2005 Express Edition
· Windows 2003 Server (32 bit)/ SQL Server 2005 Express Edition
· Windows 2003 Server (32 bit)/ SQL Server 2005 Workgroup Edition
· Windows 2003 Server (32 bit)/ SQL Server 2005 Standard Edition

The number of templates is more limited than EC2 and I did not see a way to create custom templates. However, this limitation is offset by ease of management. For my experiment I chose the Windows 2003 Server (32 bit)/ IIS/ASP.NET/SQL Server 2005Express Edition. This offered the basics I needed to serve a temporary ASP web application.

After signing up, I entered my GoGrid control panel. Here I can add a service by selecting from the option list.


Fig 2- GoGrid Control Panel

Filling out a form with the basic RAM, OS, and Image lets me add a WebbApp server to my panel. I could additionally add several WebAPP servers and configure a LoadBalancer along with a Backend Database server by similarly filling out Control Panel forms.This appears to take the AWS EC2 service a step further by letting typical scaling workflows be part of the front end GUI. Although scaling in this manner can be done in AWS it requires installation of a software Load Balancer on one of the EC2 instances and a manual setup process.


Fig 3 - example of a GoGrid WebAPP configuration form

Once my experimental server came on line I was able to RemoteDesktop into the server and begin configuring my WebAPP. I first installedthe Microsoft .NET 3.5 framework so I could make use of some of its new features. I then copied up a sample web application showing the use of a GoogleMap Earth mode control in a simple ASP interface. This is a display interface which is connected to a different database server for displaying GMTI results out of a PostGIS table.

Since I did not want to point a domain at this experimental server, I simply assigned the GoGrid IP to my IIS website. I ran into a slight problem here because the sample webapp was created using .NET 3.5System.Web.Extensions. The webapp was not able to recognize the extension configurations in my WebConfig file. I tried copying the System.Web.Extensions.dlls into my webapp bin file. However, I was still getting errors. I then downloaded the ASP Ajax control and installed it on the GoGrid server but still was unable to get the website to display. Finally I went back to Visual Studio and remade the webapp using the ASP.NET Web App template without the extensions. I was then able to upload to my GoGrid server and configure IIS to see my website as the default http service.

There was still one more problem. I could see the website from the local GoGrid system but not from outside. After contacting GoGrid support I was quickly in operation with a pointer to the Windows Firewall which GoGrid Support kindly fixed for me. The problem was that theWindows 2003 template I chose does not open port 80 by default. I needed to use the Firewall manager to open port 80 for the http service. For those wanting to use ftp the same would be required for port 21.

I now had my experimental system up and running. I had chosen a 1Gb memory server so my actual cost on the server is $0.19/hour which is a little less for your money than the AWS EC2:

$0.10Small Instance (Default)
1.7 GB of memory, 1 EC2 Compute Unit (1 virtual core with 1 EC2 Compute Unit), 160 GB of instance storage, 32-bit platform

But again, running ASP .NET 3.5 is much more complex on EC2, requiring a Mono installation on a Linux base. I have not yet tried that combination and somehow doubt that it would work with a complex ASP .NET 3.5 website, especially with Ajax controls.

The GoogleMap Control with the Earth mode was also interesting. I had not yet embedded this into an ASP website. It proved to be fairly simple. I just needed to add a <asp:ScriptManager ID=”mapscriptmanager” runat=”server”/> to my site Master page and then the internal page javascript used to create the GoogleMap Control worked as normal.

I had some doubts about accessing the GMTI points from the webapp since often there are restrictions using cross domain xmlhttpRequests. There was no problem. My GMTI to KML servlet produces kml mime type "application/vnd.google-earth.kml+xml" which is picked up in the client javascript using the Google API:·
geoXml = new GGeoXml(url);

Evidently cross domain restrictions did not apply in this case, which made me happy, since I didn’t have to write a proxy servlet just to access the gmti points on a different server.

In Summary GoGrid is a great cloud service which finally opens the cloud to Microsoft shops where Linux is not an option. The GUI control panel is easy to use and configuring a fully scalable load balanced cluster can be done right from the control panel. GoGrid fills a big hole in the cloud computing world.

Server Side Detour

July 22nd, 2008

Fig 1 - ASP using Ajax ToolKit and LinqDataSource

It has been a while since I used one of the server side web frameworks. Microsoft .NET 3.5 ASP has some attraction, especially since the announcement of SQL Server 2008 geospatial functionality along with Silverlight, WPF, and DeepZoom. There are even hints of a Virtual Earth map element for use in Silverlight. I decided to take a learning detour into ASP Land.

JSP is similar to ASP but never seemed compelling to an individual developer without the division of skill sets found in larger teams. By coding my own servlets instead of deferring to a JSP engine, I found I had more control that translated well into the ping-pong dynamic rendering now called AJAX. My prior experience with server generated html using JSF was not especially fruitful either. Admittedly it was a number of years ago when JSF was quite new, but at that time it was, you might charitably say, “clunky.” The round trips to the server for every little user interaction were not conducive to a good user experience. I guess I didnt find the complexity of a server side JSF layer too compelling, since I could manipulate SVG myself with javascript and send Msxml.XMLHTTP for any parts of my SVG that needed dynamic re-rendering. Now that higher bandwidth is more common, round trips are a bit more responsive but refresh blinks are still noticeable.

With this history in mind I started into ASP land with some reservation.

Microsoft has a very extensive set of tools available for the web developer. The basic ASP controls are all there as well as Linq to SQL, and Ajax Control Kit so ASP has come a lot further than the early days of JSF. The price is a steep learning curve with a wide range of technologies to pull together. Visual Studio 2008 makes a lot of these technologies a matter of drag and drop which means that things are easier to create but more difficult to understand or tweak.

C# is a nice language for pulling all the disparate pieces together, especially since it is so close to Java in syntax and semantics. Stephen Walthers book, ASP .NET 3.5 Unleashed was an invaluable reference for my detour through ASP.

Oversimplified, ASP, like JSP, adds special namespace controls that can be interspersed into normal html. The resulting web form files named with an .aspx extension are dynamically compiled on the server. This server side code in turn is used to create html sent back to the client browser. In addition to Javascript, ASP lets you have a lot of server side control with partial class code-behind created for each aspx page. One nice benefit is that much of the idiosyncrasies between browsers is handled by the compiler instead of the developer.

I was given an opportunity to volunteer for an energy calculator website that required a fairly complex MS SQL Server schema. This was ideal for learning ASP. I was able to adapt the SQL Server Membership capabilities to suit the website requirementsby adding some additional fields to the default aspnet_Users table of ASPNETDB.mdf. Once I had basic registration and login, complete with email notification and role based security, I could move on to the basic web application.

The first iteration involved using the new .NET 3.5 ListView control to create a basic CRUD interface (Create, Read, Update, Delete) to the required tables. ListView is a powerful Control with a great deal of flexibility. It took a little to learn all the ins and outs of events attached to the control, but I eventually had a basic approach worked out. I soon learned that Master pages simplify life considerably. Paying attention to the hierarchy of a sites page layout lets a developer abstract the unchanged into Master pages. As you go deeper into the web application a hierarchy of nested Master pages seemed to work best.

I started building my ListView controls referenced to a SqlDataSource like this:

        <asp:SqlDataSource
            id="electricitysql"
            SelectCommand="SELECT
                    Electricity.*,
                    Locations.locationID,
                    Locations.electricityDeliveryConfigID,
                    energyDeliveryConfig.*,
                    ISNULL(
                        Electricity.monthlycharge/NULLIF(Electricity.units,0),
                        Electricity.monthlycharge
                    ) AS costunit,
                    Electricity.units*energyDeliveryConfig.energyEnvironmentalImpact as co2
                FROM Electricity
                    INNER JOIN Locations ON Electricity.locationID = Locations.locationID
                    INNER JOIN energyDeliveryConfig ON Locations.electricityDeliveryConfigID =
                                      energyDeliveryConfig.energyDeliveryConfigID
                WHERE Electricity.locationID=@locationID ORDER BY billdate ASC;"
            DeleteCommand="DELETE from Electricity WHERE electricityID=@electricityID;"
            InsertCommand="INSERT Electricity (userID, locationID, billdate, units, monthlycharge)
             VALUES (@userID, @locationID, @billdate, @units, @monthlycharge)"
            UpdateCommand="UPDATE Electricity SET billdate=@billdate, units=@units,
               monthlycharge=@monthlycharge WHERE electricityID=@electricityID"

            ConnectionString="<%$ ConnectionStrings:GetPluggedInDB %>"
            Runat="server">
            <SelectParameters>
                <asp:QueryStringParameter Name="locationID" QueryStringField="id" Type="Int32" />
            </SelectParameters>
            <DeleteParameters>
                <asp:Parameter Name="electricityID" Type="Int32"/>
            </DeleteParameters>
            <InsertParameters>
                <asp:Parameter Name="userID" Type="Int32"/>
                <asp:Parameter Name="locationID" Type="Int32"/>
                <asp:Parameter Name="billdate" Type="String"/>
                <asp:Parameter Name="units" Type="Double"/>
                <asp:Parameter Name="monthlycharge" Type="Decimal"/>
            </InsertParameters>
            <UpdateParameters>
                <asp:Parameter Name="billdate" Type="String"/>
                <asp:Parameter Name="units" Type="Double"/>
                <asp:Parameter Name="monthlycharge" Type="Decimal"/>
            </UpdateParameters>
        </asp:SqlDataSource>

 

The complexity of having all this sql inside a web page with additional code behind glue, didn’t appear too concise. Fortunately on further study I realized that ASP .NET 3.5 also has a new technology called LINQ to SQL. Now I could replace the SqlDataSource with a LinqDataSource and make use of all the new ORM tools in VS2008. This is basically just dragging tables from the VS2008 Server Explorer onto a dbml page and then taking advantage of all the automatically created classes that map to the SQL table rows. It meant learning a bit more of Linq query syntax, but it was well worth the effort.

<asp:LinqDataSource
     ID="LinqDataSource1"
     runat="server"
     ContextTypeName="ElectricityDataContext"
     TableName="Electricities"
     EnableDelete="True"
     EnableInsert="True"
     EnableUpdate="True"
     OnInserting="linq_inserting"
     Where="locationID = @locationID AND userID=@userID"
     OrderBy="billdate"
     >
         <WhereParameters>
<asp:QueryStringParameter Name="locationID" QueryStringField="id"
     Type="Int32" />
         	<asp:ControlParameter Name="userID" ControlID="lblUser"
Type="Int32"/>
     </WhereParameters>
</asp:LinqDataSource>

Next on the agenda was delving a bit into AJAX. One requirement of this project was a set of cascading DropDownLists. The selection from the first DropDownList affects the content of the second etc. The content of each DropDownList is populated out of the database. There is a project called the ASP.NET AjaxTool Kit Included in the toolkit is this control, ajaxToolkit:CascadingDropDown, which exactly met the requirements. The ajaxToolkit:CalendarExtender is also much more useable than the simple asp:calendar.

This is quite a bit of capability for actually very little effort. So far I am quite pleased with my foray into ASP .NET land. I did, however, run into one area that caused some delay.

ListView controls are best wrapped in an asp:panel that can have a Scrollbar=”auto” attribute. This allows larger ListView table layouts to have their own scrollbars as needed by the client browser. This all works pretty well. The user can scroll around the table, sort columns, add new records etc. But, when he comes to edit a row that required a scroll, the page refreshes and the next moment the edit row is out of sight with the panel scroll reset to the top of the panel. This is quite confusing to anyone.

The best solution was to add an asp:UpdatePanel with default partial rendering. The UpdatePanel is a quick and dirty approach to AJAX. Any control inside the UpdatePanel <ContentTemplate> becomes an AJAX control with partial rendering happening behind the scenes. In the case of ListView this meant that the Edit command event reset the row layout for editing but did not lose the scroll position. This is nice.

Unfortunately there is a further twist. Scrolling is good to have but really what most would like to see is a fixed header at the top of a scrolling table. Asp controls do not have a nice property for fixed headers of tables inside a Panel control. One solution is setting style=”position:relative;” on the <tr> surrounding the table <th> elements. The header cells are then positioned relative to the top of the table regardless of the scroll position.

This fixes the column headers but the ajax refresh for editing rows will keep the edit row scrolled correctly while throwing the relative head position the scroll amount above its correct location. This is definitely not desirable. I spent a few days searching for some solution and finally came across this approach: Maintain Scroll Position after Asynchronous Postback

    <asp:ScriptManager ID="electrcityscriptmanager"
              EnablePartialRendering="true" runat="server"/>
    <script type="text/javascript">
	    var xPos,yPos;
	    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
	    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
        function BeginRequestHandler(sender, args)
        {
            if($get('<%= DataTableView.ClientID %>') != null){
                xPos = $get('<%= DataTableView.ClientID %>').scrollLeft;
                yPos = $get('<%= DataTableView.ClientID %>').scrollTop;
            }
            else {
                xPos=0;
                yPos = 0;
            }
            //alert(xPos+","+yPos);
        }

        function EndRequestHandler(sender, args)
        {
            if($get('<%= DataTableView.ClientID %>') != null){
                $get('<%= DataTableView.ClientID %>').scrollLeft = xPos;
                $get('<%= DataTableView.ClientID %>').scrollTop  = yPos;
            }
        }
</script>

The BeginRequestHandler is fired prior to the partial render and EndRequestHandler after the rendering. So the workaround involves capturing a current x,y scroll position on the panel before the render is fired and then restoring these after the rendering is completed in order to put things back where they should have been left.

Too bad there is no attribute available for panels like the page attribute: MaintainScrollPositionOnPostback=”true” which only works for the enclosing Page scrollbar and will not affect any interior Panel controls.

Once this bit of workaround was applied my “fixed header Ajax partial rendering ASP ListView Scrolling Table” control with full CRUD was finally working the way I needed. The effort involved was not very substantial and now that I’m further along the learning curve I can replicate this functionality across the entire website. ASP at the very least is a good approach to rapid prototyping.

Next on the agenda is exploring the Mono project to see how much of the ASP world can be forced into a Linux OS. Ultimately it would be very useful to deploy ASP websites in an Amazon EC2 AMI instance for inexpensive scaling. It remains to be seen what problems arise in a Mono based ASP platform.

Google Maps with Google Earth Plugin

June 6th, 2008



Fig 1 - Google Map with Google Earth plugin -

Google announced a new GE plugin for use inside Google Maps:
http://code.google.com/apis/earth/documentation/

This is an interesting development since it allows Google Earth to be used inside a browser. Google’s Map object can be programmed using their javascript api for user interaction control which was not available inside standalone Google Earth. The api documents have plenty of examples but the very simplest way to use the Google Earth Plugin is to simply load their plugin api javascript like this:

<script
	src="http://maps.google.com/maps?file=api&v=2.x&key=**************"
	type="text/javascript">
	google.load("earth", "1");
</script>

Then add a Map Type G_SATELLITE_3D_MAP to the Map control in the initialization code.

function initialize() {
	if (GBrowserIsCompatible()) {
		map = new GMap2(document.getElementById("map_canvas"));
		map.setCenter(new GLatLng(39.43551, -104.91207), 9);
     		var mapControl = new GMapTypeControl();
     		map.addControl(mapControl);
     		map.addControl(new GLargeMapControl());
     		map.addMapType(G_SATELLITE_3D_MAP);
	}
}

This adds a fourth map type, “Earth”, to the control shown over the Google map base.

Fig 2 - Google Map with Google Earth plugin showing map overlays

Now a user can switch to a GE type viewing frame with full 3D camera action. Unfortunately the Maptype control is hidden so returning back to a Map view requires an additional button and piece of javascript code:

function resetMapType(evt){
	map.setMapType(G_NORMAL_MAP);
}

In order to show how useful this might be I added a button to read kml from a url:

function  LoadKML(){
	var geoXml = new GGeoXml(document.getElementById('txtKML').value);
	GEvent.addListener(geoXml, 'load', function() {
		if (geoXml.loadedCorrectly()) {
			geoXml.gotoDefaultViewport(map);
			document.getElementById("status").innerHTML = "";
		}
	});
	map.addOverlay(geoXml);
	document.getElementById("status").innerHTML = "Loading...";
}

Now I simply coded up a servlet to proxy PostGIS datasources into kml for me and I can add mapOverlays to my hearts content. If I want to be a bit more SOA it would be simple to configure a Geoserver FeatureType and let Geoserver produce kml for me.

My LoadKML script lets me copy any url that produces kml into a text box, which then loads the results into the Google Map object. With the GE plugin enabled I can view my kml inside a GE viewer, inside my browser. By stacking these overlays onto the map I can see multiple layers. The javascript api gives me pretty complete control of what goes on. However, there are still some rough edges. In addition to overwriting the map control that would allow the user to click back to a map, satellite, or hybrid view, there are some very odd things going on with the kml description balloons. Since I’m using IE8beta I can’t really vouch for this being a universal oddity or some glitch in the IE8 situation. After all IE8 beta on Vista really does strange things to the Google Map website making it more or less unuseable.

Here are some items I ran across in the little bit of experimetation I’ve done:

  • plugin loading is slow and doesn’t appear to be cached
  • returning from Earth view requires javascript code
  • click descriptions are only available on point placemarks
  • the balloon descriptions show up only sometimes in an earth view
  • There appears to be a limit on the number of kml features which can be added. Over 5000 seems to choke

The rendering in the new Google Earth plugin view is quite useful and provides at least a subset of kml functionality. This evolution distinctly shows the advantage of a competitive market. The Microsoft Google competition significantly speeds the evolution of browser map technology. Microsoft is approaching this same type of browser merged capability as well with their pre announcement of Virtual Earth elements inside Silverlight. 3D buildings, Street view, Deep Zoom, Photosynth, Panoramio …. are all technologies racing into the browser. Virtual parallel worlds are fascinating especially when they overlap the real world. Kml feeds, map games, and live cameras coupled with GPS streams seem to be transforming map paradigms into more or less virtual life worlds.

GIS savvy developers already have a wealth of technology to expose into user applications. Many potential users, though, are still quite unaware of the possibilities. The ramp up of these new capabilities in the enterprise should make business tools very powerful, if not downright entertaining!

More Google Earth - Time Animation

June 3rd, 2008



Fig 1 - Google Earth Time Animation tool visible in the upper part of the view frame -

I was out of town for a trip back to Washington DC the last couple of weeks, but now that I’m back I wanted to play with some more KML features in Google Earth 4.3. One of the more interesting elements offered by KML inside Google Earth is the use of timestamps for animated sequences.
KML offers a couple of time elements:

<TimeStamp>

        <TimeStamp>
	<when>2002-09-27T21:44:41.087Z</when>
        </TimeStamp>

<TimeSpan>

        <TimeSpan>
	<begin>2002-09-27T21:44:41.087Z</begin>
                <end>2002-09-27T21:45:41.087Z</end>
        </TimeSpan>

By attaching a time stamp element to kml rendered elements it is possible to make use of the built in Google Earth time animation tool. I have a table of GMTI events for a few simulated missions that is ideal for this type of viewing. The time stamp deltas are in the millisecond range and work best as timestamp elements.

KML time formats are defined as dateTime (YYYY-MM-DDThh:mm:ssZ) which translates to a Java formatter:

SimpleDateFormat timeout = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

In KML the T char delimits date from time, while the Z indicates UTC. In my case using simulated mission data I am more interested in delta time effects than actual time.

By adding the appropriately formatted <TimeStamp> to each <Placemark> from the GMTI data set I can create a KML data stream with the time animation tool enabled.

<Placemark id="gmti_target.80916">
        <TimeStamp>
          <when>2002-09-27T21:00:06Z</when>
        </TimeStamp>
         <description><![CDATA[<table border='1'>
           <tr>
             <th colspan='8' scope='col'>gmti_target</th>
           </tr>
           <tr>
             <td>targetid</td>
             <td>missionid</td>
             <td>dwellid</td>
             <td>name</td>
             <td>time</td>
             <td>the_geom</td>
             <td>classification</td>
             <td>dwellindex</td>
             <td>trackindex</td>
             <td>geom</td>
           </tr>
           <tr>
             <td>78840</td>
             <td>16</td>
             <td>135417</td>
             <td>gh1_v4bt.cgmti</td>
             <td>75606708</td>
             <td></td>
             <td>Unknown, Simulated Target</td>
             <td>1476</td>
             <td>0</td>
             <td>SRID=4269;POINT(-111.89313294366 35.1604509260505 2180)</td>
           </tr>
           </table>
           ]]></description>
         <LookAt>
            <longitude>-111.89313294366002</longitude>
            <latitude>35.160450926050544</latitude>
            <range>700</range>
            <tilt>10.0</tilt>
            <heading>10.0</heading>
         </LookAt>
         <styleUrl>#Stylegmti_target.634</styleUrl>
         <Point>
            <coordinates-111.89313294366002,35.160450926050544</coordinates>
         </Point>
      </Placemark>

For this experiment I utilized a mission with a relatively small number of gmti targets in the 6000 point range. The time to load is still a bit slow even with only 6000 points to load. In order to boost performance I switched from a simple kml stream to a zipped kmz stream for the servlet response.·····

Response.setContentType("application/vnd.google-earth.kmz");
ZipOutputStream out = new ZipOutputStream(response.getOutputStream());

This helps with bandspeed latency by reducing the data stream from 5Mb to 0.25Mb, however, the biggest latency on my system is the Google Earth load rendering rather than the download. Im using a medium 5Mb DSL connection here on an Intel Core2 Quad CPU Q6600 2.39Ghz. The download of the kmz is about 5sec but the Google Earth ingest and rendering, complete with blanked viewport, is around 50sec.

Once rendered the point icons are available for time sequence animation. Google Earth furnishes a built in tool that automates this process. The time tool includes option settings for adjusting speed, time range view, a setting to keep or discard points from the beginning, as well as repeat, stop, or reverse selection for end of time range event. The animation is helpful for visual analysis of target association. The tool provides step and slider views as well as animation.


Fig 2 - Google Earth time animation

The built in tools provided by Google Earth are quite helpful. Virtual Earth or WPF tools can be used for time sequence as well but require writing the necessary client javascript or C# to step through the set of elements in sequence. Having the tool already available makes simple view animation much easier to create. The potential for customization and interaction is a bit limited, but many applications are well served by the prebuilt viewing tools provided by default in GE. The large terrain and imagery infrastructure behind Google Earth is a real asset to viewing. Additional high resolution imagery can be added as GroundOverlay elements for enhancing specific gmti view areas.

For classification and analysis the simple view capability is somewhat limited. What is needed is a mode of selection to group and classify point data to create track associations. This requires more interactive events than afforded by GE. WPF is more difficult to work with, but the ability to add a variety of selection tools and change classification interactively may make the effort worthwhile from a GMTI analyst’s point of view. Any background imagery, terrain, or mapping layers need to be added to the WPF UI so there would be quite a bit more effort involved.


Fig 3 - Google Earth time animationviewed from above

GMTI is only one of a number of time sequence vehicle tracking data resources. The increasing use of GPS and fleet tracking software makes these types of data sets fairly common. The use of timestamp animation is a nice addition to the viewing capability of historical tracks, of course live tracks generally retain a history tail as well, so a live tracking databases could also make good use of this timestamp element. NetworkLinkControl refresh events can keep the track synchronized with the live data feeds.

The lack of interactive UI capability in Google Earth limits its use for operator classification and analysis. However, GE is just one viewing possibility. A UI system using a FOSS GIS stack such as PostGIS, Java, and Geoserver can be accessed in a number of ways through the browser. For example one browser tool could view the data set through a WPF UI, which allows operator reclassification and filtering using a variety of selection tools, while simultaneously a GE viewer with a NetworkLinkControl refreshed from the serverside backing datastore can be open from the same client. One aspect of the power of Browser based UIs is the ability to access multiple heterogeneous views simultaneously.


Fig 4 - Multiple browser views of gmti data source - WPF xbap UI and GE Time animation

Google Earth 4.3

April 22nd, 2008

Fig 1 - Google Earth Terrain with a USGS DRG from Terraservice as a GroundOverlay

I have to admit that I’ve been a bit leary of Google Earth. It’s not just the lurking licensing issues, or the proprietary application install, or even the lack of event listeners, or accessible api. If I’m honest I have to admit I’m a bit jealous of the large infrastructure, the huge data repository, and the powerfully fun user interface. So this weekend I faced my fears and downloaded the current version, Google Earth 4.3.

I’m not really interested in the existing Google Earth stuff. There are lots of default layers available, but I want to see how I can make use of the cool interface and somehow adapt it as a control for my stuff. The easiest route to customization in GE is KML. KML was developed for XML interchange of Keyhole views before Google bought Keyhole and turned it in to Google Earth. Keeping the KML acronym does avoid some conflict since Keyhole Markup Language, KML, does not run into the namespace conflict with the other GML, OGC’s, that would result from Google Markup Language.

KML 2.2 has evolved much further than a simple interchange language with some features that can be adapted to customized GE applications. After looking over the KML 2.2 reference I started with a simple static KML file. I have a USGS topo index table in PostGIS that I wished to view over the Google terrain. PostGIS includes an AsKML function for converting Geometry to KML. Using Java I can write a JDBC query and embed the resulting geometry AsKML into a KML document. However adding a WMS layer in between the PostGIS and GE seemed like a better approach. Geoserver gives you a nice SOA approach with built in KML export functionality as well as custom styling through sld.

It is easy to set up Geoserver as a WMS layer over the PostGIS database containing my USGS topo index table. Geoserver has also included a KML export format for the WMS framework. So I simply add my table to the Geoserver Data Featuretype list. Now I can grab out a KML document with a WMS query like this:
http://rkgeorge-pc:80/geoserver/wms?bbox=-104.875,39,-104.75,39.125&styles=&Format=kml&request=GetMap&layers=usgstile&width=500&height=500&srs=EPSG:4269

This is simple, and the resulting kml provides a basic set of topo polygons complete with a set of clickable attribute tables at the polygon center points. The result is not especially beautiful or useful, but it is interesting to tilt the 3D view of the GE terrain and see that the polygons are draped onto the surface. It is also handy to have access to the topo attributes with the icon click. However, in order to be useful I need to make my kml a bit more interactive.

The next iteration was to create a simple folder kml with a <NetworkLink>:

<kml xmlns="http://earth.google.com/kml/2.1">
     <Folder>
       <name>USGS Topo Map Index</name>
       <description>
        <![CDATA[
          <h3>Map Tiles</h3>
          <p><font color="blue">index tile of 1:24000 scale <b> USGS topographic maps</b>
           1/8 degree x 1/8 degree coverage</font>
           <a href='http://topomaps.usgs.gov/'>
               more information>>
           </a>
          </p>
      ]]>
     </description>
      <NetworkLink>
        <name>WMS USGS quad tiles</name>
          <Link>
             <href>http://rkgeorge-pc/GoogleTest/servlet/GetWMS</href>
             <httpQuery>layer=usgstile</httpQuery>
             <viewRefreshMode>onStop</viewRefreshMode>
             <viewRefreshTime>1</viewRefreshTime>
             <viewFormat>BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]
                             &CAMERA=[lookatLon],[lookatLat]</viewFormat>
           </Link>
      </NetworkLink>
    </Folder>
</kml>

In this case the folder kml has a network link to a java servlet called GetWMS. The servlet handles building the GetMap WMS query with customized style sld loading so that now I can change my style as needed by editing a .sld file. The servlet then opens my usgstile query and feeds the resulting KML back to the kml folder’s <NetworkLink>. Since I have set the <viewRefreshMode> to onStop, each time I pan around the GE view I will generate a new call to the GetWMS servlet which builds a new GetMap call to Geoserver based on the current bbox view parameters.

This is more interesting and adds some convenient refresh capability, but views at a national or even state level are quickly overwhelmed with the amount of data being generated. The next iteration adds a <Region> element with a <LOD> subelement:

<Region>
  <LatLonAltBox>
    <north>70.125</north>
    <south>18.875</south>
    <east>-66.875</east>
    <west>-160.25</west>
  </LatLonAltBox>
  <Lod>
    <minLodPixels>30000</minLodPixels>
    <maxLodPixels>-1</maxLodPixels>
  </Lod>
 </Region>
</font>

Now my refreshes only occur when zoomed in to a reasonable level of detail. The kml provides a layer of USGS topo tiles and associated attributes from my PostGIS table by taking advantage of the built in KML export feature of Geoserver’s WMS.


Fig 2 - Google Earth with <Region><LOD> showing USGS topo tiles

Unfortunately Google Earth 4.3 seems to disable the onStop refresh after an initial load of my usgstile subset, once a Region element with LOD is added. In GoogleEarth 4.2 I didn’t run into this problem. The work around appears to be a manual refresh of the menu subtree “WMS USGS quad tiles”. Once this refresh is done, pan and zoom refresh in the normally expected ‘onStop’ fashion. GE 4.3 is beta and perhaps this behavior/”feature” will be changed for final release.

Now I have a reasonable USGS tile query overlay. However, why just show the tiles. It is more useful to show the actual topo map. Fortunately the “web map of the future” from four or five years ago is still around “terraservice.net” Terra service is a Microsoft research project for serving large sets of imagery into the internet cloud. It was a reasonably successful precursor to what we see now as Google Map and Virtual Earth. The useful thing for me is that one of the imagery layers that this service provides as a WMS, is DRG, Digital Raster Graph. DRG is a seamless WMS of the USGS topo map scans in a pyramid using 1:250,000, 1:100,000, and 1:24000 scale scanned paper topos. Anyone doing engineering, hiking etc before 2000 is probably still familiar with the paper topo series which, once upon a time, was the gold standard map interface. Since then the USGS has fallen on harder times, but before they fall into utter obscurity they did manage to swallow enough new tech to produce the DRG map scans and let Microsoft load it into TerraService.net.

This means that the following url will give back a nice jpeg 1:24000 topo for Mt Champion in Colorado:
http://terraservice.net/ogcmap.ashx?version=1.1.1&request=GetMap&Layers=DRG&Styles=&SRS=EPSG:4326&BBOX=-106.5625,39.0,-106.5,39.0625&width=1000&height=1000&format=image/jpeg&Exceptions=se_xml

Armed with this bit of WMS capability I can add some more capability to my GoogleTest. First I added a new field to the usgstile database, which can be seen in the screen capture above. The new field simply makes a reference url to another servlet I wrote to build the terraservice WMS query and pull down the requested topo image. By setting the width and height parameters to 2000 I can get the full 1:24000 scale detail for a single 1/8 degree topo quad. My GetDRG servlet also conveniently builds the kml document to add the topo to my Google Earth menu:

<?xml version="1.0" encoding="UTF-8"?></font>
<kml xmlns="http://earth.google.com/kml/2.2">
  <Folder>
    <name>38106G1  Buena Vista East</name>
    <description>DRG Overlay of USGS Topo</description>
    <GroundOverlay>
      <name>Large-scale overlay on terrain</name>
	     <description>
        <![CDATA[
          <h3>DRG Overlay</h3>
          <p><font color="blue">index tile of 1:24000 scale <b> USGS topographic maps</b>
          1/8 degree x 1/8 degree coverage</font>
          <a href='http://topomaps.usgs.gov/'>more information>></a>
          </p>
        ]]>
      </description>
      <Icon>
        <href>http://terraservice.net/ogcmap6.ashx?version=1.1.1&request=GetMap
           &Layers=DRG&Styles=&SRS=EPSG:4326&BBOX=-106.125,38.75,-106.0,38.875
           &width=2000&height=2000&format=image/jpeg&Exceptions=se_blank</href>
      </Icon>
      <LatLonBox>
        <north>38.875</north>
        <south>38.75</south>
        <east>-106.0</east>
        <west>-106.125</west>
        <rotation>0</rotation>
      </LatLonBox>
    </GroundOverlay>
  </Folder>
</kml>

The result is a ground clamped USGS topo over the Google Earth terrain. It is now available for some flying around at surface level in the cool GE interface. Also the DRG opacity can easily be adjusted to see the Google Earth imagery under DRG contours. The match up is pretty good but of course GE imagery will be more detailed at this stage. I also understand that Google is in the process of flying submeter LiDAR through out areas of the USA so we can expect another level in the terrain detail pyramid at some point as well.

This is all fun and hopefully useful for anyone needing to access USGS topo overlays. The technology pattern demonstrated though, can be used for just about any data resource.
1) data in an imagery coverage or a PostGIS database
2) Geoserver WMS/WCS SOA layer
3) KML produced by some custom servlets

This can be extremely useful. The Google Earth interface with all of its powerful capability is now available as a nice OWS interface for viewing OWS exposed layers which can be proprietary or public. For example here is an example of a TIGER viewer using this same pattern:




Fig 3 - TIGER 2007 view of El Paso County Colorado

Google Earth viewer does have a gotcha license, but it may be worth the license cost for the capability exposed. In addition, if Microsoft ever catches up to the KML 2.2 spec recently released as a final standard by the OGC, this same pattern will work conveniently in Virtual Earth and consequently in a browser through a recently announced future silverlight VE element. Lots of fun for view interfaces!

My next project is to figure out a way to use GE KML drawing capability to make a two way OWS using Geoserver transactional WFS, WFS-T.

Deep Zoom Easter Eggs?

March 14th, 2008

Easter rolls around early this year and the MIX08 Deep Zoom announcement made it just in time to try some experiments in the Easter Egg tradition. Using Deep Zoom Composer, images can be inserted at various locations within the zoom pyramid. This means full images of documents, html pages, schematics, data records, photos … can be inserted down at lower levels of a main image’s zoom. This was pointed out in Laurence Moroney’s recent blog posting, which showed an image inserted into the pupil of an eye in a framing picture. Looking at potential for this type of DeepZoom, here is an experiment from a geospatial perspective.



Fig 1 Denver USGS UrbanArea 0.25m zoomed in to make Coors Field visible

The SparseImageSceneGraph.xml generated by Deep Zoom Composer shows how position and insert scale are part of a SceneNode Element:

<SceneGraph version=”1″>
<AspectRatio>0.999999999999994</AspectRatio>
<SceneNode>
<FileName>C:\temp\Denver\denver5\source images\den8×8.jpg</FileName>
<x>0</x>
<y>0</y>
<Width>1</Width>
<Height>1</Height>
<ZOrder>1</ZOrder>
</SceneNode>
.
.
.
<SceneNode>
<FileName>C:\temp\Denver\denver5\source images\taylorbuchholz.jpg</FileName>
<x>0.59990935133569</x>
<y>0.584386453325495</y>
<Width>0.000326534539695684</Width>
<Height>0.000457282456000806</Height>
<ZOrder>8</ZOrder>
</SceneNode>
<SceneNode>
<FileName>C:\temp\Denver\denver5\source images\jeffbaker.jpg</FileName>
<x>0.590298544487025</x>
<y>0.565998027596921</y>
<Width>0.000436734620380339</Width>
<Height>0.000624543890228259</Height>
<ZOrder>9</ZOrder>
</SceneNode>
.
.
.
</SceneGraph>

This brings to mind the various easter egg items available in well known software packages. Interestingly aerial imagery lends itself to this type of feature since the spatial dimension provides a handy reference for hanging additional information.

As an experiment I’ve updated a Denver USGS Urban Area imagery tile with some easter egg information in the Deep Zoom approach. In this case zooming into Coors Field you will notice some small patches scattered around the field. Behind home plate are a couple of informational items from the Colorado Rockies Home page, including a roster list. Then panning around the field you will see various player cards at their field positions.

In each of these cases the image is available at sufficient scale to read the text. The scene graph will allow multiple depth image insertion, so I could go further hiding some detail of a player life inside a dot on an individual player card.


Fig 2 - Zoomed in to see the location of additional SceneNode images


Fig 3 - Zooming further you can read the text and view additional information embedded in the map


Fig 4 - Finally zoomed to an individual player card at short stop.

So far I can see this as little more than a novelty, but perhaps it would have some uses. For example a sitemap builder could be enhanced to output a Deep Zoom image to allow moving around a multipage graph showing every page in a site. This type of tool would be a great way to QC a static html site (are there any of these still around?). Perhaps facility management would benefit as well, since personnel records could be associated with a desk inside an office, inside a building floor, inside an office campus giving a secondary spatial way to review office space. Adding some papers to the desktop and then sending a deepzoom link with the apropriate zoom factor might be a novel approach to document workflow management:
public void ZoomAboutLogicalPoint( double zoomIncrementFactor, double zoomCenterLogicalX, double zoomCenterLogicalY )

In telecom, outside plant items such as transformers and switches could contain schematics embedded within a snapshot of the item, which is itself embedded in a wide area schematic or aerial imagery showing a city wide sector.
The next trick is to find a way to back track through a Deep Zoom Scene graph to a real world coordinate. This seems possible using the pair of methods shown in the MultiScaleImage class:

MultiScaleImage..::.LogicalToElementPoint Method
MultiScaleImage..::.ElementToLogicalPoint Method

Once a coordinate has been reversed into its outer root element coordinates, it should be possible to assign a real world georeference, which would be used for a nearest query on a PostGIS table for obtaining additional attributes or accessing live data.

Which brings up the big problem I see to date on the DeepZoom technology: it is static. The processing of large image sets into pyramids is not fast. Although there are some tantalizing command line hints in the ImageTool.exe and SparseImageTool.exe packaged with Deep Zoom Composer there is no real documentation:

usage: ImageTool [-v] options:
-v enable verbose output
commands:
convert

[outdir ] [basename ] [explode]
[large[tif|jpg|wdp|png] [quality ] [tilesize

]
Converts an image or a dir with files to a Seadragon stored image.
The optional outdir parameter specifies the output directory path.
The optional basename parameter allows overriding the output filesename
which defaults to the basename of the input file.
The default form is single-file (not exploded).
Specify large to use a slower algorithm, but one that can process very large images.
The default format is HDPhoto (wdp).
The quality value should be a number in the interval [0.0-1.0]. Default is 0.8
A quality value of 1.0 will result in lossless compression if possible in the chosen format.
If not specified, tilesize values default to size of 255 and a physical size of 256.
Legal values for tilesize values are >= 64 and <= 2048.dump [levels] [index]
Dumps info about the specified Seadragon stored image file.

extract [] []
Extract level image into specified output directory in
TIFF format. If level is not specified, all are output.
If the output directory is not specified, files are written to
the current working directory.

The possibility of adding smaller items to an already existing large pyramid holds promise for more dynamic real time updating from a content management system.

In looking at the pyramid of jpg files it seems possible to add a simple place holder of the right dimension and then change content by overwriting the already existing pyramid jpgs with updated content. In this way easter egg content with relatively small jpg sets could be updated dynamically out of a content management system on each refresh. If Microsoft SeaDragon adds MultiScaleImage elements to WPF xaml some of the static issues surrounding DeepZoom viewing might be easier to handle.

Deep Zoom a TerraServer UrbanArea on EC2

March 12th, 2008


Fig 1 - Silverlight MultiScaleImage of a high resolution Denver image - 200.6Mb .png

Just to show that I can serve a compiled Deep Zoom Silverlight app from various Apache servers I loaded this Denver example on a Windows 2003 Apache Tomcat here: http://www.web-demographics.com/Denver, and then a duplicate on a Linux Ubuntu7.10 running as an instance in the Amazon EC2, this time using Apache httpd not Tomcat: http://www.gis-ows.com/Denver Remember these are using beta technology and will requires updating to Silverlight 2.0. The Silverlight install is only about 4.5Mb so the install is relatively painless on a normal bandwidth connection.

Continuing the exploration of Deep Zoom, I’ve had a crash course in Silverlight. Silverlight is theoretically cross browser compatible (at least for IE, Safari, and FireFox), and it’s also cross server. The trick for compiled Silverlight is to use Visual Studio 2008 with .NET 3.5 updates. Under the list of new project templates is a template called ‘Silverlight application’. Using this template sets up a project that can be published directly to the webapp folder of my Apache Server. I have not tried a DeepZoom MultiScaleImage on Linux FireFox or Mac Safari clients. However, I can view this on a Windows XP FireFox updated to Silverlight 2.0Beta as well as Silverlight updated IE7 and IE8 beta.

Creating a project called Denver and borrowing liberally from a few published examples, I was able to add a ClientBin folder under my Denver_Web project folder. Into this folder goes the pyramid I generate using Deep Zoom Composer. Once the pyramid is copied into place I can reference this source from my MultiScaleImage element source. Now the pyramid is viewable.

To make the MultiScaleImage element useful, I added a couple of additional .cs touches for mousewheel and drag events. Thanks to the published work of Lutz Gerhard, Peter Blois, and Scott Hanselman this was just a matter of including a MouseWheelHelper.cs in the project namespace and adding a few delegate functions to the main Page initialization code behind file. Pan and Zoom .cs

Now I need to backtrack a bit. How do I get some reasonable Denver imagery for testing this Deep Zoom technology? Well I don’t belong to DRCOG which I understand is planning on collecting 6″ aerials. There are other imagery sets floating around Denver, as well, I believe down to 3″ pixel resolution. However, the cost of aerial capture precludes any free and open source type of use. However, there is some nice aerial data available from the USGS. The USGS Urban Area imagery is available for a number of metropolitan areas, including Denver.


Fig 2 - Same high resolution Denver image zoomed in to show detail

USGS Urban Area imagery is a color orthorectified image set captured at approximately 1ft pixel resolution. The data is made available to the public through the TerraServer WMS. Looking over the TerraServer UrbanArea GetCapabilities layer I see that I can ‘GetMap’ this layer in EPSG:26913 (UTM83-13m). The best possible pixel resolution through the TerraServer WMS is 0.25m per pixel. To achieve this level of resolution I can use the max pixel Height and Width of 2000 over a metric bounding box of 500m x 500m. http://gisdata.usgs.net/IADD/factsheets/fact.html

For example:
http://terraservice.net/ogcmap.ashx?version=1.1.1&service=WMS&ServiceName=WMS&request=GetMap&layers=UrbanArea&srs=EPSG:26913&bbox=511172,4399768,511672,4400268&WIDTH=2000&HEIGHT=2000

This is nice data but I want to get the max resolution for a larger area and mosaic the imagery into a single large image that I will then feed into the Deep Zoom Composer tool for building the MultiScaleImage pyramid. Java is the best tool I have to make a simple program to connect to the WMS and pull down my images one at a time into the tiff format.
try {
File OutFile = new File(dir+imageFileName);
URL u = new URL(url);
HttpURLConnection geocon = (HttpURLConnection)u.openConnection();
geocon.setAllowUserInteraction(false);
geocon.setRequestMethod(”GET”);
geocon.setDoOutput(true);
geocon.setDoInput(true);
geocon.setUseCaches(false);
BufferedImage image = ImageIO.read(geocon.getInputStream());
ImageIO.write(image,”TIFF”,OutFile);
geocon.disconnect();
System.out.println(”download completed to “+dir+imageFileName+” “+bbox);
}

Looping this over my desired area creates a directory of 11.7Mb tif images. In my present experiment I grabbed a set of 6×6 tiles, or 36 tiff files at a total of 412Mb. The next step is to collect all of these tif tiles into a single mosaic. The Java JAI package contains a nice tool for this called mosaic:
mosaic = JAI.create(”mosaic”, pbMosaic, new RenderingHints(JAI.KEY_IMAGE_LAYOUT, imageLayout));

Iterating pbMosaic.addSource(translated); over my set of TerraServer tif files and then using PNGImageEncoder, I am able to create a single png file of about 200Mb. Now I have a sufficiently large image to drop into the Deep Zoom Composer for testing. The resulting pyramid of jpg files is then copied into my ClientBin subdirectory of the Denver VS2008 project. From there it is published to the Apache webapp. Now I can open my Denver webapp for viewing the image pyramid. On this client system with a good GPU and dual core cpu the image zoom and pan is quite smooth and replicates a nice local application viewing program with smooth transitions around real time zoom pan space. On an older Windows XP running FireFox the pan and zoom is very similar. This is on a system with no GPU so I am impressed.

Peeking into the pyramid I see that the bottom level 14 contains 2304 images for a 200Mb png pyramid. Each image stays at 256×256 and the compression ranges from 10kb to 20kb per tile. Processing into the jpg pyramid compresses from the original 412Mb tif set => 200.5Mb png mosaic => 45.7Mb 3084 file jpg pyramid. Evidently there is a bit of lossy compression, but the end effect is that the individual tiles are small enough to stream into the browser at a decent speed. Connected with high bandwidth the result is very smooth pan and zoom. This is basically a Google Earth or Virtual Earth user experience all under my control!

Now that I have a workflow and a set of tools, I wanted to see what limits I ran into. The next step was to increment my tile set to an 8×8 for 64 tifs to see if my mosaic tool would endure the larger size as well as the DeepZoom Composer. My JAI mosaic will be the sticking point on a maximum image size since the source images are built in memory which on this machine is 3Gb. Taking into account Vista’s footprint I can actually only get about 1.5Gb. One possible workaround to that bottleneck is to create several mosaics and then attempt to splice them in the Deep Zoom Composer by manually positioning them before exporting to a pyramid.

First I modified my mosaic program to write a Jpeg output with jpgParams.setQuality(1.0f); This results in a faster mosaic and a smaller export. The JAI PNG encoder is much slower than JPEG. With this modification I was able to export a couple of 3000m x 3000m mosaics as jpg files. I then used Deep Zoom Composer to position the two images horizontally and exported as a single collection. In the end the image pyramid is 6000m x 3000m and 152Mb of jpg tiles. It looks like I might be able to scale this up to cover a large part of the Denver metro UrbanArea imagery.

The largest mosaic I was able to get Deep Zoom Composer to accept was 8×8 or 16000px x 16000px which is just 4000m x 4000m on the ground. Feeding this 143Mb mosaic through Composer resulted in a pyramid consists of 5344 jpg files at 82.3Mb. However, scaling to a 5000m x 5000m set of 100 tif, the 221Mb mosaic, failed on import to Deep Zoom Composer. I say failed, but in this prerelease version the import finishes with a blank image shown on the right. Export works in the usual quirky fashion in that the export progress bar generally never stops, but in this case the pyramid also remains empty. Another quirky item to note is that each use of Deep Zoom Composer starts a SparseImageTool.exe process which continues consuming about 25% of cpu even after the Deep Zoom Composer is closed. After working awhile you will need to go into task manager and close down these processes manually. Apparently this is “pre-release.”


Fig 3 - Same high resolution Denver image zoomed in to show detail of Coors Field players are visible

Deep Zoom is an exciting technology. It allows map hackers access to real time zoom and pan of large images. In spite of some current size limitations on the Composer tool the actual pyramid serving appears to have no real limit. I verified on a few clients and was impressed that this magic works in IE and FireFox although I don’t have a Linux or Mac client to test. The compiled code serves easily from Apache and Tomcat with no additional tweaking required. My next project will be adapting these Deep Zoom pyramids into a tile system. I plan to use either an OWS front end or a Live Maps with a grid overlay. The deep zoom tiles can then be accessed by clicking on a tile to open a Silverlight MultiScaleImage. This approach seems like a simple method for expanding coverage over a larger metropolitan area while still using the somewhat limiting Deep Zoom Composer pre release.

BMNG SilverLight 2.0 Beta Deep Zoom

March 7th, 2008

Well somebody had to do it! Im willing to give it a try.

What is it?

One of the many announcements at the MIX08 conference is the availability of Deep Zoom technology for Silverlight 2.0 Beta 1. This results from an R&D program in Microsoft called Sea Dragon. Sea Dragon was evidently a Microsoft acquisition awhile back. Reminiscent of Keyhole(now google earth), Sea Dragon is a tool for smooth viewing of very large image resources. The novelty is to have it useable inside a SilverLight browser view. http://labs.live.com/Seadragon.aspx

For those so inclined to load beta stuff there is a demo available here with a nice code behind zoom pan capability: http://visitmix.com/blogs/Joshua/Hard-Rock-Cafe/

The idea is that behind the viewport is a large image in PNG, JPEG, TIFF, BMP format which is fed to the screen resolution using a MultiScaleImage element in a SilverLight 2.0 page. Actually just jpeg as it turns out.

Well of course this is extremely interesting to geospatial people since all of the WMS, WCS, WFS, KML, tile caching, image pyramids etc are aimed at exactly this functionality.

How is the user experience?

Holy Mackerel, finally a reason to use Vista! But wait this is SilverLight it should work in FireFox and Safari too. By the way,if any Sea Dragon big Tuna comes trolling by this post I already have my map hacker wishlist for 2.0 at the end of this entry.

OK, let’s try it.

First I grabbed a full resolution BMNG image off of BitTorrent: http://www.geotorrent.org/torrents/61.torrent

Chris Holmes has detailed instructions on this part here: http://docs.codehaus.org/display/GEOSDOC/Load+NASA+Blue+Marble+Data

The eventual result will be twelve large(267Mb) ecw files, “world-topo-bathy-200408-3×86400x43200.ecw,” one for each month of 2004. Ecw is a wavelet compression format for imagery http://en.wikipedia.org/wiki/ECW_(file_format), but to use the image we need it in a different format, Gdal to the rescue. The easiest approach is to take advantage of the FWtools bin directory to run a command line translation like this:

“C:\Program Files\FWTools2.1.0\bin\gdal_translate” -of GTiff world-topo-bathy-200401-3×86400x43200.ecw BMNG.tiff

After a few minutes the result is a tiff image of 86400×43200 of about 11Gb. Now it is time to use the Deep Zoom Composer (actually a decomposer) to process this into a MultiScaleImage info.bin
http://blogs.msdn.com/expression/archive/2008/03/05/download-the-preview-of-the-deep-zoom-composer.aspx

When I attempted an import of this 11Gb tiff into Deep Zoom Composer, the Mermaid.exe choked after a few minutes. I guess we aren’t ready for geospatial scale exactly yet. Note to self: do this with -o Tiff, since mermaids may not like GTiff.

So I went back to a smaller downsample to start my experiment. This time I chose a 3600×1800 png at 4.154Mb. This was rather instant success. Now there is a BMNG test pyramid on my hard drive. The pyramid is 13 levels and each subdirectory contains the necessary images in jpg. Deep Zoom Composer rather handily chunks the tiles in each level, even calculating non square tiling.


Fig 1 Example of the a pyramid level resulting from Deep Zoom Image Composer

After playing around a bit the export spits out what we need for a Silverlight MultiScaleImage. Remember this is an element type introduced with SilverLight2.0 Beta so you can’t really see this unless you want to do a beta Silverlight 2.0 install.

Here are some links on other neat things in R&D over at Microsoft labs.live: http://labs.live.com/photosynth/whatis/

SilverLight works a lot better with an IIS server, but I am using an Apache server, so I created a javascript Silverlight project. Using the default project, I modified the Scene.xaml and associated scene.js to make use of the new MultiScaleImage element:

<MultiScaleImage      
x:Name=msi“      
ViewportWidth=1.0“      
ViewportOrigin=0,0“      
Source=/BMNGZoom/BMNG/info.bin>

This worked pretty well to get the image object in the browser with a sort of spring loaded entre. Perhaps the springy annoyance can be turned off by setting UseSpringsProperty=”off.” However, adding zoom and pan are bit more problematic. I am brand new to Silverlight but oddly there seem to be very few events available:
MouseMove, MouseEnter, MouseLeave, MouseLeftButtonDown, MouseLeftButtonUp

If you want MouseRight, Keyboard, MouseWheel etc, you need to have some code behind. Since I didn’t really have time to figure out all of the code behind tricks for getting this to serve from Apache, I took a primitive approach. By attaching an event to MouseLeftButtonUp I can simulate a click event. Then connecting this click event to the MultiScaleImage ViewportWidth *= 0.9; I could make a one way zoom in without too much effort. Not very useful, but good enough to get a feel for the interaction, which by the way is very impressive. The zooming is familiar to anyone used to VE or GE type of continuous zoom. Pretty nifty for a browser interface.

There is even an ‘old view’ to ‘new view’ animation effect, which cleverly distracts the user while the new tiles are streaming in over the old tiles. Local tile cache makes revisiting very smooth. I will have to try this on an older tier 0 GPU system so I can watch the tiles move slowly into place.

http://www.web-maps.com/BMNGZoom/ >


Fig 2- primitive test of a Deep Zoom BMNG

Now that I had this working on a relatively small 4.1 Mb image, my next step was to step up the size and see what the effect would be. I already knew 11Gb Gtiff was not going to work. Dividing the full Blue Marble into 8 tiles and using PNG output seemed like a possibility. This gives 8 files at 256Mb each.

However, I noticed that the pyramid files are jpeg so why not start with 8 jpeg files instead:
“C:\Program Files\FWTools2.1.0\bin\gdal_translate” -of JPEG
-projwin -180 90 -90 0 world-topo-bathy-200401-3×86400x43200.ecw BMNG1.jpg
Input file size is 86400, 43200
Computed -srcwin 0 0 21600 21600 from projected window.
0…10.

After a few minutes I could open the Deep Zoom Image Composer again and do an import on the full eight tile collection. The composer did not show anything in the view window with these larger jpg images so I was working blind on composition. I did the export anyway out of curiosity.
I’ll post the results next week since it will take a good bit of uploading time.
The result of this bit of experiment was quite surprising. The pyramid building goes fairly smoothly in the Deep Zoom Composer and is painless compared to manually building pyramids in Java. Actually Geotools ImagePyramid has some advantages like iteration over multiple images and command line capability. But the resulting tile pyramid doesn’t have the client side streaming.The MultiScaleImage element hides the complexity of an ajax slippy map interface in a single element. On the down side adding functionality seems to be aimed at IIS ASP type servers. I imagine with a bit of time I can work out the details of a pan and MouseWheel zoom. SilverLight includes RenderTransform matrix capability, it just requires code behind to make it useful with mouse and keyboard functions.

The question is “how does this work?” Of course the answer is “I dont know,” but that doesn’t stop some speculation. The pyramid is obvious. The fact that it works on both a linux or a windows box eliminates a stub socket on the server side. It appears to be an object downloaded to the client which orchestrates things in an ajax mode. Of course clr won’t work with Firefox on Linux or Safari so there must be a plugin object which can be duplicated cross platform.

Wishlist for Deep Zoom 2.0 from a map hacker

1. Can we scale this puppy to use extremely large image sets? I imagine DCOG is going to want to see their 6″ aerials for the Denver metro area in Deep Zoom. Why should they have to come up with a pyramid tile set of MultiScaleImage elements?

2. How about MultiScaleImage elements for WPF xaml/xbap? I would like to use it with a more comprehensive set of code behind tools as an xbap.

3. Once it’s in WPF how about using some OO magic and add MultiScaleImageBrush for draping on a 3D mesh?

Lets extrapolate a couple more steps

4. Why stop at images? How about extending to MultiScale3DMesh. Then my spare time project for an AJAX LiDAR viewer won’t require much work.

5. Don’t stop there, lets have MultiScaleImageBrush on MultiScale3DMesh.

Now sharpen your patent pen

6. Why not MultiScaleVideo? Sooner or later all of the bifocaled baby boomers will be downloading movies to their iPhone, oops ZunePhone. How else are we going to see anything on those miniscule screens. Besides talk about “immersive,” movies could really be interactive. Imax resolution on a phone, why not!