[android] MapObject refactoring.

This commit is contained in:
Dmitry Yunitsky 2016-03-08 19:21:05 +03:00 committed by Sergey Yershov
parent e2b56e5486
commit 4d9be7af1b
11 changed files with 56 additions and 158 deletions

View file

@ -22,45 +22,20 @@ void InjectMetadata(JNIEnv * env, jclass const clazz, jobject const mapObject, f
}
}
pair<jintArray, jobjectArray> NativeMetadataToJavaMetadata(JNIEnv * env, Metadata const & metadata)
jobject CreateMapObject(JNIEnv * env, int mapObjectType, string const & title, string const & subtitle,
double lat, double lon, string const & address, Metadata const & metadata)
{
auto const metaTypes = metadata.GetPresentTypes();
const jintArray j_metaTypes = env->NewIntArray(metadata.Size());
jint * arr = env->GetIntArrayElements(j_metaTypes, 0);
const jobjectArray j_metaValues = env->NewObjectArray(metadata.Size(), jni::GetStringClass(env), 0);
for (size_t i = 0; i < metaTypes.size(); i++)
{
auto const type = metaTypes[i];
arr[i] = type;
// TODO: Refactor code to use separate getters for each metadata.
jni::TScopedLocalRef metaString(env, type == Metadata::FMD_WIKIPEDIA ?
jni::ToJavaString(env, metadata.GetWikiURL()) :
jni::ToJavaString(env, metadata.Get(type)));
env->SetObjectArrayElement(j_metaValues, i, metaString.get());
}
env->ReleaseIntArrayElements(j_metaTypes, arr, 0);
return make_pair(j_metaTypes, j_metaValues);
}
// TODO(yunikkk): displayed information does not need separate street and house.
// There is an AddressInfo::FormatAddress() method which should be used instead.
jobject CreateMapObject(JNIEnv * env, int mapObjectType, string const & name, double lat, double lon, string const & typeName, string const & street, string const & house, Metadata const & metadata)
{
// Java signature :
// public MapObject(@MapObjectType int mapObjectType, String name, double lat, double lon, String typeName, String street, String house)
// public MapObject(@MapObjectType int mapObjectType, String title, String subtitle, double lat, double lon, String address, Metadata metadata)
static jmethodID const ctorId =
jni::GetConstructorID(env, g_mapObjectClazz, "(ILjava/lang/String;DDLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
jni::GetConstructorID(env, g_mapObjectClazz, "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;DD)V");
jobject mapObject = env->NewObject(g_mapObjectClazz, ctorId,
static_cast<jint>(mapObjectType),
jni::ToJavaString(env, name),
jni::ToJavaString(env, title),
jni::ToJavaString(env, subtitle),
jni::ToJavaString(env, address),
static_cast<jdouble>(lat),
static_cast<jdouble>(lon),
jni::ToJavaString(env, typeName),
jni::ToJavaString(env, street),
jni::ToJavaString(env, house));
static_cast<jdouble>(lon));
InjectMetadata(env, g_mapObjectClazz, mapObject, metadata);
return mapObject;
@ -69,18 +44,18 @@ jobject CreateMapObject(JNIEnv * env, int mapObjectType, string const & name, do
jobject CreateMapObject(JNIEnv * env, place_page::Info const & info)
{
ms::LatLon const ll = info.GetLatLon();
if (info.IsMyPosition())
return CreateMapObject(env, kMyPosition, {}, ll.lat, ll.lon, {}, {}, {}, {});
search::AddressInfo const address = g_framework->NativeFramework()->GetAddressInfoAtPoint(info.GetMercator());
// TODO(yunikkk): object can be POI + API + search result + bookmark simultaneously.
if (info.HasApiUrl())
return CreateMapObject(env, kApiPoint, info.GetTitle(), ll.lat, ll.lon, info.GetSubtitle(), {}, {}, info.GetMetadata());
// TODO(yunikkk): Should we pass localized strings here and in other methods as byte arrays?
if (info.IsMyPosition())
return CreateMapObject(env, kMyPosition, {}, {}, ll.lat, ll.lon, address.FormatAddress(), {});
if (info.HasApiUrl())
return CreateMapObject(env, kApiPoint, info.GetTitle(), info.GetSubtitle(), ll.lat, ll.lon, address.FormatAddress(), info.GetMetadata());
// TODO(yunikkk): Bookmark can also be a feature.
if (info.IsBookmark())
{
// Java signature :
// public Bookmark(@IntRange(from = 0) int categoryId, @IntRange(from = 0) int bookmarkId, String name)
static jmethodID const ctorId = jni::GetConstructorID(env, g_bookmarkClazz, "(IILjava/lang/String;)V");
jni::TScopedLocalRef jName(env, jni::ToJavaString(env, info.GetTitle()));
@ -93,16 +68,7 @@ jobject CreateMapObject(JNIEnv * env, place_page::Info const & info)
return mapObject;
}
Framework * frm = g_framework->NativeFramework();
if (info.IsFeature())
{
search::AddressInfo const address = frm->GetFeatureAddressInfo(info.GetID());
// TODO(yunikkk): Pass address.FormatAddress() to UI instead of separate house and street.
// TODO(yunikkk): Should we pass localized strings here and in other methods as byte arrays?
return CreateMapObject(env, kPoi, info.GetTitle(), ll.lat, ll.lon, info.GetSubtitle(), address.m_street,
address.m_house, info.GetMetadata());
}
// User have selected an empty place on a map with a long tap.
return CreateMapObject(env, kPoi, info.GetTitle(), ll.lat, ll.lon, info.GetSubtitle(), {}, {}, {});
return CreateMapObject(env, kPoi, info.GetTitle(), info.GetSubtitle(), ll.lat, ll.lon, address.FormatAddress(),
info.IsFeature() ? info.GetMetadata() : Metadata());
}
} // namespace usermark_helper

View file

@ -26,13 +26,10 @@ static constexpr int kMyPosition = 3;
static constexpr int kSearch = 4;
// Fills mapobject's metadata.
//void InjectMetadata(JNIEnv * env, jclass clazz, jobject const mapObject, feature::Metadata const & metadata);
void InjectMetadata(JNIEnv * env, jclass clazz, jobject const mapObject, feature::Metadata const & metadata);
//pair<jintArray, jobjectArray> NativeMetadataToJavaMetadata(JNIEnv * env, feature::Metadata const & metadata);
jobject CreateMapObject(JNIEnv * env, int mapObjectType, string const & name, double lat, double lon,
string const & typeName, string const & street, string const & house,
feature::Metadata const & metadata);
jobject CreateMapObject(JNIEnv * env, int mapObjectType, string const & title, string const & subtitle,
double lat, double lon, feature::Metadata const & metadata);
jobject CreateMapObject(JNIEnv * env, place_page::Info const & info);
} // namespace usermark_helper

