locked
WPF Bing Maps Control Caching RRS feed

  • Question

  • Is it possible for the Bing Maps control for WPF to preload tiles for certain zoom levels? I'm looking to replace GMap.NET with the Bing Maps control but need to support the application being offline. GMap.NET supports this by telling it to download tiles to a local cache. I only need to support 3 specific zoom levels and only aerial mode.


    • Edited by Tagnarth Saturday, September 3, 2011 7:50 PM
    Saturday, September 3, 2011 7:49 PM

Answers

  • Hi Tagnarth,

    I reflector the assembly of Bing Maps control, and find it download the images from Bing Maps service to the local memory, not the cache folder. Please use the reflector tool to check the internal classes - BitmapImageRequest and  BitmapImageRequestQueue

    The DownloadDataCompleted method of the BitmapImageRequestQueue class:

    [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes"), SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
    private void DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
    {
        Func<KeyValuePair<BitmapImageRequest, WebClient>, bool> predicate = null;
        BitmapImageRequest key = null;
        lock (this.executingRequests)
        {
            if (predicate == null)
            {
                predicate = delegate (KeyValuePair<BitmapImageRequest, WebClient> item) {
                    return item.Value == sender;
                };
            }
            key = this.executingRequests.First<KeyValuePair<BitmapImageRequest, WebClient>>(predicate).Key;
            this.executingRequests.Remove(key);
            this.thereMayBeWorkToDo.Set();
        }
        BitmapImage result = null;
        Exception error = e.Error;
        if (error == null)
        {
            try
            {
                if (e.Result.Length > 0)
                {
                    result = new BitmapImage();
                    result.BeginInit();
                    result.StreamSource = new MemoryStream(e.Result);  // A mempry stream
                    result.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable);
                    result.CacheOption = BitmapCacheOption.None;
                    result.EndInit();
                    result.Freeze();
                }
                else
                {
                    error = new Exception("empty result");
                }
            }
            catch (Exception exception2)
            {
                error = exception2;
                result = null;
            }
        }
        key.Callback(key.UserToken, result, error);
        ((WebClient) sender).Dispose();
    }
    
    

    This forum for the Bing Maps Control for WPF, if you have any problem about this control, please feel free to post here. If you have the concern about using Bing Map API or service, you could choose to post on the http://social.msdn.microsoft.com/Forums/da-DK/vemapcontroldev/threads forum.

    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Jie Bao Monday, September 12, 2011 8:05 AM
    Monday, September 5, 2011 4:30 PM

All replies

  • Well I have half my answer, the control crashes when starting up without a network connection. It throws a NullReferenceException

       at Microsoft.Maps.MapControl.WPF.AerialMode.get_TileUriFormat()
       at Microsoft.Maps.MapControl.WPF.MapMode.EnsureTileSource()
       at Microsoft.Maps.MapControl.WPF.MapMode.AsynchronousConfigurationLoadedSetViewCallback(MapConfigurationSection config, Object userState)
       at Microsoft.Maps.MapControl.WPF.Core.MapConfigurationFromService.ServiceClient_GetConfigurationCompleted(Object sender, GetConfigurationCompletedEventArgs e)
       at Microsoft.Maps.MapControl.WPF.MapControlConfigurationService.MapControlConfigurationServiceClient.OnGetConfigurationCompleted(Object state)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
       at System.Threading.ExecutionContext.runTryCode(Object userData)
       at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.ProcessQueue()
       at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.Run()
       at System.Windows.Application.RunDispatcher(Object ignore)
       at System.Windows.Application.RunInternal(Window window)
       at System.Windows.Application.Run(Window window)
       at System.Windows.Application.Run()
       at BingTest.App.Main() in c:\users\{user}\documents\visual studio 2010\Projects\BingTest\BingTest\obj\x86\Debug\App.g.cs:line 0
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()

    Saturday, September 3, 2011 9:20 PM
  • Hi Tagnarth,

    The answer is "Bing Maps Control for WPF" does not support for caching the data offline. It is a beta version now, perhaps we will get this feature in the future. But if you want to develop with the Bing Maps API, and consult the questions about it, you could try to visit this forum: http://social.msdn.microsoft.com/Forums/da-DK/vemapcontroldev/threads

    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, September 5, 2011 5:31 AM
  • I did find it does cache the images in the temporary internet files once they are downloaded. It's good to know they are cached at least for a while.So by programmatically controlling it to pan through the 3 zoom levels I can get it to cache the images I need too. Still the fact that it crashes at startup if there is no internet connection doesn't help.

    I'll try out the bing maps forum (the documentation for the control pointed to this forum)

    Monday, September 5, 2011 1:01 PM
  • Hi Tagnarth,

    I reflector the assembly of Bing Maps control, and find it download the images from Bing Maps service to the local memory, not the cache folder. Please use the reflector tool to check the internal classes - BitmapImageRequest and  BitmapImageRequestQueue

    The DownloadDataCompleted method of the BitmapImageRequestQueue class:

    [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes"), SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
    private void DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
    {
        Func<KeyValuePair<BitmapImageRequest, WebClient>, bool> predicate = null;
        BitmapImageRequest key = null;
        lock (this.executingRequests)
        {
            if (predicate == null)
            {
                predicate = delegate (KeyValuePair<BitmapImageRequest, WebClient> item) {
                    return item.Value == sender;
                };
            }
            key = this.executingRequests.First<KeyValuePair<BitmapImageRequest, WebClient>>(predicate).Key;
            this.executingRequests.Remove(key);
            this.thereMayBeWorkToDo.Set();
        }
        BitmapImage result = null;
        Exception error = e.Error;
        if (error == null)
        {
            try
            {
                if (e.Result.Length > 0)
                {
                    result = new BitmapImage();
                    result.BeginInit();
                    result.StreamSource = new MemoryStream(e.Result);  // A mempry stream
                    result.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable);
                    result.CacheOption = BitmapCacheOption.None;
                    result.EndInit();
                    result.Freeze();
                }
                else
                {
                    error = new Exception("empty result");
                }
            }
            catch (Exception exception2)
            {
                error = exception2;
                result = null;
            }
        }
        key.Callback(key.UserToken, result, error);
        ((WebClient) sender).Dispose();
    }
    
    

    This forum for the Bing Maps Control for WPF, if you have any problem about this control, please feel free to post here. If you have the concern about using Bing Map API or service, you could choose to post on the http://social.msdn.microsoft.com/Forums/da-DK/vemapcontroldev/threads forum.

    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Jie Bao Monday, September 12, 2011 8:05 AM
    Monday, September 5, 2011 4:30 PM
  • check project GMap.NET/Testing/BingWpfFusion, it's a bing map control using internal gmap.net cache proxy, works perfectly, and you can use easily any map, just change provider id, in the same way, you can use javascript/java
    Thursday, May 9, 2013 11:40 AM