Select Features
I would like to highlight features on the map meeting a specific query criteria and am looking for a code sample to demonstrate how to do this.
In my example, I have a custom layer with point features. I maintain the attributes and ids for these features in a database and create the point feature with its mFeatureInfo.mName assigned to a unique integer using the following:
For this sample, I would like to select a set of features, for example, id's 1,5,25 and 100 and based on that selection highlight those features on the map with a specific selection color.
Thank you for any help or suggestions, or sample code related to this!
Rod
In my example, I have a custom layer with point features. I maintain the attributes and ids for these features in a database and create the point feature with its mFeatureInfo.mName assigned to a unique integer using the following:
//create point GM_PointFeature_t point = new GM_PointFeature_t(); point.mPointStyle.mSymbolName = symbol; point.mPointStyle.mScale = 0.5F; point.mPointStyle.mDrawLabel = 0; point.mPos.mX = x; point.mPos.mY = y; point.mFeatureInfo.mName = id.ToString(); //unique int // Add the point to the custom layer LastGMError = GlobalMapperDLL.GM_AddPointToVectorLayer(layer, ref point, 0);
For this sample, I would like to select a set of features, for example, id's 1,5,25 and 100 and based on that selection highlight those features on the map with a specific selection color.
Thank you for any help or suggestions, or sample code related to this!
Rod
Comments
-
Rod,
What you should do is use the GM_GetPointFeature function to iterate through all of the features in a layer to find those matching particular attributes, then when you find the desired ones use GM_SetPointFeatureDrawStyle to change the drawing style to your desired selected style.
Let me know if I can be of further assistance.
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
Thank you Mike,
I'm part way there, but hung up on the following. I'll post my sample code back for others once I get it all working. For updating the style I'm getting the following error:
Error 14 'GlobalMapperDLLWrapper.GlobalMapperDLL' does not contain a definition for 'GM_SetPointFeatureDrawStyle'
foreach (int fid in foundFeatures)
{
pPoint = GlobalMapperDLL.GM_GetPointFeature(pLayer, fid);
LastGMError = GlobalMapperDLL.GM_SetPointFeatureDrawStyle(pLayer, pPoint, pStyle);
}
Here is the function reference information:
// Sets the drawing style to use for a given point feature
GM_DLL_EXPORTED GM_Error_t32 __stdcall GM_SetPointFeatureDrawStyle
(
GM_LayerHandle_t32 aLayer, // Layer the point is in
uint32 aPointIndex, // Index of point in layer
const GM_PointStyle_t* aPointStyle // New style to use for point
);
How do I call this function? -
The C# and VB.NET (which are you using?) sample applications only have sample implementations of some functions. If you let me know if you are in C# or VB.NET I can provide the sample call you would need to add if you have trouble. The only tricky parameter is the aPointStyle one, which you could define as 'ByRef' of type GM_PointStyle_t if you don't ever need to pass in NULL to reset the style, but if you do need it to allow NULL, define it as IntPtr as pass your value in that way.
Let me know if I can be of further assistance.
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
I'm using the C# SDK. A sample of how to call GM_SetPointFeatureDrawStyle would be wonderful!
Rod -
Rod,
I have attached an updated C# SDK sample that includes a declaration for the GM_SetPointFeatureDrawStyle function.
Let me know if I can be of further assistance.
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
Thank you Mike! I'm now getting a compile error on the third argument which I'm supplying to the GM_SetPointFeatureDrawStyle() function. My goal is to get the current style for the selected features and change the draw symbol to one with a different color to show the user the selected features with a "selection color". I've created and saved the new style, and I'm attempting to assign that. Since the mPointStyle property of my point is of GM_PointStlye_t type, I capture that and change its mSymbolName property. However, when I try to use this to assign the new draw style, I'm getting a type mismatch for the third argument. The function is looking for an IntPtr while I have a GM_PointStyle_t. Can you show me how I would get an IntPtr to this style instead?
//create selected style GM_PointStyle_t style = new GM_PointStyle_t(); foreach (uint fid in foundFeatures) { pPoint = GlobalMapperDLL.GM_GetPointFeature(pLayer, fid); point = (GM_PointFeature_t)Marshal.PtrToStructure(pPoint, point.GetType()); style = point.mPointStyle; style.mSymbolName = "Seismic Survey - Planned Source [selected]"; LastGMError = GlobalMapperDLL.GM_SetPointFeatureDrawStyle(pLayer, fid, style); point.mPointStyle.mSymbolName = "Seismic Survey - Planned Source [selected]"; }
-
There are a couple of ways to get an IntPtr from an object in C#. The easiest is probably just to use the 'fixed' declaration to get a fixed pointer to the object in memory, then pass that. It should look something like the following:
fixed ( GM_PointStyle_t* theStylePtr = &style )
{
LastGMError = GlobalMapperDLL.GM_SetPointFeatureDrawStyle(pLayer, fid, theStylePtr);
}
Let me know if I can be of further assistance.
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
Mike, Thank you for your help with this! I'm still getting the following C# compiler errorCannot take the address of, get the size of, or declare a pointer to a managed type ('GlobalMapperDLLWrapper.GM_PointStyle_t')
Here is a reference that provides good insight to this topic (for anyone else reading this and having similar trouble using pointers in C#): http://www.c-sharpcorner.com/UploadFile/gregory_popek/WritingUnsafeCode11102005040251AM/WritingUnsafeCode.aspx
I've tried wrapping my entire function with the unsafe declaration, but that results in the same error. Seems that I won't be allowed to use GM_PointStyle_t in both a managed and unmanaged context.
Any additional insight on solving this that you can provide me with would be greatly appreciated!foreach (uint fid in foundFeatures) { pPoint = GlobalMapperDLL.GM_GetPointFeature(pLayer, fid); point = (GM_PointFeature_t)Marshal.PtrToStructure(pPoint, point.GetType()); style = point.mPointStyle; style.mSymbolName = "Seismic Survey - Planned Source [selected]"; unsafe { fixed(GM_PointStyle_t* stylePtr = &style); } LastGMError = GlobalMapperDLL.GM_SetPointFeatureDrawStyle(pLayer, fid, stylePtr); }
-
I don't think your unsafe wrapping is correct, your current stylePtr declaration would go out of scope prior to your call to GM_SetPointFeatureDrawStyle. Try the following instead (also make sure that you have enabled the use of unsafe code in your project settings):
unsafe
{
fixed(GM_PointStyle_t* stylePtr = &style)
{
LastGMError = GlobalMapperDLL.GM_SetPointFeatureDrawStyle(pLayer, fid, stylePtr);
}
}
If that doesn't work, you can instead use the Marshal.AllocHGlobal to allocate memory the same of a GM_PointStyle_t structure, then use Marshal.StructureToPtr to copy the contents of your GM_PointStyle_t value to that memory, then pass in the pointer to that, then use Marshal.FreeHGlobal to free the allocated memory. You can avoid the use of unsafe code if you do this.
Let me know if I can be of further assistance.
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
Hi Mike,
I've tried several wrappings into an unsafe context and have not had any different results with that. The following produces the same error:unsafe { fixed (GM_PointStyle_t* stylePtr = &style) { LastGMError = GlobalMapperDLL.GM_SetPointFeatureDrawStyle(pLayer, fid, stylePtr); } }
I also tried declaring the method unsafe:public unsafe void SelectFeatures(string queryFilter, string layerName) {
as well as declaring the class unsafe:public unsafe partial class GlobalMapper2D : UserControl {
none of these work. I think it may have to do with the fact that GM_PointStyle_t is defined in managed code or has a reference type within its structure.
I would like to try using your suggested alternative. Would it be possible for you to provide a sample that uses that? It looks very greek to me, and you could probably have sample code formed up in a matter of minutes that uses that alternate method, where as I would still be wrestling with it tomorrow or the next day if left on my own with it. -
Before going down the dynamic memory allocation route, can you try just changing your GM_SetPointFeatureDrawStyle declaration to the following:
[DllImport(DLLFileName, EntryPoint = "GM_SetPointFeatureDrawStyle")]
public static extern GM_Error_t32 GM_SetPointFeatureDrawStyle
(
GM_LayerHandle_t32 aLayer, // Layer the point is in
UInt32 aPointIndex, // Index of point in layer
ref GM_PointStyle_t aPointStyle // (const GM_PointStyle_t*) New style to use for point, pass IntPtr.Zero to restore default type-based stuff
);
Then call that directly with your 'style' value. The only thing you lose with this declaration is the ability to pass in IntPtr.Zero for the style to reset it to the default, but I don't think you care about this for your application. This approach is much simpler than wrestling with the other stuff.
Thanks,
Mike
Global Mapper Support
support@globalmapper.com -
Thank you Mike,
That solved it! Here is the code I ended up with:// get pointer to layer from dictionary given layerName // note: this was saved into dictionary when layer was created IntPtr pLayer = layers[layerName]; GM_PointFeature_t point = new GM_PointFeature_t(); IntPtr pPoint; //create selected style GM_PointStyle_t style = new GM_PointStyle_t(); foreach (uint fid in foundFeatures) { pPoint = GlobalMapperDLL.GM_GetPointFeature(pLayer, fid); point = (GM_PointFeature_t)Marshal.PtrToStructure(pPoint, point.GetType()); style = point.mPointStyle; style.mSymbolName = "Seismic Survey - Planned Source [selected]"; LastGMError = GlobalMapperDLL.GM_SetPointFeatureDrawStyle(pLayer, fid, ref style); } DrawLayersToBitmap();
Categories
- 12.7K All Categories
- 5.6K Features Discussion
- 342 Downloading Imagery
- 1.3K Elevation Data
- 380 Georeferencing Imagery Discussion
- 628 GM Script Language
- 53 User Scripts
- 113 GPS Features
- 414 Projection Questions
- 819 Raster Data
- 1.3K Vector Data
- 6.6K Support
- 177 Announcement and News
- 908 Bug Report
- 558 SDK
- 1.2K Suggestion Box
- 3.7K Technical Support
- 562 Other Discussion
- 129 GIS Data Sources
- 27 Global Mapper Showcase
- 233 How I use Global Mapper
- 107 Global Mapper Forum Website