View file

@ -2,6 +2,7 @@
#include "com/mapswithme/maps/UserMarkHelper.hpp"
#include "com/mapswithme/core/jni_helper.hpp"
#include "map/place_page_info.hpp"
#include "platform/measurement_utils.hpp"
namespace
@ -75,19 +76,18 @@ Java_com_mapswithme_maps_bookmarks_data_BookmarkCategory_nativeGetTracksCount(
return getBmCategory(id)->GetTracksCount();
}
// TODO(AlexZ): Get rid of UserMarks completely in UI code.
// TODO(yunikkk): Refactor java code to get all necessary info without Bookmark wrapper, and without hierarchy.
// If bookmark information is needed in the BookmarkManager, it does not relate in any way to Place Page info
// and should be passed separately via simple name string and lat lon to calculate a distance.
JNIEXPORT jobject JNICALL
Java_com_mapswithme_maps_bookmarks_data_BookmarkCategory_nativeGetBookmark(
JNIEnv * env, jobject thiz, jint id, jint bmkId)
JNIEnv * env, jobject thiz, jint catId, jint bmkId)
{
BookmarkCategory * category = getBmCategory(id);
// TODO(AlexZ): Get rid of UserMarks completely in UI code.
Bookmark const * bm = static_cast<Bookmark const *>(category->GetUserMark(bmkId));
// TODO(yunikkk): Refactor java code to get all necessary info without Bookmark wrapper, and without hierarchy.
// If bookmark information is needed in the BookmarkManager, it does not relate in any way to Place Page info
// and should be passed separately via simple name string and lat lon to calculate a distance.
ms::LatLon const ll = bm->GetLatLon();
return usermark_helper::CreateMapObject(env, usermark_helper::kBookmark, bm->GetName(), ll.lat, ll.lon,
bm->GetType(), "", "", {});
BookmarkCategory * category = getBmCategory(catId);
place_page::Info info;
frm()->FillBookmarkInfo(*static_cast<Bookmark const *>(category->GetUserMark(bmkId)), {catId, bmkId}, info);
return usermark_helper::CreateMapObject(env, info);
}
static uint32_t shift(uint32_t v, uint8_t bitCount) { return v << bitCount; }

