Global Mapper v25.0

Performance issue loading map data

kalden
kalden Global Mapper User
edited February 2010 in SDK
I noticed the global mapper application loads large map files with relative ease. The map loads within a second or two and uses very little memory.

I am using GM_DrawLayerListToMemory to draw map data to a 2048x2048 texture, and for large map files (300MB geotiff), this is taking as long as 10 minutes. I am using the native projection of the map, so no reprojection should be taking place. Any idea why this might be taking so long?

Thanks

Comments

  • global_mapper
    global_mapper Administrator
    edited February 2010
    Do the same maps load and display quickly in Global Mapper? I would expect comparable draw times, of course with an appropriate amount of extra time due to 2048x2048 being larger than the screen, but likely just a linear relationship.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • kalden
    kalden Global Mapper User
    edited February 2010
    Yes. Maps that take minutes for me to load, take seconds for the global mapper application. I understand that my memory buffer is bigger than what is typically displayed in global mapper, but i wouldn't expect such a huge difference in load times
  • global_mapper
    global_mapper Administrator
    edited February 2010
    What version of the SDK are you using? Can you provide me with one of the maps that is taking so long as well as what your call looks like so I can see what is happening?

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • kalden
    kalden Global Mapper User
    edited February 2010
    I will send the map to the global mapper email address.

    GetSDKVersion reports 131


    My code breaks the call into two pieces. We previously had issue with drawing the entire layer in one call. If i comment out the following code, everything loads quickly:
    //Draw the top half of the image    
                   half_bounds = bounds;
                   half_bounds.mMinY += ((half_bounds.mMaxY - half_bounds.mMinY) / 2.0); 
                   err = GM_DrawLayerListToMemory( phMapLst,       // List of layers to draw or NULL for all (&hLayer) / phMapLst
                                                   1,              // Number of layers in list (0 for all)             / nMapLstNum
                                                   m_dwFlags,      // GM_DrawFlags_t32 Flags controlling how the draw is performed
                                                   &half_bounds,        // World bounds to draw or NULL for all
                                                   aColorFormat,   // GM_ColorFormat_t32 Color format
                                                   nWidth,         // Width in pixels to draw
                                                   nHeight / 2,    // Height in pixels to draw
                                                   aTxtr.pBits,    // Buffer to hold output color data
                                                   aTxtr.Pitch     // Width of a single row in the array in bytes
                                                 );
    
                   if (err == 0)
                   {            
                      //Draw bottom half of the image
                      half_bounds = bounds;
                      half_bounds.mMaxY -= ((half_bounds.mMaxY - half_bounds.mMinY) / 2.0);
                      err = GM_DrawLayerListToMemory( phMapLst,       // List of layers to draw or NULL for all (&hLayer) / phMapLst
                                                      1,              // Number of layers in list (0 for all)             / nMapLstNum
                                                      m_dwFlags,      // GM_DrawFlags_t32 Flags controlling how the draw is performed
                                                      &half_bounds,   // World bounds to draw or NULL for all
                                                      aColorFormat,   // GM_ColorFormat_t32 Color format
                                                      nWidth,         // Width in pixels to draw
                                                      nHeight / 2,    // Height in pixels to draw
                                                      ((char*)aTxtr.pBits) + (((nHeight/2)) * aTxtr.Pitch),    // Buffer to hold output color data
                                                      aTxtr.Pitch     // Width of a single row in the array in bytes
                                                    );
                   }
    
  • kalden
    kalden Global Mapper User
    edited February 2010
    I was mistaken about the buffer size. It is actually 8192 x 8192 pixels. I'm not sure that this explains the difference though. I will try using a smaller buffer
  • global_mapper
    global_mapper Administrator
    edited February 2010
    You might also try getting the latest SDK from http://www.globalmapper.com/GlobalMapperSDK_v133_beta.zip. Note that a buffer of size 8192x8192 is about 85 times as large as a typical screen size of 1024x768, so it would take probably around 80 times as long to render.

    Let me know if I can be of further assistance.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • kalden
    kalden Global Mapper User
    edited February 2010
    I agree that we are loading in way more data than can be displayed at any one time, but we are doing this to allow for a seemless zoom capability using directx.

    Something I have discovered is that the behavior is definitely not linear. I can get the map to load in 3 seconds using a 5500x5500 texture. 5600x5600 loads about as slow as 8192x8192. It is possible this is related to the map, but i don't think so since this map is 33384x33267 pixels

    I will try with your new SDK and see what the behavior is like.
  • global_mapper
    global_mapper Administrator
    edited February 2010
    I'm thinking that maybe when the size gets so large the video buffer is somehow stored somewhere different in Windows, perhaps paged to disk, that is a lot slower than normal. That is definitely a very large size for a single offscreen bitmap buffer.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • kalden
    kalden Global Mapper User
    edited February 2010
    Ok, i tried the new SDK and the behavior is the same. You are right though. 5600x5600 is about 478 MB of memory. I have plenty of physical RAM available, but maybe window is hitting a limit for a single application and going to the hard disk anyways.

    The jump from 461 MB to 478 MB for the map buffer seems to exceed some kind of boundary. Maybe it is a fragmentation issue. I'm not sure, but I think I have to rethink my approach.

    Just out of curiosity, does the global mapper application use GM_DrawLayer directly to an HDC? I am assuming then you just re-call the draw function any time you zoom so you basically have a fixed, small display buffer and just modify the bounding box for the map.
  • global_mapper
    global_mapper Administrator
    edited February 2010
    You also have to consider the memory for your buffer as well as the background buffers used internal to the SDK. The GM_DrawLayerListToMemory function will render to an offscreen bitmap, then extract the contents of that into your provided buffer.

    The Global Mapper application does use the Global Mapper SDK interface. The Global Mapper SDK is basically a C interface over the top of a lot of the functionality of Global Mapper. The Global Mapper application directly uses all of the C++ stuff underneath. In Global Mapper everything is drawn to an offscreen bitmap, then that is BitBlt'd to the paint DC. If nothing has changed, that bitmap doesn't need to be rebuilt and draws are basically instant. Otherwise the draw buffer is rebuilt from the loaded data (basically what GM_DrawLayerList does).

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • kalden
    kalden Global Mapper User
    edited February 2010
    I think what I am going to do is use a 2048x2048 texture and when my application zooms in, just call DrawLayerListToMemory again with a smaller map bounding box.

    Thanks for the help.