In this article we describe 3 methods of accessing map objects from your source code. Keymap SDK C++ Edition can be integrated into your application in many ways. You may choose to derive your view class from CMUIMap class, or directly use CMUIMap class, or even use CMapT class etc. However, the concept of accessing and manipulating map objects and layers always are the same. In some of your own classes, you have to implement member functions like this:
CMapT* GetMap();
By default, applications generated by Keymap SDK wizards have view class derived from CMUIMap, so GetMap method is available in your view class. Once the pointer to the CMapT object is obtained, the rest is quite simple: using the CMapT member functions for accessing layers, and thus the map objects.
First you need to get pointer to desired layer.
// get layer using zero-based index) CMapLayer* pLayer = GetMap()->GetLayer(iLayer); // get layer by name CMapLayer* pLayer = GetMap()->FindLayer(strName); ASSERT(pLayer); //make sure that pLayer not NULL
After layer pointer obtained, use CMapLayer API to access map objects.
Object ID is unique integer used for object identification in Keymap database. If you know some object ID, use GetObject method to access this object.
// iID is unique object ID
CMapObject* pObj = pLayer->GetObject(iID);
// do something with pObj
if(pObj->GetType() == polygon) {
...
}
// commit object changes
pObj->Commit();
// makes changes permanent in the database if needed
// if you don't want to save changes in layer database, do not call this method
pLayer->Commit();
// free memory to avoid memory leaks
FREE(pObj);
If object ID is unknown, or you need to iterate through all map objects in the layer, use CMapLayer::GetObjectIndex method.
// i is object zero-based index
for(int i=0;i<pLayer->GetObjectCount();i++) {
CMapObject* pObj = pLayer->GetObjectIndex(i);
// do something with pObj
...
//and commit object changes
pObj->Commit();
// free memory to avoid memory leaks
FREE(pObj);
}
// makes changes permanent in the database if needed
// if you don't want to save changes in layer database, do not call this method
pLayer->Commit();
This method provide very fast access to map objects, however not in right order (from beginning to end of the layer). Furthermore, you must iterate through nodes and none-node objects separately.
Iterate through all none-node objects
//get first none-node object
CMapObject* pObj = pLayer->GetFirstInXtreeObject(false);//true if you need to load metadata (slower), false if no metadata (faster)
// do something with the object
if(pObj) {
...
//and commit object changes
pObj->Commit();
// free memory to avoid memory leaks
FREE(pObj);
}
// now can get next object
pObj = pLayer->GetNextInXtreeObject(false);
// if pObj is NULL, you reach the end of the layer
if(pObj) {
...
}
// makes changes permanent in the database if needed
// if you don't want to save changes in layer database, do not call this method
pLayer->Commit();
Iterate through all node objects
//get first node object
CMapObject* pObj = pLayer->GetFirstNode(false);//true if you need to load
metadata (slower), false if no metadata (faster)
// do something with the object
if(pObj) {
...
//and commit object changes
pObj->Commit();
// free memory to avoid memory leaks
FREE(pObj);
}
// now can get next node
pObj = pLayer->GetNextNode(false);
// if pObj is NULL, you reach the end of the layer
if(pObj) {
...
}
// makes changes permanent in the database if needed
// if you don't want to save changes in layer database, do not call this method
pLayer->Commit();
Fastest method of accessing all map objects intersected with specific rectangle
This method provide very fast access to map objects intersected with specific rectangle. Like fast iteration technic above, you must iterate through nodes and none-node objects separately. Furthermore, you must define a global function as "search callback".
First we define a search callback function:
bool SearchCallback(CMapObject* pObj)
{
//call InitMetaData only in real need. This is a bit slow function
pObj->InitMetaData();
if(pObj->GetType() != node)
pObj->SetLineColor(GREEN);
else
pObj->GetObjectProperty()->SetNodeColor(GREEN);
pObj->Commit();
//free memory to avoid memory leeks
FREE(pObj);
return false;//continue search; to interrupt search, return true
}
Iterate through all none-node objects
Call CMapLayer's method FindObjectByXTree:
pLayer->FindObjectByXTree(0, GetMap()->GetViewportRect(), SearchCallback);
In this sample code we look for all none-node objects in current map window, not ignoring small objects, and use SearchCallback as search callback method.
Iterate through all node objects
Call FindNodeByKdTree method:
pLayer->FindNodeByKdTree(GetMap()->GetViewportRect(), SearchCallback);
In this sample code we look for all node objects in current map window, using SearchCallback as search callback method.