View file

@ -1006,8 +1006,9 @@ public class MwmActivity extends BaseMwmFragmentActivity
if (request == null)
return;
request.setPointData(object.getLat(), object.getLon(), object.getTitle(), object.getSearchId());
object.setTypeName(request.getCallerName(MwmApplication.get()).toString());
// TODO @yunikkk get point id for api point from core.
request.setPointData(object.getLat(), object.getLon(), object.getTitle(), "");
object.setSubtitle(request.getCallerName(MwmApplication.get()).toString());
}
else if (MapObject.isOfType(MapObject.MY_POSITION, object) &&
Framework.nativeIsRoutingActive())

View file

@ -18,13 +18,12 @@ public class Bookmark extends MapObject
private double mMerX;
private double mMerY;
Bookmark(@IntRange(from = 0) int categoryId, @IntRange(from = 0) int bookmarkId, String name)
Bookmark(@IntRange(from = 0) int categoryId, @IntRange(from = 0) int bookmarkId, String title)
{
super(BOOKMARK, name, 0, 0, "", "", "");
super(BOOKMARK, title, "", "", 0, 0);
mCategoryId = categoryId;
mBookmarkId = bookmarkId;
mTitle = name;
mIcon = getIconInternal();
initXY();
}

View file

@ -12,7 +12,6 @@ import java.lang.annotation.RetentionPolicy;
import com.mapswithme.maps.BuildConfig;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
// TODO(yunikkk): Refactor. Displayed information is different from edited information, and it's better to
// separate them. Simple getters from jni place_page::Info and osm::EditableFeature should be enough.
@ -31,59 +30,38 @@ public class MapObject implements Parcelable
@MapObjectType protected final int mMapObjectType;
protected String mTitle;
protected String mSubtitle;
protected double mLat;
protected double mLon;
protected String mSubtitle;
protected String mStreet;
protected String mHouseNumber;
protected String mAddress;
protected Metadata mMetadata;
protected boolean mIsDroppedPin;
protected String mSearchId;
// TODO @yunikkk add static factory methods for different mapobject creation
public MapObject(@MapObjectType int mapObjectType, String name, double lat, double lon, String typeName, String street, String house)
public MapObject(@MapObjectType int mapObjectType, String title, String subtitle, String address, double lat, double lon)
{
this(mapObjectType, name, lat, lon, typeName, street, house, new Metadata());
this(mapObjectType, title, subtitle, address, lat, lon, new Metadata());
}
public MapObject(@MapObjectType int mapObjectType, String name, double lat, double lon, String typeName, String street, String house, Metadata metadata)
public MapObject(@MapObjectType int mapObjectType, String title, String subtitle, String address, double lat, double lon, Metadata metadata)
{
mMapObjectType = mapObjectType;
mTitle = name;
mTitle = title;
mSubtitle = subtitle;
mAddress = address;
mLat = lat;
mLon = lon;
mSubtitle = typeName;
mStreet = street;
mHouseNumber = house;
mMetadata = metadata;
mIsDroppedPin = TextUtils.isEmpty(mTitle);
}
protected MapObject(Parcel source)
{
//noinspection ResourceType
this(source.readInt(), // MapObjectType
source.readString(), // Name
source.readString(), // Title
source.readString(), // Subtitle
source.readString(), // Address
source.readDouble(), // Lat
source.readDouble(), // Lon
source.readString(), // TypeName
source.readString(), // Street
source.readString(), // HouseNumber
(Metadata) source.readParcelable(Metadata.class.getClassLoader()));
mIsDroppedPin = source.readByte() != 0;
mSearchId = source.readString();
}
public void setDefaultIfEmpty()
{
if (TextUtils.isEmpty(mTitle))
mTitle = TextUtils.isEmpty(mSubtitle) ? MwmApplication.get().getString(R.string.dropped_pin)
: mSubtitle;
if (TextUtils.isEmpty(mSubtitle))
mSubtitle = MwmApplication.get().getString(R.string.placepage_unsorted);
}
/**
@ -122,17 +100,12 @@ public class MapObject implements Parcelable
public String getTitle() { return mTitle; }
public String getSubtitle() { return mSubtitle; }
public double getLat() { return mLat; }
public double getLon() { return mLon; }
public String getSubtitle() { return mSubtitle; }
public boolean getIsDroppedPin()
{
return mIsDroppedPin;
}
@NonNull
public String getMetadata(Metadata.MetadataType type)
{
@ -163,37 +136,12 @@ public class MapObject implements Parcelable
return result.toString();
}
public String getStreet()
{
return mStreet;
}
public String getHouseNumber()
{
return mHouseNumber;
}
@MapObjectType
public int getMapObjectType()
{
return mMapObjectType;
}
public String getSearchId()
{
return mSearchId;
}
public void setName(String name)
{
mTitle = name;
}
public void setHouseNumber(String houseNumber)
{
mHouseNumber = houseNumber;
}
public void setLat(double lat)
{
mLat = lat;
@ -204,7 +152,7 @@ public class MapObject implements Parcelable
mLon = lon;
}
public void setTypeName(String typeName)
public void setSubtitle(String typeName)
{
mSubtitle = typeName;
}
@ -225,11 +173,6 @@ public class MapObject implements Parcelable
addMetadata(types[i], values[i]);
}
public void setStreet(String street)
{
mStreet = street;
}
public static boolean isOfType(@MapObjectType int type, MapObject object)
{
return object != null && object.getMapObjectType() == type;
@ -256,14 +199,11 @@ public class MapObject implements Parcelable
dest.writeInt(mMapObjectType); // write map object type twice - first int is used to distinguish created object (MapObject or Bookmark)
dest.writeInt(mMapObjectType);
dest.writeString(mTitle);
dest.writeString(mSubtitle);
dest.writeString(mAddress);
dest.writeDouble(mLat);
dest.writeDouble(mLon);
dest.writeString(mSubtitle);
dest.writeString(mStreet);
dest.writeString(mHouseNumber);
dest.writeParcelable(mMetadata, 0);
dest.writeByte((byte) (mIsDroppedPin ? 1 : 0));
dest.writeString(mSearchId);
}
public static final Creator<MapObject> CREATOR = new Creator<MapObject>()

View file

@ -176,7 +176,7 @@ public enum LocationHelper implements SensorEventListener
return null;
if (mMyPosition == null)
mMyPosition = new MapObject(MapObject.MY_POSITION, "", mLastLocation.getLatitude(), mLastLocation.getLongitude(), "", "", "");
mMyPosition = new MapObject(MapObject.MY_POSITION, "", "", "", mLastLocation.getLatitude(), mLastLocation.getLongitude());
return mMyPosition;
}

View file

@ -107,9 +107,6 @@ public class SlotFrame extends LinearLayout
void setMapObject(MapObject mapObject)
{
mMapObject = mapObject;
if (mMapObject != null)
mMapObject.setDefaultIfEmpty();
updateText();
}

View file

@ -343,7 +343,7 @@ public class SearchFragment extends BaseMwmFragment
if (mFromRoutePlan)
{
//noinspection ConstantConditions
final MapObject point = new MapObject(MapObject.SEARCH, result.name, result.lat, result.lon, result.description.featureType, "", "");
final MapObject point = new MapObject(MapObject.SEARCH, result.name, result.description.featureType, "", result.lat, result.lon);
RoutingController.get().onPoiSelected(point);
}

View file

@ -371,8 +371,6 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene
if (mMapObject == null)
return;
mMapObject.setDefaultIfEmpty();
refreshPreview();
refreshDetails();
final Location loc = LocationHelper.INSTANCE.getLastLocation();
@ -418,8 +416,7 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene
mTvTitle.setText(mMapObject.getTitle());
if (mToolbar != null)
mToolbar.setTitle(mMapObject.getTitle());
String subtitle = mMapObject.getSubtitle();
mTvSubtitle.setText(subtitle);
mTvSubtitle.setText(mMapObject.getSubtitle());
mAvDirection.setVisibility(View.GONE);
}

View file

@ -474,7 +474,6 @@ private:
/// @returns true if command was handled by editor.
bool ParseEditorDebugCommand(search::SearchParams const & params);
void FillBookmarkInfo(Bookmark const & bmk, BookmarkAndCategory const & bac, place_page::Info & info) const;
void FillFeatureInfo(FeatureID const & fid, place_page::Info & info) const;
/// @param customTitle, if not empty, overrides any other calculated name.
void FillPointInfo(m2::PointD const & mercator, string const & customTitle, place_page::Info & info) const;
@ -482,6 +481,8 @@ private:
void FillMyPositionInfo(place_page::Info & info) const;
public:
void FillBookmarkInfo(Bookmark const & bmk, BookmarkAndCategory const & bac, place_page::Info & info) const;
/// @returns address of nearby building with house number in approx 1km distance.
search::AddressInfo GetAddressInfoAtPoint(m2::PointD const & pt) const;
/// @returns valid street address only if it was specified in OSM for given feature; used in the editor.