Arc ASCII Grid Export header

codemousecodemouse Global Mapper UserPosts: 186Trusted User
edited December 2013 in SDK
Mike,

When I export information to an Arc ASCII Grid file via the GUI, I get a header in the Arc ASCII grid similar to th the following:

ncols 164
nrows 128
xllcorner -116.5440610236
yllcorner 28.9583011811
cellsize 0.016797637795
nodata_value -9999

When trying to do a similar thing programatically, I get the following header:

ncols 164
nrows 128
xllcorner -30.0002340539
yllcorner 59.9997367630
xdim 0.00020590309646876
ydim 0.00026426932853862
nodata_value -9999

When I try to import to ArcMap, I get the message: Invalid Raster Dataset.

Here is essentially how I am calling GM_ExportElevation from c# - any ideas on how to get the desired results?
var filename = "c:\Test.asc";

            var format = GM_ElevationExportFormat_t32.GM_Export_Arc_ASCII_Grid;

//have to force these in, though in GUI i don't select these manually
            var pixelWidth = 164;
            var pixelHeight = 128;

            var flags = GM_RasterExportFlags_t32.GM_ExportFlags_HideProgress;
            
            var elevUnits = = GM_ElevUnits_t8.GM_ElevUnit_Meters;

            var lastGmError = GlobalMapper.GM_ExportElevation(filename, format, _asciiLayerHandle, ref _currentViewRectangle, pixelWidth, pixelHeight, flags, elevUnits);
«1

