Global Mapper v26.0

Problem with custom elevation layer

dcoggin
dcoggin Global Mapper UserTrusted User
edited July 2012 in SDK
Mike,

I have a strange problem when creating elevation grids with GM_CreateCustomElevGridLayer. After creating a grid I generate a crash (I believe in the call to GM_GetLocationElevation) in my OnMouseMove function. This only happens if I do some combination of zooming and moving the mouse (getting the elevation). It doesn't happen immediately but only happens when zooming and moving -- either alone doesn't affect it. It seems to only happen with very small grids once they are zoomed way out, but it does happen with small or large grids.

I do not have this problem if I read a grid from disk. It also seems strange that if I write the grid to a workspace, and read it back in, I have the same problem -- it crashes when I zoom out and move. When it crashes, Visual Studio shows it is in the call to GetLocationElevation, but I have been unable to make it happen while stepping through in Debug. It does happen in both Debug and Release versions.

The error is a Windows error "<File description> has stopped working", with a Problem Event Name of BEX64 which I read is a buffer overflow. Any ideas? I would think it's all on my end with a memory problem, but it happens when I read the workspace back in also (same workspace works fine in GM13.2). I would appreciate any help or thoughts.

David

Comments

  • global_mapper
    global_mapper Administrator
    edited July 2012
    David,

    What version of the SDK are you using? What does your call to GM_GetLocationElevation look like?

    Thanks,

    Mike
    Global Mapper Guru
    gmsupport@bluemarblegeo.com
    http://www.globalmapper.com
  • dcoggin
    dcoggin Global Mapper User Trusted User
    edited July 2012
    Mike,

    Thanks for the help. My SDK is v1.38, build date is 1/22/12. I also add the float* to a struct I store as LayerUserData. I save the pointer so I can delete the memory if I close the layer. Not sure if that could have anything to do with it. Since that doesn't survive the restoring from a workspace, I wouldn't think it does.

    Thanks again. Here's the code:

    header file:
    static const float m_fNoDataOutput; // No data value when writing elevation grids

    cpp file:
    const float EM_ElevationLayerTools::m_fNoDataOutput = -99999.9;

    member function:
    GM_LayerHandle_t32
    EM_ElevationLayerTools::CreateNewElevLayer_AddAllMesh
    (
    const CString& strNewLayerName,
    const GM_LayerHandle_t32 pCurrentElevLayer
    )
    {
    . . .
    // Function overlays a TIN on a grid. If a cell of the new grid lies in a TIN, it is used for the elevation value.

    GM_LayerHandle_t32
    pNewElevLayer = NULL;
    GM_GridLayout_t8 theGridLayout = GM_GridLayout_Float;
    GM_Point_t thePt;


    // Get dx and dy from grid to copy
    double dDx = (pLayerInfo->mNativeRect.mMaxX - pLayerInfo->mNativeRect.mMinX) / pLayerInfo->mPixelWidth;
    double dDy = (pLayerInfo->mNativeRect.mMaxY - pLayerInfo->mNativeRect.mMinY) / pLayerInfo->mPixelHeight;


    // Grid to copy – row 0, col 0 coord

    pGrid->GridToCoord(0, 0, thePt.mX, thePt.mY); // pGrid is my own grid format used here just for this GridToCoord function

    float* pValues = new float[pLayerInfo->mPixelHeight * pLayerInfo->mPixelWidth];


    for (int nRow = 0; nRow != pLayerInfo->mPixelHeight; ++nRow)
    {
    theErr = GM_GetPixelElevationRow(pCurrentElevLayer,
    nRow,
    pValues + nRow * pLayerInfo->mPixelWidth,
    m_fNoDataOutput);


    for (int nCol = 0; nCol != pLayerInfo->mPixelWidth; ++ nCol)
    {
    if (// calls function to see if this grid row, col (theMeshPt) is in the bdg box of a TIN))
    {
    // This grid cell lies within the bounding box of this mesh
    if (// calls function to see if theMeshPt lies in TIN and if it does assign a z value)
    {
    pValues[nRow * pLayerInfo->mPixelWidth + nCol] = theMeshPt[2] * (*c_elev_conv_it);
    break;
    }
    }


    pNewElevLayer = GM_CreateCustomElevGridLayer(strNewLayerName,
    &pLayerInfo->mNativeProj
    &thePt,
    dDx,
    dDy,
    pLayerInfo->mPixelWidth,
    pLayerInfo->mPixelHeight,
    (void*)pValues,
    theGridLayout,
    m_fNoDataOutput);


    }
    }
    pLayerInfo = NULL;
    pLayerInfo = GM_GetLayerInfo(pNewElevLayer);


    // Now add the elevation values pointer to EM_LayerUserData, a struct I use to track
    // layer data. The elevation pointer is added so I can delete it when closing the layer.

    EM_LayerUserData* pLayerUserData = new EM_LayerUserData();
    pLayerUserData->m_pElevData = pValues;
    pValues = NULL;
    pLayerUserData->m_eElevGridLayout = theGridLayout;

    theErr = GM_SetLayerUserData (pNewElevLayer, static_cast <void*> (pLayerUserData));
  • dcoggin
    dcoggin Global Mapper User Trusted User
    edited July 2012
    Mike,

    I just noticed I should have deleted that break statement. That jumps out of a while loop that's not shown. The while loop is inside all the for loops.

    David
  • global_mapper
    global_mapper Administrator
    edited July 2012
    David,

    I assume the 'break' isn't the cause of your crash though? Since this happens from a workspace as well and as you note that is independent of your code to create the grid, I don't think that's the issue. I would be interested to see what the GM_GetLocationElevation call looks like and also what is being passed in when it crashes.

    Of course I would also recommend updating to the v13 SDK so you can have the latest and greatest, just in case there was something fixed. Nothing jumps to mind though, but I change so much who knows since you are about 6 months back.

    Thanks,

    Mike
    Global Mapper Guru
    gmsupport@bluemarblegeo.com
    http://www.globalmapper.com
  • dcoggin
    dcoggin Global Mapper User Trusted User
    edited July 2012
    Mike,

    First off, when I mentioned the break statement, I just meant that I should have deleted it from the post since I had omitted the while loop in the interest of simplifying the code for posting.

    I didn't think of trying it until I pasted and explained the code, but I just commented out all of the lines where I added the pValues float pointer to the LayerUserData. With that change it works fine and the saved and reloaded workspace looks fine. I will look into that and see if I see why that would be affecting things.

    David
  • dcoggin
    dcoggin Global Mapper User Trusted User
    edited July 2012
    Mike,

    Also, I asked Monday about upgrading my SDK (I got sticker shock when I asked earlier), but the person that handles it is out this week. Hopefully I should be able to get that done next week.

    David