Welcome to MSDN Blogs Sign in | Join | Help

Bing Maps 3D

As you may be aware, the website changed names to Bing Maps:  http://www.bing.com/maps/.  The 3D view on the site is now called "Bing Maps 3D".

As a developer it doesn't change much for you, and in terms of the engine/SDK it's still valid to refer to it as "Virtual Earth 3D".  The only technical issue I can think of is to repeat that it's a good idea to use fwlinks for the urls for our base layer data, as explained at the end of the post here.

Thanks!

Posted by NikolaiF | 0 Comments

Data Format update and reminder

You may recall that I posted about a data format change for the new version.  The final switch-over is going to happen July 9th.  If you are still using an old version, models will stop displaying.  So upgrade now, the new version is better anyway.

For those already on the new version (assembly version 4), you do not need to change anything at all.

The plus side is that all of you developers have, for reasons of compatibility, been getting the old data for some time now, even if you have upgraded (right now, only Bing Maps gets the new data, everyone else gets the old).  On that date you will automatically start getting the new data, and yes you will notice.

Posted by NikolaiF | 0 Comments
Filed under:

WMS Data

I was having a discussion with Kurt Guenther from Infusion yesterday on the topic of WMS servers and VE3D.  There is a large amount of very interesting spatial data out there served by Web Map Services, or WMS servers.  VE3D is able to process this data using ConnectionParameter-based DataSources.  Setting it up is pretty easy:

ConnectionParameters cp = new ConnectionParameters(http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Portland/Portland_ESRI_Neighborhoods_AGO/MapServer/export?bbox={16},{17},{18},{19}&bboxSR=4326&layers=&layersDefs=&size=256,256&imageSR=102113&format=png&transparent=true&dpi=&f=image);

            string connectionParameters = cp.ToString(); 

            DataSourceLayerData layerData = new DataSourceLayerData(LayerName, Name, connectionParameters, DataSourceUsage.TextureMap);

            Host.DataSources.Add(layerData);

Drop this in to your Activate (plug-in) or Initialized handler (winforms etc) app and fly to Portland, OR to see the data (thanks to ArcGIS for the sample data and Kurt for the pointer).

