Added: Command to search and target closest user landmark.
--HG-- branch : develop
This commit is contained in:
parent
11150e6b79
commit
923084a818
3 changed files with 186 additions and 5 deletions
|
@ -2493,6 +2493,33 @@ class CAHTarget : public IActionHandler
|
||||||
};
|
};
|
||||||
REGISTER_ACTION_HANDLER (CAHTarget, "target");
|
REGISTER_ACTION_HANDLER (CAHTarget, "target");
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
class CAHTargetLandmark : public IActionHandler
|
||||||
|
{
|
||||||
|
virtual void execute (CCtrlBase * /* pCaller */, const string &Params)
|
||||||
|
{
|
||||||
|
string search = getParam(Params, "search");
|
||||||
|
if (search.empty()) return;
|
||||||
|
|
||||||
|
bool startsWith = false;
|
||||||
|
if (search.size() > 0 && (search[0] == '\'' || search[0] == '"') && search[0] == search[search.size()-1])
|
||||||
|
{
|
||||||
|
startsWith = true;
|
||||||
|
search = trimQuotes(search);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string mapid = "ui:interface:map:content:map_content:actual_map";
|
||||||
|
CGroupMap* cgMap = dynamic_cast<CGroupMap*>(CWidgetManager::getInstance()->getElementFromId(mapid));
|
||||||
|
if (cgMap)
|
||||||
|
{
|
||||||
|
if (!cgMap->targetLandmarkByName(search, startsWith))
|
||||||
|
{
|
||||||
|
CInterfaceManager::getInstance()->displaySystemInfo(CI18N::get("uiTargetErrorCmd"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
REGISTER_ACTION_HANDLER (CAHTargetLandmark, "target_landmark");
|
||||||
|
|
||||||
|
|
||||||
class CAHAddShape : public IActionHandler
|
class CAHAddShape : public IActionHandler
|
||||||
|
|
|
@ -100,6 +100,12 @@ const uint32 ISLAND_PIXEL_PER_METER = 2;
|
||||||
|
|
||||||
static void setupFromZoom(CViewBase *pVB, CContLandMark::TContLMType t, float fMeterPerPixel);
|
static void setupFromZoom(CViewBase *pVB, CContLandMark::TContLMType t, float fMeterPerPixel);
|
||||||
|
|
||||||
|
// calculate distance (squared) between two points
|
||||||
|
static float distsqr(const CVector2f a, const CVector2f b)
|
||||||
|
{
|
||||||
|
return pow(a.x - b.x, 2) + pow(a.y - b.y, 2);
|
||||||
|
}
|
||||||
|
|
||||||
// popup the landmark name dialog
|
// popup the landmark name dialog
|
||||||
|
|
||||||
static void popupLandMarkNameDialog()
|
static void popupLandMarkNameDialog()
|
||||||
|
@ -2671,21 +2677,38 @@ void CGroupMap::updateLandMarkButton(CLandMarkButton *lmb, const CLandMarkOption
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================================================
|
//============================================================================================================
|
||||||
bool CGroupMap::filterLandmark(const ucstring &title) const
|
bool CGroupMap::filterLandmark(const ucstring &title, const std::vector<ucstring> filter, bool startsWith) const
|
||||||
{
|
{
|
||||||
if (_LandmarkFilter.size() > 0)
|
if (filter.size() > 0)
|
||||||
{
|
{
|
||||||
ucstring lcTitle = toLower(title);
|
ucstring lcTitle = toLower(title);
|
||||||
for(uint i = 0; i< _LandmarkFilter.size(); ++i) {
|
if (startsWith)
|
||||||
if (lcTitle.find(_LandmarkFilter[i]) == ucstring::npos) {
|
{
|
||||||
|
if (lcTitle.find(filter[0]) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(uint i = 0; i< filter.size(); ++i)
|
||||||
|
{
|
||||||
|
if (lcTitle.find(filter[i]) == ucstring::npos)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================================================
|
||||||
|
bool CGroupMap::filterLandmark(const ucstring &title) const
|
||||||
|
{
|
||||||
|
return filterLandmark(title, _LandmarkFilter);
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================================================
|
//============================================================================================================
|
||||||
void CGroupMap::addLandMark(TLandMarkButtonVect &destList, const NLMISC::CVector2f &pos, const ucstring &title, const CLandMarkOptions &options)
|
void CGroupMap::addLandMark(TLandMarkButtonVect &destList, const NLMISC::CVector2f &pos, const ucstring &title, const CLandMarkOptions &options)
|
||||||
{
|
{
|
||||||
|
@ -3186,6 +3209,129 @@ void CGroupMap::targetLandmarkResult(uint32 index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=========================================================================================================
|
||||||
|
CGroupMap::CLandMarkButton* CGroupMap::findClosestLandmark(const CVector2f ¢er, const ucstring &search, bool startsWith, const TLandMarkButtonVect &landmarks, float &closest) const
|
||||||
|
{
|
||||||
|
CLandMarkButton *ret = NULL;
|
||||||
|
|
||||||
|
std::vector<ucstring> keywords;
|
||||||
|
if (startsWith)
|
||||||
|
keywords.push_back(search);
|
||||||
|
else
|
||||||
|
splitUCString(toLower(search), ucstring(" "), keywords);
|
||||||
|
|
||||||
|
closest = std::numeric_limits<float>::max();
|
||||||
|
for(TLandMarkButtonVect::const_iterator it = landmarks.begin(); it != landmarks.end(); ++it)
|
||||||
|
{
|
||||||
|
ucstring lc;
|
||||||
|
(*it)->getContextHelp(lc);
|
||||||
|
if(filterLandmark(lc, keywords, startsWith)) {
|
||||||
|
CVector2f pos;
|
||||||
|
mapToWorld(pos, (*it)->Pos);
|
||||||
|
float dist = distsqr(center, pos);
|
||||||
|
if (dist < closest)
|
||||||
|
{
|
||||||
|
ret = (*it);
|
||||||
|
closest = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================================================================
|
||||||
|
CGroupMap::CLandMarkText* CGroupMap::findClosestLandmark(const CVector2f ¢er, const ucstring &search, bool startsWith, const TLandMarkTextVect &landmarks, float &closest) const
|
||||||
|
{
|
||||||
|
CLandMarkText *ret = NULL;
|
||||||
|
|
||||||
|
std::vector<ucstring> keywords;
|
||||||
|
if (startsWith)
|
||||||
|
keywords.push_back(search);
|
||||||
|
else
|
||||||
|
splitUCString(toLower(search), ucstring(" "), keywords);
|
||||||
|
|
||||||
|
closest = std::numeric_limits<float>::max();
|
||||||
|
for(TLandMarkTextVect::const_iterator it = landmarks.begin(); it != landmarks.end(); ++it)
|
||||||
|
{
|
||||||
|
ucstring lc;
|
||||||
|
lc = (*it)->getText();
|
||||||
|
if(filterLandmark(lc, keywords, startsWith)) {
|
||||||
|
CVector2f pos;
|
||||||
|
mapToWorld(pos, (*it)->Pos);
|
||||||
|
float dist = distsqr(center, pos);
|
||||||
|
if (dist < closest)
|
||||||
|
{
|
||||||
|
ret = (*it);
|
||||||
|
closest = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGroupMap::targetLandmarkByName(const ucstring &search, bool startsWith) const
|
||||||
|
{
|
||||||
|
CCompassTarget ct;
|
||||||
|
CLandMarkButton* lm;
|
||||||
|
float dist;
|
||||||
|
float closest = std::numeric_limits<float>::max();
|
||||||
|
bool found = false;
|
||||||
|
CVector2f center;
|
||||||
|
mapToWorld(center, _PlayerPos);
|
||||||
|
|
||||||
|
lm = findClosestLandmark(center, search, startsWith, _UserLM, dist);
|
||||||
|
if (lm && dist < closest)
|
||||||
|
{
|
||||||
|
ct.setType(CCompassTarget::UserLandMark);
|
||||||
|
mapToWorld(ct.Pos, lm->Pos);
|
||||||
|
lm->getContextHelp(ct.Name);
|
||||||
|
closest = dist;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only check other types if user landmark was not found
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
lm = findClosestLandmark(center, search, startsWith, _ContinentLM, dist);
|
||||||
|
if (lm && dist < closest)
|
||||||
|
{
|
||||||
|
ct.setType(CCompassTarget::ContinentLandMark);
|
||||||
|
mapToWorld(ct.Pos, lm->Pos);
|
||||||
|
lm->getContextHelp(ct.Name);
|
||||||
|
closest = dist;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLandMarkText* lmt;
|
||||||
|
lmt = findClosestLandmark(center, search, startsWith, _ContinentText, dist);
|
||||||
|
if (lmt && dist < closest)
|
||||||
|
{
|
||||||
|
ct.setType(CCompassTarget::ContinentLandMark);
|
||||||
|
mapToWorld(ct.Pos, lmt->Pos);
|
||||||
|
ct.Name = lmt->getText();
|
||||||
|
closest = dist;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
CInterfaceManager *im = CInterfaceManager::getInstance();
|
||||||
|
CGroupCompas *gc = dynamic_cast<CGroupCompas *>(CWidgetManager::getInstance()->getElementFromId(_CompassId));
|
||||||
|
if (gc)
|
||||||
|
{
|
||||||
|
gc->setActive(true);
|
||||||
|
gc->setTarget(ct);
|
||||||
|
gc->blink();
|
||||||
|
CWidgetManager::getInstance()->setTopWindow(gc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
//=========================================================================================================
|
//=========================================================================================================
|
||||||
void CGroupMap::getLandmarkPosition(const CCtrlButton *lm, NLMISC::CVector2f &worldPos)
|
void CGroupMap::getLandmarkPosition(const CCtrlButton *lm, NLMISC::CVector2f &worldPos)
|
||||||
{
|
{
|
||||||
|
|
|
@ -192,6 +192,8 @@ public:
|
||||||
// target the given landmark
|
// target the given landmark
|
||||||
void targetLandmark(CCtrlButton *lm);
|
void targetLandmark(CCtrlButton *lm);
|
||||||
void targetLandmarkResult(uint32 index);
|
void targetLandmarkResult(uint32 index);
|
||||||
|
// search matching landmark and target it. return true if landmark was targeted
|
||||||
|
bool targetLandmarkByName(const ucstring &search, bool startsWith) const;
|
||||||
// get the world position of a landmark or return vector Null if not found
|
// get the world position of a landmark or return vector Null if not found
|
||||||
void getLandmarkPosition(const CCtrlButton *lm, NLMISC::CVector2f &worldPos);
|
void getLandmarkPosition(const CCtrlButton *lm, NLMISC::CVector2f &worldPos);
|
||||||
|
|
||||||
|
@ -551,6 +553,12 @@ private:
|
||||||
|
|
||||||
// Test title against landmark filter
|
// Test title against landmark filter
|
||||||
bool filterLandmark(const ucstring &title) const;
|
bool filterLandmark(const ucstring &title) const;
|
||||||
|
bool filterLandmark(const ucstring &title, const std::vector<ucstring> filter, bool startsWith = false) const;
|
||||||
|
|
||||||
|
// return closest landmark which matches (case insensitive) search string
|
||||||
|
// center position must be in world coordindates
|
||||||
|
CLandMarkButton* findClosestLandmark(const NLMISC::CVector2f ¢er, const ucstring &search, bool startsWith, const TLandMarkButtonVect &landmarks, float &closest) const;
|
||||||
|
CLandMarkText* findClosestLandmark(const NLMISC::CVector2f ¢er, const ucstring &search, bool startsWith, const TLandMarkTextVect &landmarks, float &closest) const;
|
||||||
|
|
||||||
// update the scale depending on the window size and the user scale
|
// update the scale depending on the window size and the user scale
|
||||||
void updateScale();
|
void updateScale();
|
||||||
|
|
Loading…
Reference in a new issue