Howto create image from RadMap without showing the RadMap

7 posts, 0 answers
  1. Janko
    Janko avatar
    9 posts
    Member since:
    Sep 2012

    Posted 13 Sep 2019 Link to this post

    I use a very general image creation method to create multiple images for a report.
    This method doesn't yet work with RadMap because there are unfinished animations (Zooming, ...(?)) and the OpenStreetMap data isn't loaded and shown yet

    Questions:
    1) Can I disable the RadMap animations and get an eventcall when the map loading and creation process is finished?
       Or is there even a better way to implement it?
    2) Is it possible to use something like a cache for the openStreetMap data during my report creation
    3) Is it possible to use the OpenStreetMapProvider offline?


    image creation method:
    var outerGrid = CreateNewViewAndSetDataContextCreateViewInGrid(myDataContext);
    outerGrid.Width = width;
    outerGrid.Height = height;
    outerGrid.Measure(new Size(width, height));
    outerGrid.Arrange(new Rect(0, 0, width, height));
    outerGrid.UpdateLayout();
    var renderTargetBitmap = new RenderTargetBitmap(
       (int)width,
       (int)height,
       96,
       96,
       System.Windows.Media.PixelFormats.Pbgra32);
    renderTargetBitmap.Render(outerGrid);
    var bitmapEncoder = new PngBitmapEncoder();
    bitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
    return bitmapEncoder;



    RadMap Code:
    <telerik:RadMap x:Name="Map" MiniMapExpanderVisibility="Collapsed">
        <telerik:RadMap.Provider>
            <telerik:OpenStreetMapProvider x:Name="MapProvider"/>
        </telerik:RadMap.Provider>
        <telerik:VisualizationLayer x:Name="LayerInMap"/>
    </telerik:RadMap>


    RadMap Code Behind:
    this.DataContextChanged += /* set map properties. e.g. fill visualization layer with charts */

  2. Vladimir Stoyanov
    Admin
    Vladimir Stoyanov avatar
    636 posts

    Posted 18 Sep 2019 Link to this post

    Hello Janko,

    Thank you for the provided code snippets. 

    I will go straight to your questions:

    1) Can I disable the RadMap animations and get an eventcall when the map loading and creation process is finished?
       Or is there even a better way to implement it?

    You can try the Loaded event of the RadMap and you can also use a Dispatcher with a lower DispatcherPriority in order to make sure that everything is loaded. 

    2) Is it possible to use something like a cache for the openStreetMap data during my report creation

    3) Is it possible to use the OpenStreetMapProvider offline?

    To address both 2) and 3) together, you can check out the following threads for more information on the topic of caching and offline usage: 

    Offline Map Server

    Offline TiledMapProvider

    I hope you find this helpful.

    Regards,
    Vladimir Stoyanov
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  3. Jason D
    Jason D avatar
    128 posts
    Member since:
    Jan 2011

    Posted 16 Dec 2019 in reply to Janko Link to this post

    A little late, but if you want an image of the map *as-is* on the screen, you can use this extension method:

    Telerik.Windows.Media.Imaging.ExportExtensions.ExportToImage

    If you are creating the map in code and never show it on screen, I don't know if you can use this method because I don't know if the map will render.

  4. Janko
    Janko avatar
    9 posts
    Member since:
    Sep 2012

    Posted 03 Feb Link to this post

    Sorry for not answering. Now I'm back :)

    I managed the offline behavior.

    But I failed to disable all animations and I failed detecting when the map is loaded (when it isn't available offline) and correctly shown in GUI.


    Here is what happened when I tried the suggestions mentioned here:

    >You can try the Loaded event of the RadMap
    This is only called once at the beginning and then never again.

    >you can also use a Dispatcher with a lower DispatcherPriority
    That didn't work. I receive a callback from Dispatcher with SystemIdle priority before all the new image data is loaded from the internet (and shown). This was tested by changing the position in the map with the mouse.

    >Telerik.Windows.Media.Imaging.ExportExtensions.ExportToImage
    I also tried that. But it is just a snapshot and results in a wrong picture if the map data is not yet loaded

    Here is what I also tried:

    - Ideally, I would like to take the picture immediately after setting the DataContext and calling UIElement.UpdateLayout(). (see code in my topmost post). But then I have an additional problem with the RadMap (besides an unloaded map): The map looks max zoomed out (i.e. all pinpoints are at the same position) and only later it would zoom into the correct position, which is too late.
    Therefore I tried to disable all the animations. But disabling of AnimationManager and setting of Map.UseSpringAnimations wasn't enough to change the result image.
    Do you have an idea how to tell the RadMap that it has to start with the correct zoom?

    - I subscribed to the public events listed in RadMap, but none was raised at the moments that I needed.


    Do you have any other suggestions?
  5. Jason D
    Jason D avatar
    128 posts
    Member since:
    Jan 2011

    Posted 03 Feb in reply to Janko Link to this post

    I use Vladimir's Dispatcher suggestion in my app (but I don't print the map in a report). I also use it for a different WPF component that I need to wait for rendering to finish before I can include it in a PDF. Try using different priorities. I usually use ContextIdle or ApplicationIdle.

    For whatever reason, I also use a variety of different dispatchers. I think there are only 2 dispatchers in reality but not sure:

    System.Windows.Application.Current.Dispatcher.Invoke

    Windows.Threading.Dispatcher.CurrentDispatcher.Invoke

    or the dispatcher of the current WPF object

  6. Janko
    Janko avatar
    9 posts
    Member since:
    Sep 2012

    Posted 03 Feb in reply to Jason D Link to this post

    The SystemIdle priority that I mentioned above is already the lowest priority one can subscribe to. Therefore trying another priority cannot help (correct me if I'm confused here).
    But I already tried it when I wrote my previous post. In my test I called Dispatcher.BeginInvoke for all allowed DispatcherPriority-values including ContextIdle, ApplicationIdle and SystemIdle whenever the position in the Radmap changed. And sometimes the new mapdata was only shown after I received all callbacks from the Dispatcher.
    Therefore the Dispatcher can be SystemIdle when the RadMap waits for the images from the internet.

    >For whatever reason, I also use a variety of different dispatchers.
    Fortunately, I didn't need that yet.  I only use the Application's Dispatcher. Maybe I will need that for the RadMap. But then I still need an event that tells me when the the data of the map provider is loaded+shown.

  7. Vladimir Stoyanov
    Admin
    Vladimir Stoyanov avatar
    636 posts

    Posted 05 Feb Link to this post

    Hello Janko,

    Thank you for the updates. 

    Indeed you are correct that the SystemIdle priority is the lowest one. That said, I am afraid that I cannot think of another suggestion based on the provided information.

    May I ask you to prepare a sample project demonstrating your scenario and send it over in a new support ticket (since project files cannot be attached to forum posts)? This will allow me to investigate and hopefully assist you further.

    Thank you in advance for any help you can provide.

    Regards,
    Vladimir Stoyanov
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Back to Top