I won't go into all the details of the WMS spec here, but I will call out a few important parts.  First, in order for this to work you must specify the bbox to be in Geographic coordinates (4326).  This is usually the default.  Second, you must pay attention to the returned projection.  In the above case, we have instructed the server to return 102113, which is Web Mercator, VE3D's native image projection.  This data can be consumed directly with very little overhead.  However, different servers support only certain formats and projections, and you must be careful for any particular server (it is possible to query this using WMS's GetCapabilities).  Nearly all support returning images in Geographic coordinates, 4326.  It is possible to instruct VE3D to reproject this to Web Mercator (this is the only reprojection VE3D will do for you, fortunately it will work for the majority of data).

Now, to look at ConnectionParameters and what it can do for you.  First, there's the big url.  Notice that the bbox has string.Format replacement variables in it:  {16}, {17}, etc.  Requests to the server are made on a per-tile basis (the T key is useful here).  For each request, these variables are replaced with data specific to the tile in question.  Here is a list of available parameters:

0 Reserved

1 Map Style

2 Round-robin integer

3 Reserved

4 Quadkey

5 Extension

6 Generation

7 Stripe (0-3)

8 Tile Host

9 App Host

10 Language code

11 Region code

12 Tile LOD

13 Tile X

14 Tile Y

15 Low order stripe (0-1)

16 MinLong

17 MinLat

18 MaxLong

19 MaxLat

20 RequestToken

21 Culture name

The most interesting ones are 4 (the main quad-key, very useful for already-tiled data), 12, 13, 14, and and 16-19.  To see some of this in action, check out the TerrainImages sample (also available in the sample code of course).  Programatically, you can investigate these values using the TileId class, using GetRequestCode, GetPosition, and GetLatLonBoundingBox.

As for other values on ConnectionParameters, you can control reprojection (if your data is in Geographic, specify CoordinateReferenceSystem = WGS84CoordinateReferenceSystem.Instance, as noted before this is the only reprojection natively supported, so otherwise leave this field uninitialized), the bounds of where the data is valid is terms of Lat/Long and LOD (useful to reducing unnecessary network requests), and caching behavior.

Caching behavior deserves special discussion, because WMS servers are often quite slow.  By default, data loaded using ConnectionParameters is not cached locally.  Once it moves out of memory, it must be re-queried.  If you set CacheRetention however, the data will be kept locally for the period of time specified (unless it is evicted due to space restrictions in the interim).  If you set CacheRetention = new TimeSpan(24, 0, 0), for example, for 24 hours from the time of query a given tile will not be re-queried.  Note that some servers are dynamic, such as weather data, so it's important to use an appropriate value here.

And just to give Kurt a poke in the ribs, please remember to only add DataSources after/during the Initialized event!

 Update:

John Fletcher from Latitude Geographics pointed out that the example I give above isn't actually WMS compliant in its query parameters.  He suggests an alternate sample, of the British Columbia, CA area:

ConnectionParameters p = new ConnectionParameters("http://openmaps.gov.bc.ca/mapserver/libcwms2?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&LAYERS=DBM_7H_MIL_BATHYMETRIC_POLY,BC_LABEL,DBM_7H_MIL_DRAINAGE_LINE,DBM_7H_MIL_DRAINAGE_POLY,DBM_7H_MIL_ROADS_LINE,DBM_7H_MIL_POLITICAL_POLY_PS,DBM_7H_MIL_POPULATION_POINT&STYLES=,,,,,,&SRS=EPSG:4326&BBOX={16},{17},{18},{19}&WIDTH=256&HEIGHT=256&FORMAT=image/png&TRANSPARENT=TRUE&EXCEPTIONS=application/vnd.ogc.se_inimage&");

p.CoordinateReferenceSystem = Microsoft.MapPoint.CoordinateSystems.Wgs84CoordinateReferenceSystem.Instance;

Host.DataSources.Add(new DataSourceLayerData("foo", "bar", p.ToString(), DataSourceUsage.TextureMap));

John also provided a link to the WMS spec repository (http://www.opengeospatial.org/standards/wms).  Note that the sample above is for WMS 1.1.1.  The most current version is 1.3.0, but many servers use the older, or support both.  No matter which you use (or even for something a little off spec like my original example) the interface with VE3D is the same.

Posted by NikolaiF | 0 Comments
Filed under: , , , ,

Modifying cache location

My, it has been a long time since I posted.  I promise I will try to be better.

Recently I was asked if it is possible to change the location of the cache file.  It is, with certain minor restrictions.  You can change the location by adding this to user.config:

      <setting name="PersistentCacheDirectory" serializeAs="String">
        <value>path here</value>
      </setting>

 

Or, when creating the GlobeControl directly, pass in a GlobeControlInitializationOptions object with PersistentCachePath set.

 

In either case, you can either specify a full path to anywhere, or a relative path from the current location (\AppData\LocalLow\Microsoft\Virtual Earth 3D\).

Putting the file outside LocalLow will cause problems when running in IE7/8 protected mode (Vista/Win7 with UAC on).  For a WinForms or WPF-based solution, it’s fine.  In such a case, the GlobeControlInitializationOptions setting is generally preferred as it will prevent problems when running Bing Maps on the same machine.  On the other hand, this will also cause two caches to be written, one in the default location and containing data from runs in Bing Maps, and one in the specified location.  The best approach depends on your exact usage.

 

Posted by NikolaiF | 0 Comments
Filed under: ,

Manual Rendering

Folks have really reacted to my mention of manual rendering, so I've made a sample for it.  Good thing, too, because to be frank there are a few warts.  On the upside, however, it is possible to work around all of them and the code required is not too scary.

Get the code!

In this sample, I host a GlobeControl on a form like normal, but instead of using the built-in render thread I render on the UI thread using the manual render API.  If you are content to let WinForms present to the screen for you, you're done at this point.

But it is common in these situations to want to get the rendered surface to make a movie, present in some other context like WPF, etc.  I include an example of the most basic way to do this, which is the only official way to currently do it (WorldEngine.CaptureScreenShot).  If this isn't good enough, and you're a bit more daring, it is possible to get our rendering surface and do more clever things with it.  That's what the good folks at Infostrat did for their WPF code, and for the time being I actually recommend using their wrapper if you want to use WPF.

I've labelled all the warts and their workarounds with the tag "WORKAROUND" in the code so you can look more closely if you like, but you should also just be able to copy and paste the sample and get your code to work as it should.  Also, this is not actually an an official part of the sample pack, but something similar to it will be.

Anisotropic Filtering

Anisotropic has been a bit of a frustration for us because while it is very easy to do (it's really just a flag to DirectX), the compatibility issue I mentioned before made it a pain to actually get it in to the control.  It's a shame we couldn't turn it on by default, but at least it's there.  The effect of it is really quite dramatic, as you can see below.  I took these images at this location, near the 405 and 90 interchange in Bellevue.

With anisotropic filtering enabled:

Anisotropic filtering

Without:

Trilinear Filtering

To turn it on in the website, click "options" in the upper right corner, then "3D settings", and finally check "Use anisotropic filtering".  To turn it on in code:

plugIn.Host.RenderEngine.Graphics.Settings.UseAnisotropicFiltering = true;

These settings are remembered in the user.config file for future runs of the control.  The perf penalty for this on cards that are even remotely modern is almost zero, so go turn it on now!

Posted by NikolaiF | 3 Comments
Filed under: ,

New Version Released!

Our new version has gone live.  Head on over to maps.live.com and click "3D" to upgrade.  This release is billed primarily as a perf and bug release because it doesn't add a lot of new features at the end-user level (though I think you will be pleased with the perf improvements), but we did have time to throw in some good stuff for the devs.

I've updated the Samples entry, and clicking on the link should get you the new sample set.  As usual, please pass along any problems in comments or blog feedback.  The samples are mostly the same, with a few new additions, but they have been cleaned up for best practices and new features.  I do recommend that you take a glance at them even if you're already familiar with the API.  The Camera sample is most changed, and hopefully should help explain the flow of camera control a little better.

Get the code!

Here's a sampling of new and expanded areas:

Initialized event
 A new event on RenderEngine that simplifies the startup scenario.  Check out SimpleForm to see it.  Remember that use of this event or FirstFrameRendered is now required!

Anisotropic Filtering
 Greatly improves the appearance of terrain when at an angle.  It's off by default, since there are some graphics cards that don't play nice with it (usually old and rare, but still).  You can turn this on through the website in the options box, or you can set it programmatically.  See SimpleForm.

Dem Data
 The ability to supply custom DEM data, and have it automatically stitched into existing data.  Previously DEM datasources did not work very well, mostly because we did not automatically stitch.  They are still a bit trickier than imagery, but there's a new sample DemData to help you out.

ILocationListener
 An interface that allows automatic and efficient query of a location to determine elevation as data changes.  ActorDataSource now uses it.  Essentially, you register this object and report its Lat/Lon position.  If the ground or other solid object moves or changes there, you will get a call to update.

Manual Rendering
 Manual render functions that allow use your own thread as the render thread, good for offline rendering or incorporation into another product.  RenderEngine.ManuallyInitializeRender and ManuallyRenderNextFrame.

Datasource ConnectionParameters
 Helper function for specifying data sources without a content manifest.  The string parameter was very hard to use, this is nicer.  There are also a few new options, like allowing caching of data specified this way.  See TerrainImages.

CelestialStyle
 Allow display of a stylized sky with constellations.  This is used on the website in Road Mode, but you can set it yourself.  See SimpleForm.

Versioning
 Support for running code built against previous control versions, if it meets certain requirements.  I've outlined this in http://blogs.msdn.com/virtualearth3d/archive/2009/04/01/upcoming-new-version.aspx.  To show it working, I've set up a page with samples built from the previous version and from the new version.  Both sets work just fine with the new release.

Pixel-width lines
 GeometryManager supports pixel-width 3D lines (previously only single-pixel or meter-width).  See the Camera sample.  We also now have nice looking text labels.  See the XFile sample.

Constant value datasources
 Helper functions for supplying flat color or elevation data.  The Mandelbrot sample uses one to display flat elevation.  Please note that a DEM and an Imagery datasource are actually required for proper display.  These constant value sources are useful for this case.

Terrain Scaling
 WorldEngine.Min/MaxElevationScaling.  It is actually possible to have varying scale based on your altitude, but there is some cost associated and I recommend that you set the two values equal to each other.  Our default value is 1.0, unscaled.

Override Loading Screen
 You can now render (or suppress) the loading screen (affectionately known as "The Circle Of Hope" since our first version, back when the startup flow was a bit less stable than it is now).  In the very simplest case, write this:

 class MyControl : GlobeControl
 {
    protected override void OnPaintLoading(...)
    {
    }
 }

This will get you a black screen.  You can also grab a reference to the control's Graphics object from the PaintEventArgs and draw anything you like.

Building culling value
 Allows control of how many buildings are displayed, based on distance and size of the buildings.  WorldEngine.BuildingCulling.  The effectiveness of this varies on hardware -- some hardware benefits a great deal, some very little.

Turn on/off street level navigation
 Can turn off some of the special navigation effects that occur when right next to the ground, such as sticking to the ground, and the screen drag regions on the sides of the screen when at low altitude.  WorldEngine.Enable*.


We have not yet updated the docs.  However, we did not make many fundamental changes to the code from an API perspective, and in fact existing code is as much as possible exactly the same.  So it is just lacking detail on the new features, and still a good reference.

Posted by NikolaiF | 13 Comments
Filed under: , ,

Data Format Revision

As part of our version update, we are also updating the file format of our 3D buildings.  The upside is that the new data format is significantly smaller, for faster download.  The downside is that old versions of the code cannot understand the new data.  However, in the short term this should not affect you.  There will be a period where old data will still be served to clients that are using the Javascript API and the Managed API.  This represents a bit of a compromise, because even clients that have updated to the new version will get the old data for this period, but we felt that this was better than releasing new code and breaking old (and existing) code on the same day.

To see the new data after the version update, simply navigate to maps.live.com and click 3D.  The new data will be live on the site.

Once this period is over, clients that have updated will automatically begin receiving the new data without any required changes or interruptions.  You will probably hardly notice, except that buildings of course will load faster.  Clients that have not updated will break!  You've been warned!  The only issue really will be that buildings will not appear, and only if your code is directly adding model data sources.

The exact length of this period is TBD, but probably about a month.  Our hope is that most everyone will update by then anyway, because the new version really is better.  I will blog a reminder when the date is decided and approaching.  As always, let me know if you will need any help during the transition.

In addition, in several samples I directly linked to the manifest files for some resources, like imagery, dem, and models.  These are the urls used when creating DataSourceLayerData objects.  I encourage you to instead use fwlinks, which are just redirects to the same resources.  This will help us update data while minimizing impact to clients.

Road:  http://go.microsoft.com/fwlink/?LinkID=98770
Aerial:  http://go.microsoft.com/fwlink/?LinkID=98771
Hybrid:  http://go.microsoft.com/fwlink/?LinkID=98772
DEM:  http://go.microsoft.com/fwlink/?LinkID=98774
Models:  http://go.microsoft.com/fwlink/?LinkID=98775

Edit:  took down the traffic link.  If you are interested in traffic data, please see here:  http://msdn.microsoft.com/en-us/library/bb877877.aspx

Posted by NikolaiF | 2 Comments

Logging

At times it can be useful to know when and if errors are occurring in VE3D.  When instructed, VE3D produces a log file that can be helpful for diagnosis.  This requires editing the user.config file and adding an entry:

      <setting name="Logging" serializeAs="String">
        <value>True</value>
      </setting>


The user.config file is located at:

(Vista) C:\Users\{username}\AppData\LocalLow\Microsoft\Virtual Earth 3D

(XP) C:\Documents and Settings\{username}\Application Data\Microsoft\Virtual Earth 3D

Log files are generated at:

(Vista) C:\Users\{username}\AppData\LocalLow\Microsoft\Virtual Earth 3D

(XP) C:\Documents and Settings\{username}\Local Settings\Application Data\Microsoft\Virtual Earth 3D

To increase the verbosity of logs, add another entry to user.config:

      <setting name="LoggingLevel" serializeAs="String">
        <value>2</value>
      </setting>

The values are like so:

0:  Critical errors only.  These errors may affect users.
1:  Warnings only.  These are errors that are handled internally and should not affect users.
2:  Informational.  These are not errors, but can be useful in some cases for debugging.

Posted by NikolaiF | 1 Comments
Filed under: ,

Upcoming new version

Next week we'll be releasing a new version of the control.  The focus of the release is on perf and bug fixes, but it also adds a set of interesting new functions for managed code developers.  I'll be posting updated samples, and more detail on the changes, when the control goes public.

But will it break me?

This is of course the biggest question for most devs, and the reason why you're getting a heads up.  We've tried hard to minimize breakage.  The main differences between this update and the previous is that we've maintained binary compatibility for the "public" assemblies, and are also including version redirect assemblies.  The upshot is that if you are only hitting public members in those assemblies, your code should continue to function without a recompile.  If you are hitting other assemblies, you will have to recompile.

Here are the public API assemblies:

Microsoft.MapPoint.Data.dll
Microsoft.MapPoint.Geometry.dll
Microsoft.MapPoint.Rendering3D.dll
Microsoft.MapPoint.Rendering3D.Utility.dll
Microsoft.MapPoint.UtilityPartialTrust.dll

Note that these are also the assemblies accessible to partial trust.

There is one caveat to the compatibility story, and that is startup.  This is significant enough that I posted about it already.  If you haven't looked at this yet please do so.  But overall I think the transition will be easier this time around, and we aim to make that better as we go.

As usual I will be available via the comments section or blog feedback to help with any issues.  Thanks!

Posted by NikolaiF | 1 Comments
Filed under:

WPF and VE3D

I do love having a developer community out there.  We've had lots of requests for direct WPF integration of VE3D, and we've certainly wanted to make it part of the story... and then someone else just goes and does it.  Marc Schweigert called this to me attention yesterday.  Infostrat has taken VE3D and wrapped it up in a WPF control that you can just drop right into your XAML, which is precisely what folks have wanted out of it.

But it gets better.  Infostrat has also put this project, including the source, onto CodePlex under LGPL.  I've downloaded the source and built myself with no problems.  You just need VS 2008 and .NET 3.5 SP1.  The central problem and the trickiest part for most folks is how to efficiently get VE3D to composite into the rest of the WPF app, and they've done a good job.  For more sugar, they also have a Surface version with multi-touch support.

Many thanks to Josh Blake, the primary developer on the project, and the Infostrat team.  Have fun!

Posted by NikolaiF | 2 Comments
Filed under: ,

Multitouch in VE3D

Ever since I got a Touchsmart at home I've been very interested in the desktop touch experience, and so in the last couple days I decided to play with how I could incorporate it into VE3D.  The code itself isn't really ready for consumption, but if you'd like to see where I'm at, I've built a very preliminary plug-in that you can install and play with.

Download

This requires Windows 7 and a machine that has multitouch support, such as a Touchsmart or Latitude XT.  The package is a self-extracting zip, just run it and accept the defaults.  The next time you launch VE3D, the plug-in will load shortly after startup.  There's no UI or anything.  The gestures will just quietly start working.  The plug-in will work on any app that uses GlobeControl (and loads it), but since it calls native code it does require installation.

Currently supported are two-finger zoom and two-finger rotate.  I'm using the built-in gesture engine from Win7, which makes things very easy, but in the future I would like to use direct touch input instead.  This should eliminate a few artifacts like a momentary delay between when you start input and when the map starts moving.  It should also allow support of some more interesting types of inputs, like a two-finger pan, combining rotate and zoom into a single fluid motion, etc.  The point is that there's a lot of potential beyond what I've done here.

The touch interface in Win7 relies on Windows Messages and a few native functions.  To listen to Windows Messages, use Host.CommunicationManager.AttachToMessage.  To interact with the native gesture API, here's something to get you started (this code will work just as well in any managed application).  After that it's a matter of redirecting gestures to existing navigation Actions using bindings.  To really do it right you'd probably also want to write a few things in your own CameraController.

Here's the gesture documentation on MSDN.  Here's the raw touch docs.

Note:  there's a bug in the current GlobeControl where the lParam and wParam values are reversed in the handler to AttachToMessage.  Whoops!  This is fixed in the next version, so be prepared.  I will be releasing my code as a sample at that time, and will update the installer as well.

Note 2:  I noticed on my Touchsmart that the rotate gesture has some trouble when your fingers are diagonal relative to the screen.  I think this is a driver thing, since it doesn't happen on the Latitude XT, which uses a different touch technology and, obviously, different drivers.  However, it looks like they are releasing improved drivers on Windows Update, so I hope this is just a bleeding edge thing.

Edit:  the "Download" link has been updated to a version that is compatible with the current build on Virtual Earth 3D.  Please uninstall the old version first and then install the new one.  Functionality is still the same, that is to say, less than ideal.  From what I have seen, using WM_TOUCH instead of WM_GESTURE will provide a far superior experience.  Stay tuned.

Posted by NikolaiF | 5 Comments

Server transition

Hello all,

I've had a few emails regarding our files being down this weekend.  Sorry I didn't give a heads up earlier, but our backing servers are transitioning to a new host.  They tell me the servers should be back tomorrow morning (3/2/09) at 8am PST.

Sorry for the inconvenience.  I promise all the goodies will be back soon.

Update:  the transition seems to have gone smoothly.  Thanks for your patience.

Posted by NikolaiF | 1 Comments

Startup and Host interaction

When the control first starts, there are several stages that need to complete before it is really ready.

1 Construction.  This occurs when you call GlobeControl's constructor.

2 Initialization on the UI thread.  Some objects can initialize themselves here.  This happens when the control starts receiving windows messages.

3 Initialization on the Render thread.  Other objects need information from the graphics system, which must happen on the render thread to keep DX happy.

4 Start rendering.  The control is now ready to go.

If you start playing with the control before it's done, accessing properties and functions on the various Host objects, you can get bad behavior.  You may get an error, and you may not.  In the current version, there is no validation for this, so you might be fine, or there could be subtle or rare badness.  To get past all of this, you should hook up to the Host.RenderEngine.FirstFrameRendered event and do all of your GlobeControl-related setup there, like adding DataSources and PlugIns, really everything should happen in or after the event.  Properties that derive from Control (the winforms class), such as Height and Width, are ok.

In the next version, we will be validating startup to make sure you don't call most functions until it's ready.  You will be able to access the events on RenderEngine right after construction, but that's all you should do.  There will be a new event, Initialized, to make this process more obvious and logical.

So I encourage everyone to hook up to the FirstFrameRendered event now.  If you're not using it, you may be broken and not realize it.  In the next version, you will definitely be broken.  The FirstFrameRendered event will still be available, and there will not a big difference between it and Initialized, but Initialized will be the best practices way of doing it.

We have tried hard to minimize breaking changes for the next version, and in fact I can't think of any others off the top of my head, but for this we decided it is for the best.

Posted by NikolaiF | 2 Comments
Filed under: ,

Microsoft Photo Calibration Tool

Siddharth Jain, one of the devs on our team, wrote a tool using VE3D to place photos in 3D and save this information as a tag in the file itself.  In short, you open a picture in the program, fly to roughly where the picture was taken from, click on points in the world and in the photo that you know are the same (for example, the chimney of a house, or the edge of a lake), and the program tries to determine where the picture was taken from.  You can then view this picture in the world.

We have a picture that another dev on the team took in Las Vegas for you to play with.  This picture already has some rough information in it to help you get started, and it might be a good idea to start with it.  There's also an image that has already been placed, so you can see how it might look after you're done (load this picture into the tool instead of the first one to see it).  Generally speaking your own photos will probably not have any positioning information in them to begin with, unless you have a very fancy camera, so it is important that you know pretty much where you were when you took it.  Also keep in mind that this is a tool and demonstration, not a finished product.

Here’s Sid’s writeup of the tool.  Enjoy!

Install

Download the zip file and extract its contents to any folder (there is no installer program).  As long as all four dll/exe files are in the same directory it should just run by double-clicking the exe file.

Introduction

The Microsoft Photo Placement Tool can be used to find the geographic coordinates of the camera that took a photo. In this way a photo can be geolocated in the 3D world. There are seven parameters which need to be determined to geoposition a photo in the 3D world. Six of them are latitude, longitude, altitude, roll, pitch, yaw which define the position and orientation of the camera. The seventh parameter is the focal length of the camera that took the photo. The Photo Placement Tool allows determination of these seven parameters via manually specified correspondences between points in the photo and 3D world.

System Requirements

Virtual Earth 3D (VE3D) must be installed on user’s machine.

Usage

On running the exe following screen is displayed:

Startup view

Step 1: User uploads a photo by clicking on Load Image button

Any exif information in the image such as GPS position and focal length is automatically loaded.

Step 2: User navigates in VE3D to a position from where s/he can begin adding correspondences

An example screen is shown below:

Smith tower

Step 3: User turns on calibration by clicking on Turn ON Calibration button

When you are ready to begin adding correspondences, click on the Turn ON Calibration button. This sets the initial camera position and orientation, which is then optimized as correspondences are added.  To get back to step 2, click on the Load Image button again.

Step 4: User adds point correspondences between photo and 3D world

As the user adds correspondences via left mouse click, the tool calibrates the photo in the background. The Preview Result button is automatically enabled after adding 3 or more correspondences. An example is shown below:

Smith correspondences

While in calibration mode it is still possible to navigate in VE3D using the arrow keys, and change the view by holding the shift and ctrl keys while dragging with the mouse. Normal mouse drag is disabled in this mode.

Step 5: Preview the result by clicking on Preview button

When the RMS reprojection error becomes small (say less than 20 pixels), preview the result by clicking on Preview button. The smaller the error, the better the preview would be.

Step 6: Either Accept the result or Revise

User can either Accept or Revise. Clicking on Accept will display the solution and prompt user to save the calibrated photo as a JPEG. The latitude, longitude, altitude, roll, pitch, yaw, and focal length are saved as EXIF tags in the JPEG. Roll, pitch, yaw are relative to the local coordinate system at (lat,lon,alt). All angles (lat, lon, roll, pitch, yaw) are stored in degrees. Next time the photo is opened in this tool, the camera will automatically fly to that location.

By clicking on Revise user can continue to add more correspondences and refine the result. Note that as more correspondences are added, the RMS reprojection error may become better or even worse.

Placed image

Miscellaneous Features

Use Locate feature to quickly fly to a location e.g. New York

Use the Locate button on the Menu to quickly fly to a location e.g. New York

Deleting a pushpin

Move mouse pointer over pushpin. Its color changes. Press delete key to delete the pushpin. Note that deleting a pushpin also deletes the corresponding pushpin, if any, in the other view.

The Settings Window

By clicking on the Settings button, user can control the parameters to optimize. The user would generally not need to change the default settings. However, for completeness the options provided by this window are described here. If the altitude option is unchecked, the tool will not optimize the altitude of the camera. For example, if you took a photo from the ground and have positioned the Virtual Earth 3D camera on the ground, you may want to uncheck the altitude button as the correct altitude has already been set by you. Similarly, if the focal length option is left unchecked, the tool will not optimize the focal length of the camera. You may want to do this, for example, when you are sure that the EXIF focal length is the correct focal length.

Technical Note: user may find that when a calibrated photo is opened, the camera does not fly to the exact calibrated location. Usually when this happens the camera is positioned too high.  This is because the background data in the area, specifically the DEM, is not yet fully loaded, and the program wasn’t able to get to the right spot.  Loading the image again should correct the problem.

Acknowledgements

Bill Chen in VE3D Research originally developed a photo geopositioning tool.  His work can be found here.  The present tool has been developed from scratch and is 100% managed code.  I would like to acknowledge Nikolai Faaland, David Buerer, Bret Mulvey for helping me out on this project. David Buerer provided the Hilton Las Vegas image used in this writeup.  Jonathan Doughi provided the Smith Tower image used in the writeup.

Placed test image

Posted by NikolaiF | 18 Comments
Filed under: ,
More Posts Next page »
 
Page view tracker