how to create an area feature and draw it with GM_CreateCustomVectorLayer?
I am trying to develop a GIS application with this SDK in C# and i have a question:
how i pass the points to the structure GM_AreaFeature_t?
My code such as :
GM_AreaFeature_t lt_Customize = new GM_AreaFeature_t();
lt_Customize.mPointList = ?????;//what will be assigned?
lt_Customize.mFeatureInfo = lt_VectorFeature;
lt_Customize.mNumPoints =(uint) pList.Count;
lt_Customize.mNumHoles = 0;
Any help will be apprecated1
Jerry
how i pass the points to the structure GM_AreaFeature_t?
My code such as :
GM_AreaFeature_t lt_Customize = new GM_AreaFeature_t();
lt_Customize.mPointList = ?????;//what will be assigned?
lt_Customize.mFeatureInfo = lt_VectorFeature;
lt_Customize.mNumPoints =(uint) pList.Count;
lt_Customize.mNumHoles = 0;
Any help will be apprecated1
Jerry
Comments
-
Jerry,
I'm not a C# programmer, but what the mPointList value expects is the address of a continguous chunk of memory containing a series of GM_Point_t features. In C/C++ this is just a pointer to the first element in an array of GM_Point_t features. I'm sure there is a way to allocate a chunk of memory in C# and then assign values to it.
Let me know if I can be of further assistance.
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
Mike,
Thanks for your reply.
My code such as :
GM_AreaFeature_t myAreaFeature = CreateMyArea(coor);
GlobalMapperDLL.GM_AddAreaToCustomVectorLayer(LayerHandle, ref myAreaFeature , true);
public GM_AreaFeature_t CreateMyArea(ArrayList coor)
{
GM_Point_t[] lt_Point = new GM_Point_t[coor.Count / 2];//My Points stored in Coor Array
int ln_Counter = 0;
for (int i = 0; i < coor.Count - 1; i++)//read XY coordinates and write into GM_Point_t.
{
lt_Point[ln_Counter].X = Convert.ToDouble(coor);
lt_Point[ln_Counter].Y = Convert.ToDouble(coor[i + 1]);
ln_Counter++;
i++;
}
//allocate a chunk of memory
IntPtr ptrPoint = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(GM_Point_t)));
//assign the array[0] address to IntPtr.
Marshal.StructureToPtr(lt_Point[0], ptrPoint, true);
GM_AreaFeature_t lt_Customize = new GM_AreaFeature_t();
lt_Customize.mFeatureInfo = ptrPoint ;
lt_Customize.mNumPoints =lt_Point.Length;
lt_Customize.mNumHoles = 0;
return lt_Customize
}
It can draw out some things but not what i want! -
My C# is not so good, but I would expect your Marshal.AllocCoTaskMem call to allocate enough memory for all of the points in the array and not just one. I think that line should look like the following:
IntPtr ptrPoint = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(GM_Point_t) * coor.Count / 2));
Then your call to Marshal the structure to the pointer will have to copy each point element into the allocated memory buffer (or just do some sort of memcpy if that is possible in C#).
Let me know if I can be of further assistance.
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
Thanks Mike,
the above question has solved with Pointer in C# and draw it correctly.But i find another question which i think as a bug:
After drawing GM_CreateCustomVectorLayer,i resize the form again and again,or minimize it for many times,then the application seems to be dead! however , i load other layers from files instead of creating my custom vectorlayer,the application works fine!
Could you help me again?
Jerry -
Jerry,
Where is the program locking up when it seems to be dead? Is it stuck in a SDK function or some other location?
If the only difference is the custom vector layer, be very careful that you aren't writing past the end of your allocated memory buffer or something like that and corrupting memory.
Let me know if I can be of further assistance.
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
Mike,
I am trying SDK and want to create my customvectorlayer,my code such as :
public unsafe GM_AreaFeature_t CreateMyArea(ArrayList coor)
{
GM_Point_t[] lt_Point = new GM_Point_t[coor.Count / 2];//My Points stored in Coor Array
int ln_Counter = 0;
for (int i = 0; i < coor.Count - 1; i++)//read XY coordinates and write into GM_Point_t.
{
lt_Point[ln_Counter].X = Convert.ToDouble(coor);
lt_Point[ln_Counter].Y = Convert.ToDouble(coor[i + 1]);
ln_Counter++;
i++;
}
IntPtr ptrPoint;
GM_VectorFeature_t lt_VectorFeature = new GM_VectorFeature_t { Name = "testName", Desc = "testDesc", Class = 0, NumAttrs = 1 };
fixed (GM_Point_t* point_t = <_Point[0])
{
ptrPoint = (IntPtr)point_t;
}
GM_AreaFeature_t lt_Customize = new GM_AreaFeature_t();
lt_Customize.mPointList = ptrPoint;
lt_Customize.mFeatureInfo = lt_VectorFeature;
lt_Customize.mNumPoints = (uint)lt_Point.Length;
lt_Customize.mNumHoles = 0;
return lt_Customize;
}
I use it such as :
private void menuItem5_Click(object sender, EventArgs e)
{
CreateMyPrjSys();
Int32 LayerHandle = GlobalMapperDLL.GM_CreateCustomVectorLayer("MyPoint", ref lt_Prj);
........
GM_AreaFeature_t lt_MyPoint = CreateMyArea(coor); //here coor has been filled with values.
GlobalMapperDLL.GM_AddAreaToCustomVectorLayer(LayerHandle, ref lt_MyPoint, true);
clsGlobalVARS.LayerHandles.Add(LayerHandle);
DrawLayersToBitmap();
}
When I comment the line ticked with red color,everything goes well! -
Can I see your declaration for the GM_CreateCustomVectorLayer function as well as the 'lt_Prj' variable? Can I also see your declaration for the GM_AreaFeature_t type?
Does your application lock up as soon as you call the GM_CreateCustomVectorLayer function?
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
Mike,
I refactor my code in a new project and find that the question has gone! I use GM_DrawLayerList function to draw layers instead of GM_DrawLayer! I am so sorry for saying what it is bug.
Here i encounter another question:I want to symbol the customVectorlayer,my code is followed:
public void drawCustomLayer()
{
if (mn_CustomLayerHandle == null || mn_CustomLayerHandle.Count==0)
{
return;
}
UInt32 j = 0;
for (int i = 0; i < mn_CustomLayerHandle.Count; i++)
{
Int32 lp_LayerHandle = (Int32)mn_CustomLayerHandle;
IntPtr layerInfoPtr = GlobalMapperDLL.GM_GetLayerInfo(lp_LayerHandle);
//my layer contains two area feature,but GM_LayerInfo_t.mNumAreas=0;
GM_LayerInfo_t layerInfo_t = (GM_LayerInfo_t) Marshal.PtrToStructure(layerInfoPtr, typeof(GM_LayerInfo_t));
while (true)
{
IntPtr ptr = GlobalMapperDLL.GM_GetAreaFeature(lp_LayerHandle, j);
if (ptr.ToInt32() == 0) break;
GM_AreaFeature_t areaInfo = (GM_AreaFeature_t)Marshal.PtrToStructure(ptr, typeof(GM_AreaFeature_t));
//GlobalMapperDLL.GM_FreeAreaFeature(ptr);
GM_VectorFeature_t lt_VectorFeature = areaInfo.mFeatureInfo;
IntPtr ptrAttribute = lt_VectorFeature.AttrList;
GM_AttrValue_t lt_AttrValue = (GM_AttrValue_t)Marshal.PtrToStructure(ptrAttribute, typeof(GM_AttrValue_t));
GM_AreaStyle_t lt_AreaStyle = areaInfo.mAreaStyle;
lt_AreaStyle.mBrushStyle = GM_BrushStyle_t16.GM_BRUSH_SOLID;
lt_AreaStyle.mBrushColor = (uint)Color.FromArgb(255, 255, int.Parse(lt_AttrValue.mVal) * 80).ToArgb();
GlobalMapperDLL.GM_SetAreaFeatureDrawStyle(lp_LayerHandle, (int)j, ref lt_AreaStyle);
//Is it right release area feature here?
GlobalMapperDLL.GM_FreeAreaFeature(ptr);
j++;
}
}
}
there are two question in this code segment:
1.the line ticked with red color cannot return the right number of the area features in my layer.
2.the code ticked with green color is excuted well for the first time,an error occurses with the secondary excution:Try to access the protected memory! -
Everything looks ok in your code above, assuming that your GM_LayerInfo_t structure definition is correct. Do the other values in that structure look ok?
Assuming that is fine, when you call the GM_AddAreaToCustomVectorLayer function, is it returning 0 or some error code?
Your GM_FreeAreaFeature code looks correct, at least from my limited understanding of C#. You should just directly pass it the value that GM_GetAreaFeature provided you. Perhaps this one will sort itself out when the other problem is fixed.
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
Mike,
I think the stuct GM_LayerInfo_t declare is OK and when calling the GM_AddAreaToCustomVectorLayer function, it is returning 0 :
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 Int32 mPixelWidth; //' RASTER/ELEV ONLY: Number of pixels wide layer is
public Int32 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
public Int32 mNumGCPs; //' RASTER ONLY: Number of ground control points in list
public double mMinElevation; //' ELEV ONLY: Minimum elevation in meters
public double mMaxElevation; //' ELEV ONLY: Maximum elevation in meters
public Int32 mNumAreas; //' VECTOR ONLY: Number of area features
public Int32 mNumLines; //' VECTOR ONLY: Number of line features
public Int32 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)
} ;
the following image show you what is returned(do not mind the value of mDescription parameter is "MyPoint",In fact it is an area featurelayer.):
-
I actually see some problems in your declaration of the GM_LayerInfo_t structure. You have the mMinElevation and mMaxElevation values declared as 'double' when they should be 'float'.
Here are some definitions from the C# sample on our web site that should work:
// This type is used to describe a single projection attribute value
public struct GM_ProjAttrValue_t
{
public PROJATTR mAttr; // Attribute
public double mValue; // Attribute value
};
// This type is used to fully describe a projection.
public struct GM_Projection_t
{
public PROJSYS mProjSys; // Projection system
public DATUM mDatum; // Horizontal datum
public UNIT mUnit; // Ground units
public UInt32 mNumAttrs; // Number of attributes in attribute list
public GM_ProjAttrValue_t mAttr1; // Attribute value list items (C# doesn't support fixed length arrays)
public GM_ProjAttrValue_t mAttr2;
public GM_ProjAttrValue_t mAttr3;
public GM_ProjAttrValue_t mAttr4;
public GM_ProjAttrValue_t mAttr5;
public GM_ProjAttrValue_t mAttr6;
public GM_ProjAttrValue_t mAttr7;
public GM_ProjAttrValue_t mAttr8;
public GM_ProjAttrValue_t mAttr9;
public GM_ProjAttrValue_t mAttr10;
public GM_ProjAttrValue_t mAttr11;
public GM_ProjAttrValue_t mAttr12;
public GM_ProjAttrValue_t mAttr13;
public GM_ProjAttrValue_t mAttr14;
public GM_ProjAttrValue_t mAttr15;
public GM_ProjAttrValue_t mAttr16;
};
// This type is used when rectifying imagery
public struct GM_GroundControlPoint_t
{
public double PixelX; // x pixel coordinate of GCP
public double PixelY; // y pixel coordinate of GCP (top is 0, increases down)
public double GroundX; // x ground coordinate of GCP (in provided projection)
public double GroundY; // y ground coordinate of GCP (in provided projection)
};
// This type is used when returning information about a layer
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 UInt32 mPixelWidth; // RASTER/ELEV ONLY: Number of pixels wide layer is
public UInt32 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 UInt32 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 UInt32 mNumAreas; // VECTOR ONLY: Number of area features
public UInt32 mNumLines; // VECTOR ONLY: Number of line features
public UInt32 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 UInt32 mGlobalPixelWidth; // RASTER/ELEV ONLY: Approximate number of pixels required in width for a 1:1 pixel mapping in the current projection
public UInt32 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 UInt32 mMetadataListSize; // Number of entries in mMetadataList
};
Let me know if I can be of further assistance.
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
Hi,Mike,
Now it works well,Thanks a lot!
Categories
- 12.8K All Categories
- 5.7K Features Discussion
- 345 Downloading Imagery
- 1.3K Elevation Data
- 385 Georeferencing Imagery Discussion
- 637 GM Script Language
- 54 User Scripts
- 114 GPS Features
- 417 Projection Questions
- 826 Raster Data
- 1.3K Vector Data
- 6.6K Support
- 178 Announcement and News
- 913 Bug Report
- 558 SDK
- 1.2K Suggestion Box
- 3.7K Technical Support
- 569 Other Discussion
- 131 GIS Data Sources
- 27 Global Mapper Showcase
- 238 How I use Global Mapper
- 107 Global Mapper Forum Website