Document directory
- Virtual Earth tile Server
- WorldWind plugins
- WorldWind tiles
- Attempt #1-quadtileset (failed)
- Attempt #2-reproject (SUCCESS)
- Video
- Conclusion
- Source
- Thanks
- Updates
This article will explain how to create a plugin for NASA WorldWind that will induplicate ate Virtual Earth's data. the benefit for WW is that VE provides a great source for maps with multiple views (road, aerial, hybrid ). the benefit for VE is that WW brings the maps into a 3D world with terrain data and other plugins for overlaying other data sources. thanks to NASA for providing a great open so Urce application like WW, and thanks to Microsoft for providing terrifle IC mapping data. I believe MS already provides terraserver data to WW too!
Virtual Earth tile Server
Virtualearth is the backendLocal.live.comAnd it provides between cial and non-commercial cial developer capabilities for adding maps to your web site. The best resource for developing with VE isVia Virtual Earth. The supported development model is to embed a control on your web page and then script against that control. This article doesn't use any of the supported developer hooks-this is a totalHackThat goes directly against the ve tile servers so Microsoft cocould change their protocol for communicating to the tile servers and break this any time they wanted. consider yourself warned. they just recently updated to V2 for the tile servers, so hopefully this will last for at least a little bit. also, MS has allowedVe mobileApplication (by Jason Fuller) to remain in the wild... so that's a good sign.
The first step was to figure out how to request map tiles. one way to reverse engineer this wocould be to sniff the wire with some application like Fiddler when you are browsing local.live.com. instead, I just reverse engineered ve mobile (V2) using Lutz's reflector. to figure out which tile to get, you need to know the row, column, zoom level and map type. the tiles are laid out in rows and columns and there are at least 19 zoom levels (maybe more ). at zoom Level 1, there are only 4 tiles (2 rows, 2 columns) to make up the entire map of the Earth. if you zoom in, then each level 1 tile becomes 4 Level 2 tiles, so Level 2 is made up of 16 tiles (4 rows, 4 columns ). if you keep zooming in, then these numbers get big real quick...
- Zoom level/# of tiles
- 01 4
- 02 16
- 03 64
- 04 256
- 05 1024
- 06 4096
- 07 16384
- 08 65536
- 09 262144
- 10 1048576
- 11 4194304
- 12 16777216
- 13 67108864
- 14 268435456
- 15 1073741824
- 16 4294967296
- 17 17179869184
- 18 68719476736
- 19 274877906944
I told you... big numbers. each tile is 256x256 pixels. the road tiles are. PNG files and the aerial/hybrid map types are. JPEG files. if you want to think about even bigger numbers, then take a guess at what the average size for a 256x256. PNG /. JPEG file is and then multiply that by the # of tiles above! Of course, they can conserve some space by just having a single file for water, etc. also, most of their data is currently for the US. if you zoom in where there is no data, then you'll get the following image:
The row count goes top-down (N-S) and the column count is from left-right (W-E ). the number of rows/columns increases as the zoom level increases. it's also important to know what distance each tile represents. this can be calculated to determineMeters per pixel.
- Zoom level/meters per pixel
- 01 78271.52
- 02 39135.76
- 03 19567.88
- 04 9783.94
- 05 4891.97
- 06 2445.98
- 07 1222.99
- 08 611.50
- 09 305.75
- 10 152.87
- 11 76.44
- 12 38.22
- 13 19.11
- 14 9.55
- 15 4.78
- 16 2.39
- 17 1.19
- 18 0.60
- 19 0.30
This is where I refer you to the Code (Linked In the 'source' section below ). it's pretty easy to start with a lat/lon and then determine what row/COL you shoshould be in. with the row/COL info, then you can generate the URL that is needed to request the appropriate tile. map type comes into play when generating the URL-it effects the URL in a couple places.
One other thing worth noting is the ve tiles are in a Mercator projection. this makes it kind of tricky to bring the data into ww. also, Mercator is no good around the north and south poles. the PIC below was created by stitching together the 4 tiles for Zoom Level 1.
That is all we really need to know about the tile servers.
WorldWind plugins
WorldWind has a pretty powerful plugin model. I just recently used it with/MceworldwindArticle to create three different plugins but I had never attempted to use the model to add an image layer into ww. luckily, the bluemarble layer is implemented as a plugin, so I used it as a starting point. the plugin starts up and creates a form that can be displayed to allow for user input. it also hooks the menubar, the toolbar, and adds image layers to the layermanager. excellent-the ve plugin needs all of that.
WorldWind tiles
So WorldWind also has its own tiling scheme, but its rows start in the south and move up (opposite of VE), while the columns are also west to east. it also supports zoom levels so if you zoom in, then each tile is replaced by 4 tiles for higher resolution. it adds the concept of zerotilesizedegrees which specifies when a certain level will be displayed and determines when Zoom levels change. when you are fully zoomed out, a ztsd of 45 or 36 degrees will work. if you don't want your layer to display at that high of altitude, then you can specify a smaller ztsd. next, the WW globe uses epsg: 4326 (LAT/lon projection) and its mesh is modeled as a perfect sphere. all of this is implemented in the quadtile class.
Attempt #1-quadtileset (failed)
Er, um... so I thought this was going to be easy. it looked like I cocould just reuse the existing quadtileset logic and then create my own imagetileservice to return the appropriate tile server URL. it works by the quadtileset requesting a URL for a tile. in this request it passes the WW row, Col, and level. the imagetileservice uses that to create the appropriate URL to retrieve the right texture and then returns that URL, then the quadtileset downloads that image and uses it as a texture for the mesh.
My first attempt was to create my own imagetileservice. it wocould get the WW row/COL/level and then convert that to the corresponding ve row/COL/level, then that cocould be used to create the ve URL for the tile and magic wowould happen. well... it worked... in theory but I cocould never get things to line up just right. actually, the tiles did line up at the equator, but as you moved north or south (away from the equator), then the tiles were just not lining up correctly. the first problem is that a row of tiles wocould be occasionally skipped. the image below is wrong (I have dyslexic tendencies), but look at 've rowxcol' (which shocould really read colxrow ). if you look at the top tile and then look at the one below it, you'll see that the rows jump from 20 to 22, then it correctly goes to 23 so if that were displaying actual ve tiles, then the map wocould just be wrong-an entire row of images wocould be missing.
I changed things a bit, and made it so that it wocould not skip rows like above, but then the problem was that the map looked right, but nothing was in the right LAT/lon coordinates. e. g: If I went to my own LAT/lon, then the map was showing Canada or Illinois (forget if it was abve or below ?) But it definitely wasn' t Milwaukee. at this point I was pretty convinced that the problem was caused by ve being projected in Mercator. the thought was that WW was creating the meshes for a different projection, And I wasn' t going to be able to request the ve tiles that correctly mapped to those meshes.
Note: I gave up pretty quickly on this technique because I was time boxed by the Virtual Earth madness competition deadline. need to revisit this to fully convince myself. it's quite possible that I was just making a silly mistake and couldn't see it at the time.
Attempt #2-reproject (SUCCESS)
The next step was to take more control. I started out by understanding Mashi's existingMap Projection plug-in. The plugin takes a single image map of the world in sinusoid projection (upside down), and it usesProj.4To reproject into LAT/lon coordinates and render in WW. proj.4 is a library provided by the USGS that converts Cartesian coordinates to/from LAT/lon using different projection techniques. this is almost exactly what I needed. the ve tiles are represented as Cartesian coordinates (in meters) And I Need To reproject into LAT/lon for ww. proj.4 also supports the Mercator projection and spherical ellip SES. Perfect! I started with the core of that codebase and extended it.
The first step was to get a single tile to display. I created my own custom layer by inheriting from renderableobject. for the update method it determines the current Lat, Lon, and zoom level. with that info it can determine which tile to request from the ve tile server. it can also determine the extents of that tile and use proj.4 to create the appropriate mesh, then the render method just has Set the texture and draw the mesh... success! The PIC below shows how closely the tile lines up:
In real life, it wasn' t that simple. the first attempt was real close, but it was about half a tile too high. that error was removed by changing the proj.4 ellipse parameter from 'wgs84 'to 'global', because WW is modeled as a perfect sphere (even though the Earth is a bit squashed ). now it was time to add features...
Tiling-I didn't think I had time to figure out how to insert this new logic into the quadtileset class, so I decided to come up with my own tiling scheme for V1. it works by knowing what tile you are currently focused on and what the zoom level is. from the current tile, it creates neighbor tiles outwards in square patterns. it requests tiles up to 3 rows/Cols out from your current position. if you pan at the same level, then it just has to request the new tiles and dispose of the tiles no longer in view. if you change zoom level, then it requests a whole new set of tiles. the PIC below shows a set of VE tiles being rendered.
Downloading-it uses the WW webdownload class to download the tiles from the ve tile servers. this shoshould support any proxies you have setup (wasn' t able to test this ). also, it lets you see what is happening in the downloadmanager (CTRL-h ). it does not render any progress bar in the lower-right corner, but it does outline currently downloading tiles with a Red Square. the PIC below shows the Download Manager and the red rectangles where tiles were being downloaded.
Caching-it saves the downloaded tiles to disk. PNG or. JPEG files accordingly. if the file has already been cached, then it won't be downloaded again. this improves performance and takes some load off of the ve tile servers. it purposefully does not save. DDS because it is such a large file size and eats up disk space too fast.
Terrain-I had to extend the Code a little for creating meshes, but you can adjust the verticalexaggeration and see the terrain. I consider this one of the primary reasons for adding ve data into WW; 3D is a goodness. the PIC below shows terrain. it's cool to follow the roads through the mountains.
Map types-it can display the road, aerial, and hybrid maps. Hybrid is definitely my favorite. The PIC below shows a top down view of hybrid tiles.
Starting zoom level-this is similar to WW's zeroleveltilesize. you can use this to change when WW tiles start to appear. if you set it to 3, then ve tiles will always display, even if you zoom all the way out. if you set it to a higher zoom level, then ve tiles won't display until you zoom in really close. the PIC below shows ve tiles being displayed at a low starting zoom level.
Locate me-you can click a button to have it zoom in on your location in the world based on IP address. the PIC below shows the ve form for interacting with the ve layer. you can open the form by using the Virtual Earth icon on the toolbar.
Link to local.live.com-if you click this button then it will open a browser showing the same view that you have open in WW. you might do this to see bird's eye imagery. added this in as an afterthought, But it's proven very useful. the PIC below shows a side by side view in WW and local.live.com:
Find address and find business-this code was taken directly from ve mobile. it will add a pushpin for each business found. you can search for a specific location and it will zoom to that location, or it will just search the current visible viewport. the PIC below shows a search for Hooters in Wisconsin:
And you can use the ve map data with created of the other WW plugins that have already been created! I also consider this a primary motivator for getting ve data into ww. The PIC below shows the ve layer in the layer manager and the toolbar icon for opening the ve form.
Not all the features I wanted to get in, but not a bad start for v1.
Video
The following video shows the Virtual Earth maps in WorldWind:
Conclusion
That gives us Microsoft's virtualearth map data in NASA's WorldWind application. it ended up being harder than I originally expected it to be. the plugin is not as polished as I 'd like for it to be, but I'm happy that it works and at least gets V1 out there for others to build on. I worked on this over 3 weekends.
Source
Virtualearthplugin.zip-This is the WorldWind plugin (including code). To install:
- NASA's WorldWindNeeds to be installed. Note: WorldWind requires the. NET and DirectX runtimes to be installed too. The source code is available.
- Copy 'proj. dll 'To where worldwind.exe installed: C:/program files/NASA/World Wind 1.3/proj. DLL. 'proj. DLL is a native DLL used to reproject virtualearth's Mercator map tiles into WorldWind's spherical projection. the original source can be foundHttp://proj.maptools.org/.
- Create 'virtualglobal' plugins folder: C:/program files/NASA/World Wind 1.3/plugins/virtualearth/
- Copy four files to 'virtualglobal' plugin Folder: virtualearthplugin.png, examples, virtualearthplugin. CS, and virtualearthplugin. resx. This our my code. It will automatically be compiled when WorldWind starts up.
- Configure WorldWind to run the Plugin:
- Start 'World wind 1.3 '(EARTH)
- From the menu bar, select 'ins ins'
- 'Load/unload ...'
- Click on 'virtual Earth plugin' text
- Click 'load'
- Select 'startup' checkbox
The PIC below shows the dialog for loading the ve plugin.
You can now zoom in on the earth to see the ve tiles. the default setting is to have the tiles start appearing below an altitude of 300 km. also, the best ve data is currently available for the US.
Vetileapp.zip-This is a small stand-alone winform test app showing how to interact with the ve tile servers.
If you want to step through the code in Visual Studio, you'll need to grab the NASA WorldWind source code and open its solution, then add the code to the/WorldWind project and include the source files in the project. then you shoshould be able to start debugging.
Thanks
I have to thank tons of people on this one:
- Microsoft and virtualearth team for providing the great map data
- NASA and WorldWind team for open sourcing a great application
- Jason Fuller for providing ve mobile that helped me understand the ve tile servers and for the search code
- Adam Hill for pointing me in the right directions when I wocould get stuck with mapping problems
- MS East Regional Platform and evangelism team for motivating me with VE madness
- Mashi for providing the reproject plugin sample... which I never wowould have figured out on my own
- Shockfire for sharing his experience, knowledge of WW classes, and beta testing
- USGS for providing proj.4 reproject Library
- Also bull, dr. Neil, H, m_k, mdsummer, Etc...
Updates
So I 've already written this twice, I'll need some time away before I'm ready to tackle V2. if the WW community wants to take over V2, then that is fine too but I think we shoshould wait a bit before starting... to see what Microsoft's reaction is, because none of this uses supported ve APIs. I 'd really like some sort of good faith nod from MS before starting again (at least that they won't break it that badly ).
Anyway, I cranked this out in a rush, so it definitely needs a rewrite, and we can always add features. The following is a list of possible tasks for V2:
- (Rewrite) replace my custom layer with a modified quadtileset. It will perform better and have better integration to automatically supports alot of features
- (Rewrite) replace my custom pushpins with use of the WW icon class. it provides name, description, and a clickableurl. the clickableurl cocould open a details page for that business in local.live.com. the RegEx from search results wowould need to be slightly expanded
- (Rewrite) replace use of executablepath with plugindirectory.
- (Extend) add different map types (as radio buttons) into the layermanager instead of just the single ve Layer
- (Extend) Save layer settings such as what map type to display and the starting zoom level
- (Feature) try to add bird's eye imagery based on the direction you are facing
- (Feature) Update locate me to also use the WiFi search for better results
- (Feature) 3D driving directions ctions. cocould manually request directions and screenscape the results. Then cocould render lines with altitude and possibly do a fly through the route
- (Feature) transparency to overlay roads on any Layer
- (Bug) There can be small tears between my tiles when rotated to view terrain (pictured below). Use of quadtileset wowould probably fix this
Article contributedCasey chesnut. Have you got somethingContribute?