Added function to get closest FeatureMetadata around point.

This commit is contained in:
vng 2015-03-04 17:39:24 +03:00 committed by Alex Zolotarev
parent ce8fb6d785
commit 12a4b305d2
3 changed files with 90 additions and 15 deletions

View file

@ -820,6 +820,24 @@ extern "C"
jniEnv->CallVoidMethod(*obj.get(), methodId, j_name, j_type, j_address, lat, lon);
}
pair<jintArray, jobjectArray> NativeMetadataToJavaMetadata(JNIEnv * jniEnv, feature::FeatureMetadata const & metadata)
{
const vector<feature::FeatureMetadata::EMetadataType> metaTypes = metadata.GetPresentTypes();
const jintArray j_metaTypes = jniEnv->NewIntArray(metadata.Size());
jint * arr = jniEnv->GetIntArrayElements(j_metaTypes, 0);
const jobjectArray j_metaValues = jniEnv->NewObjectArray(metadata.Size(), jni::GetStringClass(jniEnv), 0);
for (int i = 0; i < metaTypes.size(); i++)
{
arr[i] = metaTypes[i];
feature::FeatureMetadata::EMetadataType metaType = static_cast<feature::FeatureMetadata::EMetadataType>(metaTypes[i]);
jniEnv->SetObjectArrayElement(j_metaValues, i, jni::ToJavaString(jniEnv, metadata.Get(metaType)));
}
jniEnv->ReleaseIntArrayElements(j_metaTypes, arr, 0);
return make_pair(j_metaTypes, j_metaValues);
}
// POI
void CallOnPoiActivatedListener(shared_ptr<jobject> obj, m2::PointD const & globalPoint,
search::AddressInfo const & addrInfo, feature::FeatureMetadata const & metadata)
@ -832,22 +850,12 @@ extern "C"
const double lon = MercatorBounds::XToLon(globalPoint.x);
const double lat = MercatorBounds::YToLat(globalPoint.y);
const vector<feature::FeatureMetadata::EMetadataType> metaTypes = metadata.GetPresentTypes();
const jintArray j_metaTypes = jniEnv->NewIntArray(metadata.Size());
jint * arr = jniEnv->GetIntArrayElements(j_metaTypes, 0);
const jobjectArray j_metaValues = jniEnv->NewObjectArray(metadata.Size(), jni::GetStringClass(jniEnv), 0);
for (int i = 0; i < metaTypes.size(); i++)
{
arr[i] = metaTypes[i];
feature::FeatureMetadata::EMetadataType metaType = static_cast<feature::FeatureMetadata::EMetadataType>(metaTypes[i]);
jniEnv->SetObjectArrayElement(j_metaValues, i, jni::ToJavaString(jniEnv, metadata.Get(metaType)));
}
jniEnv->ReleaseIntArrayElements(j_metaTypes, arr, 0);
pair<jintArray, jobjectArray> const meta = NativeMetadataToJavaMetadata(jniEnv, metadata);
const char * signature = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;DD[I[Ljava/lang/String;)V";
const jmethodID methodId = jni::GetJavaMethodID(jniEnv, *obj.get(),
"onPoiActivated", signature);
jniEnv->CallVoidMethod(*obj.get(), methodId, j_name, j_type, j_address, lat, lon, j_metaTypes, j_metaValues);
jniEnv->CallVoidMethod(*obj.get(), methodId, j_name, j_type, j_address, lat, lon, meta.first, meta.second);
}
// Bookmark
@ -873,6 +881,7 @@ extern "C"
::Framework * fm = frm();
UserMark const * mark = markCopy->GetUserMark();
fm->ActivateUserMark(mark);
switch (mark->GetMarkType())
{
case UserMark::API:
@ -880,32 +889,43 @@ extern "C"
double lat, lon;
mark->GetLatLon(lat, lon);
CallOnApiPointActivatedListener(obj, CastMark<ApiMarkPoint>(mark), lat, lon);
break;
}
break;
case UserMark::BOOKMARK:
{
BookmarkAndCategory bmAndCat = fm->FindBookmark(mark);
if (IsValid(bmAndCat))
{
feature::FeatureMetadata metadata;
fm->FindClosestPOIMetadata(mark->GetOrg(), metadata);
CallOnBookmarkActivatedListener(obj, bmAndCat);
}
break;
}
break;
case UserMark::POI:
{
PoiMarkPoint const * poiMark = CastMark<PoiMarkPoint>(mark);
CallOnPoiActivatedListener(obj, mark->GetOrg(), poiMark->GetInfo(), poiMark->GetMetadata());
break;
}
break;
case UserMark::SEARCH:
{
SearchMarkPoint const * searchMark = CastMark<SearchMarkPoint>(mark);
feature::FeatureMetadata metadata;
fm->FindClosestPOIMetadata(mark->GetOrg(), metadata);
CallOnAdditionalLayerActivatedListener(obj, searchMark->GetOrg(), searchMark->GetInfo());
break;
}
case UserMark::MY_POSITION:
{
double lat, lon;
mark->GetLatLon(lat, lon);
CallOnMyPositionActivatedListener(obj, lat, lon);
break;
}
}
}

View file

@ -1731,6 +1731,60 @@ bool Framework::GetVisiblePOI(m2::PointD const & pxPoint, m2::PointD & pxPivot,
return false;
}
namespace
{
/// POI - is a point or area feature.
class DoFindClosestPOI
{
m2::PointD const & m_pt;
double m_distMeters;
FeatureID m_id;
public:
DoFindClosestPOI(m2::PointD const & pt, double tresholdMeters)
: m_pt(pt), m_distMeters(tresholdMeters)
{
}
void operator() (FeatureType & ft)
{
if (ft.GetFeatureType() == feature::GEOM_LINE)
return;
double const dist = MercatorBounds::DistanceOnEarth(m_pt, feature::GetCenter(ft));
if (dist < m_distMeters)
{
m_distMeters = dist;
m_id = ft.GetID();
}
}
void LoadMetadata(model::FeaturesFetcher const & model, feature::FeatureMetadata & metadata) const
{
if (!m_id.IsValid())
return;
Index::FeaturesLoaderGuard guard(model.GetIndex(), m_id.m_mwm);
FeatureType ft;
guard.GetFeature(m_id.m_offset, ft);
ft.ParseMetadata();
metadata = ft.GetMetadata();
}
};
}
void Framework::FindClosestPOIMetadata(m2::PointD const & pt, feature::FeatureMetadata & metadata) const
{
DoFindClosestPOI doFind(pt, 1.1 /* search radius in meters */);
m_model.ForEachFeature(m2::RectD(pt, pt), doFind, scales::GetUpperScale() /* scale level for POI */);
doFind.LoadMetadata(m_model, metadata);
}
Animator & Framework::GetAnimator()
{
return m_animator;

View file

@ -358,6 +358,7 @@ private:
public:
bool GetVisiblePOI(m2::PointD const & pxPoint, m2::PointD & pxPivot, search::AddressInfo & info, feature::FeatureMetadata & metadata) const;
void FindClosestPOIMetadata(m2::PointD const & pt, feature::FeatureMetadata & metadata) const;
#ifndef USE_DRAPE
virtual void BeginPaint(shared_ptr<PaintEvent> const & e);