Comments

  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Both look like perfectly valid Arc ASCII Grid files to me. The one difference I see is that cellsize is used in one and xdim and ydim in the other. This is because your first export has square samples, while your other has samples that are different sizes in the X and Y direction. You would have to adjust your export bounding box and pixel dimensions in your call to get identical X and Y sample spacing values for the 'cellsize' field to be used rather than 'xdim' and 'ydim', although really either one should work fine.

    I presume that your first file works in ArcMap and the 2nd doesn't? If you manually change your second to use 'cellsize' instead of 'xdim' and just delete the 'ydim' line (note this will make the position incorrect, but should be fine for testing), does ArcMap then like the file?

    Let me know if I can be of further assistance.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    Mike,

    Yes - manually changing the second file "worked" (Import to ArcMap successful) though the sizing was wrong.

    So this solution:

    "You would have to adjust your export bounding box and pixel dimensions in your call to get identical X and Y sample spacing values for the 'cellsize'"

    The bounding box is my _currentviewRectangle which I set to the max bounds of the ASCII file layer that I load like so:

    _asciiLayerInfo = (GM_LayerInfo_t)Marshal.PtrToStructure(GlobalMapper.GM_GetLayerInfo(_asciiLayerHandle), typeof(GM_LayerInfo_t))

    _currentViewRectangle.mMaxX = _asciiLayerInfo.mGlobalRect.mMaxX;
    _currentViewRectangle.mMinX = _asciiLayerInfo.mGlobalRect.mMinX;
    _currentViewRectangle.mMaxY = _asciiLayerInfo.mGlobalRect.mMaxY;
    _currentViewRectangle.mMinY = _asciiLayerInfo.mGlobalRect.mMinY;

    Dumb question - how (specifically) do I set in the x/y pixelwidth/height values to GM_ExportElevation to be "even" and avoid xdim/ydim and instead output cellsize?

    Thanks,

    Brian
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Brian,

    The X sample spacing is going to be the width of the bounding box passed in divided by the pixel width minus 1 (same for the Y dimension), so you can calculate the pixel width and height to pass in to get equal X and Y sample spacings for your bounding box. Note that you will probably have to slightly adjust your bounding box since you can't have non-integer pixel sizes.

    If it would make things easier for you, I could add a new export flag to "force square samples", which would adjust your export pixel size automatically for you if passed in.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    Mike,

    I am not opposed to you adding a new flag :). Let me know.

    I will see if I can get this working in the meantime as you suggested. Thanks.

    Brian
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    Mike,

    On a related note to this I am also exporting a GeoTIF and notice I have to pass in pixel width/height values as well. Is there a good way to determine, automatically, a good pixel width/height for the TIF? I know the GUI does something to a certain degree automatically. Let me know thoughts on this one too.

    Brian
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Brian,

    I have completed adding a new flag (GM_ExportFlags_ForceSquareSamples) that will automatically adjust your provided pixel dimensions (and possibly a slight expansion of your export bounds) to make the samples square. I have placed the new SDK build with this flag at http://www.globalmapper.com/GlobalMapperSDK_v134_beta.zip for you to try.

    For the pixel dimensions, if you just have a single layer, call GM_GetLayerInfo and use the mGlobalPixelWidth and mGlobalPixelHeight values to get good pixel dimensions for the layer in the current projection. For more than one layer, Global Mapper calculates the sample spacing (i.e. resolution) of the most detailed layer, then uses that by default for the export, that way you aren't losing any resolution if you use the default settings.

    Let me know if I can be of further assistance.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    Mike,

    Thank you! I was away for
    The weekend - will try this out first thing in the am and report back.

    Brian
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    Mike,

    Something is not quite right - I keep getting GM_Error 8 - nothing to export. Here is my c# code and pinvoke wrapper:
    private GM_LayerInfo_t _asciiLayerInfo;
    private GM_Rectangle_t _currentViewRectangle;
    
    
                var filename = globalMapperParams.ArcAsciiGridFilePath;
    
                var format = GM_ElevationExportFormat_t32.GM_Export_Arc_ASCII_Grid;
    
                var pixelWidth = (int)_asciiLayerInfo.mGlobalPixelWidth;
                var pixelHeight = (int)_asciiLayerInfo.mGlobalPixelHeight;
    
                var flags = GM_RasterExportFlags_t32.GM_ExportFlags_HideProgress | GM_RasterExportFlags_t32.GM_ExportFlags_ForceSquareSamples;
                
                var elevUnits = GM_ElevUnits_t8.GM_ElevUnit_Meters;
    
                var lastGmError = GlobalMapper.GM_ExportElevation(filename, format, _asciiLayerHandle, ref _currentViewRectangle, pixelWidth, pixelHeight, flags, elevUnits);
    
            [DllImport(GlobalMapperDLL, EntryPoint = "GM_ExportElevation")]
            public static extern GM_Error_t32 GM_ExportElevation(string aFilename, GM_ElevationExportFormat_t32 aFormat, IntPtr aLayer, ref GM_Rectangle_t aWorldBounds, int aPixelWidth, int aPixelHeight, GM_RasterExportFlags_t32 aFlags, GM_ElevUnits_t8 aElevUnits);
    

    Any ideas? I'll keep looking..

    Brian
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Brian,

    What do the values in your _currentViewRectangle look like and what about the layer info for your _asciiLayerHandle? Was the _asciiLayerHandle layer loaded so it is a gridded elevation layer?

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    _currentViewRectangle is loaded as follows:

    _currentViewRectangle = new GM_Rectangle_t();
    _currentViewRectangle.mMaxX = _asciiLayerInfo.mGlobalRect.mMaxX;
    _currentViewRectangle.mMinX = _asciiLayerInfo.mGlobalRect.mMinX;
    _currentViewRectangle.mMaxY = _asciiLayerInfo.mGlobalRect.mMaxY;
    _currentViewRectangle.mMinY = _asciiLayerInfo.mGlobalRect.mMinY;

    _asciiLayerInfo is loaded like so:

    _asciiLayerInfo = (GM_LayerInfo_t)Marshal.PtrToStructure(GlobalMapper.GM_GetLayerInfo(_asciiLayerHandle), typeof(GM_LayerInfo_t));

    _asciiLayerHandle well is the layer handle out from loaded ascii layer. here is how i load the ascii layer:

    IntPtr layerHandle;

    var flags = GM_LoadFlags_t32.GM_LoadFlags_HideAllPrompts | GM_LoadFlags_t32.GM_LoadFlags_HideProgress;

    var genericAsciiTextFileImportOptions = new GM_AsciiFormatInfo_t
    {
    mImportType = GM_AsciiImportType_t8.GM_AsciiImport_Elevation,
    mCoordDelim = GM_AsciiCoordDelim_t8.GM_AsciiDelim_AutoDetect,
    mYCoordFirst = 1,
    mIncludeCoordAttrs = 0,
    mColumnHeadersInFirstRow = 0,
    mIncludeElevCoords = 1,
    mColumnsToSkip = 0,
    mCoordLinePrefix = String.Empty,
    mAreaType = AreaFeatureClass_t16.AFC_UNKNOWN,
    mLineType = LineFeatureClass_t16.LFC_UNKNOWN,
    mPointType = PointFeatureClass_t16.PFC_UNKNOWN,
    mIgnoreZeroElevations = 1,
    mFillToBounds = 0,
    mOffsetX = 0,
    mOffsetY = 0,
    mOffsetZ = 0,
    mScaleX = 1,
    mScaleY = 1,
    mScaleZ = -1,
    mNoDataDistanceFactor = 0.0,
    mBreakOnColumnIdx = IntPtr.Zero
    };

    var lastGmError = GlobalMapper.GM_LoadGenericAsciiTextLayer(globalMapperParams.AsciiDepthFilePath, out layerHandle, flags, ref genericAsciiTextFileImportOptions, ref _projection);
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    if i need to load a gridded layer, how would i go about doing that?
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Actually your use of GM_AsciiImportType_t8.GM_AsciiImport_Elevation would cause the data to be gridded on import. If you draw the ASCII layer does it draw as an elevation layer?

    Your assignment of the bounding rectangle looks fine as well. Can you perhaps post a screenshot or else list of the values in the GM_LayerInfo_t structure for your ASCII layer so that I can verify that all looks ok?

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    how's this? :)
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Actually I think the forum automatically shrunk your JPG so it is basically unreadable. From what little I could make out it looks like there may be some alignment issues with your GM_LayerInfo_t declaration, but I can't tell for sure. Can you post your GM_LayerInfo_t declaration and maybe email the screenshot to support@globalmapper.com?

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    public struct GM_LayerInfo_t
    {
    public string mDescription; // Description string
    public GM_Rectangle_t mNativeRect; // Bounding rect of layer in native coordinates
    public GM_Rectangle_t mGlobalRect; // Bounding rect of layer in global coordinates
    public uint mPixelWidth; // RASTER/ELEV ONLY: Number of pixels wide layer is
    public uint mPixelHeight; // RASTER/ELEV ONLY: Number of pixels tall layer is
    public GM_Projection_t mNativeProj; // Native projection of layer
    public IntPtr mControlPoints; // RASTER ONLY: Ground control points list. Point to GM_GroundControlPoint_t
    public uint mNumGCPs; // RASTER ONLY: Number of ground control points in list
    public float mMinElevation; // ELEV ONLY: Minimum elevation in meters
    public float mMaxElevation; // ELEV ONLY: Maximum elevation in meters
    public uint mNumAreas; // VECTOR ONLY: Number of area features
    public uint mNumLines; // VECTOR ONLY: Number of line features
    public uint mNumPoints; // VECTOR ONLY: Number of point features
    public double mPixelSizeX; // RASTER/ELEV ONLY: Pixel size in meters in the x direction
    public double mPixelSizeY; // RASTER/ELEV ONLY: Pixel size in meters in the y direction
    public byte mHasRasterData; // Does this layer have raster or elevation data?
    public byte mEnabled; // Is this layer enabled for display or it it hidden?
    public byte mHasVectorData; // Does this layer have vector data (the features counts can all be 0 for things like map catalogs)
    public byte mUsedDefaultPos; // RASTER/ELEV ONLY: Was the default position used for this layer since the file could not be automatically positioned?
    public string mFilename; // Filename from which layer was loaded (if this is an archive file, like .zip, then the name of the actual loaded file will be in mArchiveFilename
    public string mArchiveFilename; // Filename within archive file (e.g. .zip or .tar.gz) from which layer was loaded, if any (might be NULL)
    public string mTypeName; // Layer type name
    public uint mGlobalPixelWidth; // RASTER/ELEV ONLY: Approximate number of pixels required in width for a 1:1 pixel mapping in the current projection
    public uint mGlobalPixelHeight; // RASTER/ELEV ONLY: Approximate number of pixels required in height for a 1:1 pixel mapping in the current projection
    public IntPtr mMetadataList; // List of metadata attributes and values for the layer
    public uint mMetadataListSize; // Number of entries in mMetadataList
    public uint mNumBands; // Number of bands in a raster image (use GM_SetRasterDisplayOptions to change color band layout)
    public string mExtraLoadFlags; // Additional load flags with options selected by user during load. Pass these to GM_LoadLayerListEx to remember options.
    public GM_PaletteEntry_t mPalette; // List of palette entries for palette-based raster layer
    public uint mPaletteSize; // Number of entries in palette list
    public IntPtr mUserData; // Custom data associated with layer provided by user via GM_SetLayerUserData function
    public GM_ElevUnits_t8 mElevUnits; // Elevation units for layer
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Brian,

    I'm not seeing anything obviously wrong. To get the error code you are getting either the layer being passed in isn't recognized as an elevation layer (it appears to be correct based on your load) or else the export bounding rectangle provided is either empty or the layer passed in doesn't intersect it. Can you check the values of the bounding box being passed in just before you call the GM_ExportElevation function and make sure they look ok there?

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    Mike,

    If I take out that new flag you created, the process works fine just like before - and all of my other functions work as they once did as well.

    What is that new GM_RasterExportFlags_t32.GM_ExportFlags_ForceSquareSamples looking for now that I may not be passing in to complain of error 8? I'll keep looking but I can definitely product an Arc ASCII grid without that flag just like before - if for some reason my pixel height and depth are the same, it will even produce a header without separate x/y dims and just do cellsize like the following:

    ncols 128
    nrows 128
    xllcorner -30.0002632370
    yllcorner 59.9997367630
    cellsize 0.00026426932853865
    nodata_value -9999
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Ah I totally missed that you were using that new flag. I took a look and found that the flag caused the bounding box to be messed up half the time. I have placed a new build at http://www.globalmapper.com/GlobalMapperSDK_v134_beta.zip which should fix this.

    Let me know if I can be of further assistance.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    Mike,

    Seems like no change - still Error 8.

    Brian
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Brian,

    Can you check the time stamp on the GlobalMapperInterface.dll file that you are using? I'm guessing maybe you got a cached version of the new SDK built download that didn't have the update.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    9/15/2010 10:45AM for GlobalMapperInterface.dll in bin (32-bit)
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Brian,

    Hmmm that sounds right, can you provide me with a list of the parameter values (the bounding box in particular) that are being passed in so that I can pass those in and see what happens?

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    just emailed you.
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    Let me know what I may be missing here - like I said, remove the flag, things go fine. Same data.
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    i'm baffled... been trying several different things with no luck. any desire to do a goto meeting or teamviewer session to check this out? it's curious...
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    I was out of the office all afternoon and just returned. I will take a look shortly and debug in to see what I can find.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Ah found the problem right away debugging. Looks like I just fixed the "force square samples" flag for the GM_ExportRaster function and not the GM_ExportElevation function as well. I have placed a new build at http://www.globalmapper.com/GlobalMapperSDK_v134_beta.zip for you to try.

    Let me know if I can be of further assistance.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    Mike,

    Good news bad news! Good news is yes it works! Bad news is that when I compare programatically generating it vs. using the GUI the ASC files are not the same. Here is the Programatic output header:

    ncols 129
    nrows 128
    xllcorner -30.0002632370
    yllcorner 59.9997367630
    cellsize 0.00026426932853862
    nodata_value -9999

    Here is the GUI output header (same data):

    ncols 128
    nrows 128
    xllcorner -30.0001311024
    yllcorner 59.9998688976
    cellsize 0.0002622047244094
    nodata_value -9999

    Any thoughts? I know you said you forced the bounding box to maybe be bigger but I think something simpler is at play here - let me know what you think. Thank you again.

    Brian
  • global_mapperglobal_mapper Administrator Posts: 17,238
    edited September 2010
    Brian,

    I think the issue is the bounding rectangle that you are passing in. The GM_ExportElevation function expects an export rectangle from grid cell center to grid cell center, but the mGlobalRect from the layer info goes from the outer edge of the left-most pixel to the outer edge of the right-most pixel, so it's one sample spacing larger. I think if you shrink your export rectangle by one half of the sample spacing of the layer then you will get the bounds that you want to match what the GUI gets you.

    Let me know if I can be of further assistance.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemousecodemouse Global Mapper User Posts: 186Trusted User
    edited September 2010
    This makes sense. How would I grab the sample spacing of the layer? If the global and regular pixel heights and widths of the layer info are all 128, and then the mPixelSizeX is 14.561431375161227, and the mPixelSizeY is 29.212902308711136, and the original sample spacing of the import file was 2.0 minutes.

    I'm going to think this through as well, but just in case you have a faster answer.

    Brian
Sign In or Register to comment.