Global Mapper Pro

Load Generic ASCII File into Layer - C#

codemouse
codemouse Global Mapper UserTrusted User
edited August 2010 in SDK
Trying to load an ASCII file into a layer. Can accomplish this easily within the GUI, having issues utilizing the SDK via C# to achieve these results. Here is where I am at (I've encapsulated the SDK a little differently - broken it apart, but same concept as sample SDK code):
var filename="c:\\test.asc";

IntPtr layerHandle;

var flags = GlobalMapperDLL.GM_LoadFlags_t32.GM_LoadFlags_HideAllPrompts;

var asciiFormatInfo = new GlobalMapperDLL.GM_AsciiFormatInfo_t
                                      {
                                          mImportType = GlobalMapperDLL.GM_AsciiImportType_t8.GM_AsciiImport_Elevation,
                                          // specify import type
                                          mCoordDelim = GlobalMapperDLL.GM_AsciiCoordDelim_t8.GM_AsciiDelim_AutoDetect,
                                          // sepcify coordinate delimeter
                                          mYCoordFirst = 1,
                                          // is Y coordinate first or X coordinate?
                                          mIncludeCoordAttrs = 0,
                                          // include attributes from coordinate lines
                                          mColumnHeadersInFirstRow = 0,
                                          // is the first row of the file column headers? (like for CSV files)
                                          mIncludeElevCoords = 1,
                                          // is the 3rd coordinate column an elevation or Z value? Must be TRUE for eAsciiImportElevation import type.
                                          mColumnsToSkip = 0,
                                          // columns to skip before reaching coordinate columns
                                          mCoordLinePrefix = String.Empty,
                                          // prefix to look for at beginning of coordinate lines (default to NULL or empty)
                                          mAreaType = AreaFeatureClass_t16.AFC_UNKNOWN,
                                          // area type to assign to imported created area features
                                          mLineType = LineFeatureClass_t16.LFC_UNKNOWN,
                                          // line type to assign to imported created line features
                                          mPointType = PointFeatureClass_t16.PFC_UNKNOWN,
                                          // point type to assign to imported point features
                                          mIgnoreZeroElevations = 0,
                                          // ignore features with an elevation of zero
                                          mFillToBounds = 1,
                                          // fill grid to full bounds of data (i.e. don't constrict to convex hull)
                                          mOffsetX = 0,
                                          // offset to apply to X coordinates
                                          mOffsetY = 0,
                                          // offset to apply to Y coordinates
                                          mOffsetZ = 0,
                                          // offset to apply to Z coordinates
                                          mScaleX = 1.0,
                                          // Scale to apply to X coordinates (default is 1.0)
                                          mScaleY = 1.0,
                                          // Scale to apply to Y coordinates (default is 1.0)
                                          mScaleZ = -1.0,
                                          // Scale to apply to Z coordinates (default is 1.0)
                                          mNoDataDistanceFactor = 0.0,
                                          // tightness factor to use when gridding 3D data. Use 0.0 for default.
                                          mBreakOnColumnIdx = IntPtr.Zero
                                          // index of column to break features on when value changes. Pass NULL for default break behavior.
   };

            var projection = new GM_Projection_t
                                        {
                                            mProjSys = PROJSYS.GM_PRJ_GEO,
                                            // Projection system
                                            mDatum = DATUM.GM_DATUM_WGS_84,
                                            // Horizontal datum
                                            mUnit = UNIT.GM_PRJ_UNIT_ARC_DEGREES,
                                            // Ground units
                                            mNumAttrs = 0
                                            // Number of attributes in attribute list
                                        };

GlobalMapperDLL.GM_LoadGenericAsciiTextLayer(fileName, out layerHandle, flags, ref asciiFormatInfo, ref projection);
---------------------------

When it tries to run GM_LoadGenericAsciiTextLayer it comes out with the following error:
GlobalMapperInterface
Unable to load text file test.asc
GenericASCIIOverlay.cpp - 1635
Version: v1.33
Build Time: Mar 3 2010 16:03:06
Use Ctrl+V to Paste Error
OK

Additionally, if I try to pass in empty asciiFormatInfo and projection, it runs into memory issues:

First-chance exception at 0x755eb727 (KernelBase.dll) in blah.exe: Microsoft C++ exception: SmartASCIIFile_t::MissingFile_t at memory location 0x00329d83 (or whatever the memory du jour is).

Can you provide an accurate example of how to load in an ASCII file via C# (or heck even C++ at this point) or help to me to understand where and how this is failing?

Brian

Comments

  • global_mapper
    global_mapper Administrator
    edited August 2010
    Brian,

    Can you show me your C# declaration of the GM_AsciiFormatInfo_t structure? I'm guessing there is an error there as the error you are getting back means that the mImportType value is not valid, which likely means there is an alignment error in your structure.

    In particular, make sure that you are NOT using the C# 'bool' type for the 'boolean' values in the C++ declaration as the C# 'bool' is 32-bits and the C++ 'boolean' in the header is just 8-bytes. Use Byte instead.

    Let me know if I can be of further assistance.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    yes correct - that was it, figured this out late last night - here is the code (i restored to original SDK layout and it worked), but i have one more issue (after code) that i'm having a very hard time figuring out:
    // This type represents layout information for a generic ASCII import
            public struct GM_AsciiFormatInfo_t
            {
                public GM_AsciiImportType_t8 mImportType;                // specify import type
                public GM_AsciiCoordDelim_t8 mCoordDelim;                // sepcify coordinate delimeter
                public Byte mYCoordFirst;               // is Y coordinate first or X coordinate?
                public Byte mIncludeCoordAttrs;         // include attributes from coordinate lines
                public Byte mColumnHeadersInFirstRow;   // is the first row of the file column headers? (like for CSV files)
                public Byte mIncludeElevCoords;         // is the 3rd coordinate column an elevation or Z value? Must be TRUE for eAsciiImportElevation import type.
                public Byte mColumnsToSkip;             // columns to skip before reaching coordinate columns
                public Byte mReserved;                  // reserved, must be 0
                public String mCoordLinePrefix;           // prefix to look for at beginning of coordinate lines (default to NULL or empty)
                public AreaFeatureClass_t16 mAreaType;                  // area type to assign to imported created area features
                public LineFeatureClass_t16 mLineType;                  // line type to assign to imported created line features
                public PointFeatureClass_t16 mPointType;                 // point type to assign to imported point features
                public Byte mIgnoreZeroElevations;      // ignore features with an elevation of zero
                public Byte mFillToBounds;              // fill grid to full bounds of data (i.e. don't constrict to convex hull)
                public double mOffsetX;                   // offset to apply to X coordinates
                public double mOffsetY;                   // offset to apply to Y coordinates
                public double mOffsetZ;                   // offset to apply to Z coordinates
                public double mScaleX;                    // Scale to apply to X coordinates (default is 1.0)
                public double mScaleY;                    // Scale to apply to Y coordinates (default is 1.0)
                public double mScaleZ;                    // Scale to apply to Z coordinates (default is 1.0)
                public double mNoDataDistanceFactor;      // tightness factor to use when gridding 3D data. Use 0.0 for default.
                public IntPtr /* uint8* */      mBreakOnColumnIdx;          // index of column to break features on when value changes. Pass NULL for default break behavior.
            }
    

    so now it's able to process, however once i try to grab the layer info, i get a different kind of error when i run this line:
    var info = (GM_LayerInfo_t)Marshal.PtrToStructure(pointer, typeof(GM_LayerInfo_t));
    

    the error is:

    A first chance exception of type 'System.AccessViolationException' occurred in mscorlib.dll
    An unhandled exception of type 'System.AccessViolationException' occurred in mscorlib.dll

    Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

    I have been trying to read up how this is the case - and the best thing I can think of is it may have to do with me running 64-bit Windows 7. I am using Visual Studio 2010 Premium, building both projects to "Any CPU" (one of the few configs that works) and targeting the 64-bit (bin64) SDK build (I had ZERO luck targeting the 32-bit SDK build) with working directory for debug set to the SDK directory (to find the associated libraries).

    I'm tempted to put Visual Studio on my 32-bit WinXP VM and build there, my guess is I would not see this error. Any thoughts on the 64/32-bit madness? It's possible this isn't even a factor, but I did have to go through quite a learning curve as to which 64/32 bit configurations/build settings worked and didn't work in order to even get this far.

    Let me know any thoughts, thanks. I'll keep reading up - possibly build out 32-bit environment to test.

    Brian
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    Also, setting Build of projects to "x86" against 64-bit SDK always results in the following ugliness:

    An unhandled exception of type 'System.BadImageFormatException' occurred in blah.exe

    Additional information: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

    Setting the build explicitly to x64 against 64-bit SDK (with working debug directory set to 64-bit SDK directory) results in the same error as my prior post - SystemAccess memory violation...

    If I fail to set the working directory of course, I will receive this message no matter what I do (irrelevant for now, just point it out):

    Form1: blah.vshost.exe - System Error
    The program can't start because gmp-vc90-mt.dll is missing from your computer. Try reinstalling the program to fix this problem.
    OK

    Let me know if you have any further thoughts.

    Brian
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    Lastly, setting project builds to x86 with the proper working directory set to /bin of SDK and targeting the 32-bit DLL results in the SAME error as listed above.

    Brian
  • global_mapper
    global_mapper Administrator
    edited August 2010
    Brian,

    First off, the 'Any CPU' setting is not what you want as you shouldn't be able to call code compiled for a specific architecture (like the 32-bit or 64-bit SDK DLLs) from CPU-generic code. You need to use a x86 build with the 32-bit SDK libraries and an x64 build with the 64-bit SDK libraries.

    I think the error that you are getting is likely again due to an incorrect structure definition (this time of GM_LayerInfo_t), resulting in the marshalling accessing memory incorrectly. I don't believe this has anything to do with a 32-bit or 64-bit issue.

    Are you using the C# sample application at http://www.globalmapper.com/developer/SDK_Sample_CSharp.zip as a base? It should have correct structure definitions for a lot of structures, including the GM_LayerInfo_t structure, as well as some sample code for correctly calling this and a working Visual Studio project that you can test with.

    Let me know if I can be of further assistance.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • codemouse
    codemouse Global Mapper User Trusted User
    edited August 2010
    Mike,

    Just figured out all my issues - yes some struct def issue mismatches. Cleaned up everything and looked around for missing items. I had picked up some work-in-progress from a colleague from months back. I believe they had an older version of the SDK combined with some modifications of their own.

    I can get everything working now - utilizing 32bit or 64bit SDK on my workstation.

    Thank you again for your quick responses. Very helpful.

    Brian
Sign In or Register to comment.