Merge pull request #2850 from VladiMihaylenko/master

[omim] Added localized name in street.
This commit is contained in:
Alex Zolotarev 2016-04-11 19:49:02 +04:00
commit d111f686d7
9 changed files with 95 additions and 65 deletions

View file

@ -185,13 +185,15 @@ Java_com_mapswithme_maps_editor_Editor_nativeSetDefaultName(JNIEnv * env, jclass
JNIEXPORT jstring JNICALL
Java_com_mapswithme_maps_editor_Editor_nativeGetStreet(JNIEnv * env, jclass)
{
return jni::ToJavaString(env, g_editableMapObject.GetStreet());
// TODO(yunikkk): use "GetStreet().m_localizedName" to get localized street
return jni::ToJavaString(env, g_editableMapObject.GetStreet().m_defaultName);
}
JNIEXPORT void JNICALL
Java_com_mapswithme_maps_editor_Editor_nativeSetStreet(JNIEnv * env, jclass, jstring street)
{
g_editableMapObject.SetStreet(jni::ToNativeString(env, street));
//TODO(yunikkk): pass original localized street name as a second parameter.
g_editableMapObject.SetStreet({jni::ToNativeString(env, street), ""});
}
JNIEXPORT jstring JNICALL
@ -213,7 +215,8 @@ Java_com_mapswithme_maps_editor_Editor_nativeGetNearbyStreets(JNIEnv * env, jcla
int const size = streets.size();
jobjectArray jStreets = env->NewObjectArray(size, jni::GetStringClass(env), 0);
for (int i = 0; i < size; ++i)
env->SetObjectArrayElement(jStreets, i, jni::TScopedLocalRef(env, jni::ToJavaString(env, streets[i])).get());
// TODO(yunikkk): use "streets[i].m_localizedName" to get localized street.
env->SetObjectArrayElement(jStreets, i, jni::TScopedLocalRef(env, jni::ToJavaString(env, streets[i].m_defaultName)).get());
return jStreets;
}

View file

@ -36,7 +36,7 @@ vector<LocalizedName> EditableMapObject::GetLocalizedNames() const
return result;
}
vector<string> const & EditableMapObject::GetNearbyStreets() const { return m_nearbyStreets; }
vector<LocalizedStreet> const & EditableMapObject::GetNearbyStreets() const { return m_nearbyStreets; }
string const & EditableMapObject::GetHouseNumber() const { return m_houseNumber; }
string EditableMapObject::GetPostcode() const
@ -85,9 +85,9 @@ void EditableMapObject::SetType(uint32_t featureType)
}
void EditableMapObject::SetID(FeatureID const & fid) { m_featureID = fid; }
void EditableMapObject::SetStreet(string const & street) { m_street = street; }
void EditableMapObject::SetStreet(LocalizedStreet const & st) { m_street = st; }
void EditableMapObject::SetNearbyStreets(vector<string> && streets)
void EditableMapObject::SetNearbyStreets(vector<LocalizedStreet> && streets)
{
m_nearbyStreets = move(streets);
}
@ -193,7 +193,7 @@ void EditableMapObject::SetBuildingLevels(string const & buildingLevels)
m_metadata.Set(feature::Metadata::FMD_BUILDING_LEVELS, buildingLevels);
}
string const & EditableMapObject::GetStreet() const { return m_street; }
LocalizedStreet const & EditableMapObject::GetStreet() const { return m_street; }
void EditableMapObject::SetCuisines(vector<string> const & cuisine)
{

View file

@ -43,6 +43,14 @@ struct LocalizedName
string const m_name;
};
struct LocalizedStreet
{
string m_defaultName;
string m_localizedName;
bool operator==(LocalizedStreet const & st) const { return m_defaultName == st.m_defaultName; }
};
class EditableMapObject : public MapObject
{
public:
@ -55,8 +63,8 @@ public:
StringUtf8Multilang const & GetName() const;
vector<LocalizedName> GetLocalizedNames() const;
string const & GetStreet() const;
vector<string> const & GetNearbyStreets() const;
LocalizedStreet const & GetStreet() const;
vector<LocalizedStreet> const & GetNearbyStreets() const;
string const & GetHouseNumber() const;
string GetPostcode() const;
string GetWikipedia() const;
@ -69,8 +77,8 @@ public:
void SetType(uint32_t featureType);
void SetID(FeatureID const & fid);
// void SetTypes(feature::TypesHolder const & types);
void SetStreet(string const & street);
void SetNearbyStreets(vector<string> && streets);
void SetStreet(LocalizedStreet const & st);
void SetNearbyStreets(vector<LocalizedStreet> && streets);
/// @returns false if house number fails validation.
static bool ValidateHouseNumber(string const & houseNumber);
void SetHouseNumber(string const & houseNumber);
@ -95,8 +103,8 @@ public:
private:
string m_houseNumber;
string m_street;
vector<string> m_nearbyStreets;
LocalizedStreet m_street;
vector<LocalizedStreet> m_nearbyStreets;
EditableProperties m_editableProperties;
};
} // namespace osm

View file

@ -406,14 +406,14 @@ Editor::SaveResult Editor::SaveEditedFeature(EditableMapObject const & emo)
fti.m_feature.ReplaceBy(emo);
bool const sameAsInMWM = featureStatus != FeatureStatus::Created &&
AreFeaturesEqualButStreet(fti.m_feature, *m_getOriginalFeatureFn(fid)) &&
emo.GetStreet() == m_getOriginalFeatureStreetFn(fti.m_feature);
emo.GetStreet().m_defaultName == m_getOriginalFeatureStreetFn(fti.m_feature);
if (featureStatus != FeatureStatus::Untouched)
{
// A feature was modified and equals to the one in editor.
auto const & editedFeatureInfo = m_features[fid.m_mwmId][fid.m_index];
if (AreFeaturesEqualButStreet(fti.m_feature, editedFeatureInfo.m_feature) &&
emo.GetStreet() == editedFeatureInfo.m_street)
emo.GetStreet().m_defaultName == editedFeatureInfo.m_street)
{
return NothingWasChanged;
}
@ -448,7 +448,7 @@ Editor::SaveResult Editor::SaveEditedFeature(EditableMapObject const & emo)
// TODO: What if local client time is absolutely wrong?
fti.m_modificationTimestamp = time(nullptr);
fti.m_street = emo.GetStreet();
fti.m_street = emo.GetStreet().m_defaultName;
// Reset upload status so already uploaded features can be uploaded again after modification.
fti.m_uploadStatus = {};

View file

@ -349,7 +349,7 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
MWMEditorSelectTableViewCell * tCell = (MWMEditorSelectTableViewCell *)cell;
[tCell configWithDelegate:self
icon:[UIImage imageNamed:@"ic_placepage_adress"]
text:@(m_mapObject.GetStreet().c_str())
text:@(m_mapObject.GetStreet().m_defaultName.c_str())
placeholder:L(@"add_street")];
break;
}
@ -594,23 +594,19 @@ NSString * reuseIdentifier(MWMPlacePageCellType cellType)
#pragma mark - MWMStreetEditorProtocol
- (NSString *)getStreet
- (void)setNearbyStreet:(osm::LocalizedStreet const &)street
{
return @(m_mapObject.GetStreet().c_str());
m_mapObject.SetStreet(street);
}
- (void)setStreet:(NSString *)street
- (osm::LocalizedStreet const &)currentStreet
{
m_mapObject.SetStreet(street.UTF8String);
return m_mapObject.GetStreet();
}
- (NSArray<NSString *> *)getNearbyStreets
- (vector<osm::LocalizedStreet> const &)nearbyStreets
{
auto const & streets = m_mapObject.GetNearbyStreets();
NSMutableArray * arr = [[NSMutableArray alloc] initWithCapacity:streets.size()];
for (auto const & street : streets)
[arr addObject:@(street.c_str())];
return arr;
return m_mapObject.GetNearbyStreets();
}
#pragma mark - Segue

View file

@ -1,11 +1,14 @@
#import "MWMTableViewController.h"
#include "indexer/editable_map_object.hpp"
#include "std/vector.hpp"
@protocol MWMStreetEditorProtocol <NSObject>
- (NSString *)getStreet;
- (void)setStreet:(NSString *)street;
- (NSArray<NSString *> *)getNearbyStreets;
- (osm::LocalizedStreet const &)currentStreet;
- (void)setNearbyStreet:(osm::LocalizedStreet const &)street;
- (vector<osm::LocalizedStreet> const &)nearbyStreets;
@end

View file

@ -6,15 +6,17 @@ namespace
NSString * const kStreetEditorEditCell = @"MWMStreetEditorEditTableViewCell";
} // namespace
@interface MWMStreetEditorViewController () <MWMStreetEditorEditCellProtocol>
using namespace osm;
@property (nonatomic) NSMutableArray<NSString *> * streets;
@interface MWMStreetEditorViewController () <MWMStreetEditorEditCellProtocol>
{
vector<osm::LocalizedStreet> m_streets;
string m_editedStreetName;
}
@property (nonatomic) NSUInteger selectedStreet;
@property (nonatomic) NSUInteger lastSelectedStreet;
@property (nonatomic) NSString * editedStreetName;
@end
@implementation MWMStreetEditorViewController
@ -45,18 +47,23 @@ namespace
- (void)configData
{
self.streets = [[self.delegate getNearbyStreets] mutableCopy];
NSString * currentStreet = [self.delegate getStreet];
BOOL const haveCurrentStreet = (currentStreet && currentStreet.length != 0);
m_streets = self.delegate.nearbyStreets;
auto const & currentStreet = self.delegate.currentStreet;
BOOL const haveCurrentStreet = !currentStreet.m_defaultName.empty();
if (haveCurrentStreet)
{
[self.streets removeObject:currentStreet];
[self.streets insertObject:currentStreet atIndex:0];
auto const it = find(m_streets.begin(), m_streets.end(), currentStreet);
self.selectedStreet = it - m_streets.begin();
}
else
{
self.selectedStreet = NSNotFound;
}
self.editedStreetName = @"";
self.selectedStreet = haveCurrentStreet ? 0 : NSNotFound;
self.lastSelectedStreet = NSNotFound;
self.navigationItem.rightBarButtonItem.enabled = haveCurrentStreet;
self.lastSelectedStreet = NSNotFound;
m_editedStreetName = "";
}
- (void)configTable
@ -74,8 +81,11 @@ namespace
- (void)onDone
{
NSString * street = (self.selectedStreet == NSNotFound ? self.editedStreetName : self.streets[self.selectedStreet]);
[self.delegate setStreet:street];
if (self.selectedStreet == NSNotFound)
[self.delegate setNearbyStreet:{m_editedStreetName, ""}];
else
[self.delegate setNearbyStreet:m_streets[self.selectedStreet]];
[self onCancel];
}
@ -84,12 +94,13 @@ namespace
if ([cell isKindOfClass:[MWMStreetEditorEditTableViewCell class]])
{
MWMStreetEditorEditTableViewCell * tCell = (MWMStreetEditorEditTableViewCell *)cell;
[tCell configWithDelegate:self street:self.editedStreetName];
[tCell configWithDelegate:self street:@(m_editedStreetName.c_str())];
}
else
{
NSUInteger const index = indexPath.row;
NSString * street = self.streets[index];
// TODO: also display localized name if it exists.
NSString * street = @(m_streets[index].m_defaultName.c_str());
BOOL const selected = (self.selectedStreet == index);
cell.textLabel.text = street;
cell.accessoryType = selected ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
@ -103,7 +114,7 @@ namespace
if (text && text.length != 0)
{
self.navigationItem.rightBarButtonItem.enabled = YES;
self.editedStreetName = text;
m_editedStreetName = text.UTF8String;
if (self.selectedStreet != NSNotFound)
{
self.lastSelectedStreet = self.selectedStreet;
@ -128,8 +139,7 @@ namespace
- (UITableViewCell * _Nonnull)tableView:(UITableView * _Nonnull)tableView cellForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath
{
NSUInteger const streetsCount = self.streets.count;
if (streetsCount == 0)
if (m_streets.empty())
return [tableView dequeueReusableCellWithIdentifier:kStreetEditorEditCell];
if (indexPath.section == 0)
return [tableView dequeueReusableCellWithIdentifier:[UITableViewCell className]];
@ -139,7 +149,7 @@ namespace
- (NSInteger)tableView:(UITableView * _Nonnull)tableView numberOfRowsInSection:(NSInteger)section
{
NSUInteger const count = self.streets.count;
auto const count = m_streets.size();
if ((section == 0 && count == 0) || section != 0)
return 1;
return count;
@ -147,7 +157,7 @@ namespace
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.streets.count > 0 ? 2 : 1;
return m_streets.empty()? 1 : 2;
}
#pragma mark - UITableViewDelegate

View file

@ -2448,21 +2448,23 @@ bool Framework::ParseEditorDebugCommand(search::SearchParams const & params)
namespace
{
vector<string> FilterNearbyStreets(vector<search::ReverseGeocoder::Street> const & streets,
string const & exactFeatureStreet = "")
vector<osm::LocalizedStreet> FilterNearbyStreets(vector<search::ReverseGeocoder::Street> const & streets,
string const & exactFeatureStreet = "")
{
vector<string> results;
vector<osm::LocalizedStreet> results;
// Exact feature street always goes first in Editor UI street list.
// TODO: Push into result LocalizedStreet object with default and localized street name.
if (!exactFeatureStreet.empty())
results.push_back(exactFeatureStreet);
results.push_back({exactFeatureStreet, ""});
// Reasonable number of different nearby street names to display in UI.
constexpr size_t kMaxNumberOfNearbyStreetsToDisplay = 8;
for (auto const & street : streets)
{
auto const e = results.end();
if (e == find(results.begin(), e, street.m_name))
osm::LocalizedStreet const st{street.m_name, ""};
if (find(results.begin(), results.end(), st) == results.end())
{
results.push_back(street.m_name);
results.push_back(st);
if (results.size() >= kMaxNumberOfNearbyStreetsToDisplay)
break;
}
@ -2518,10 +2520,12 @@ bool Framework::GetEditableMapObject(FeatureID const & fid, osm::EditableMapObje
street = streets.first[streets.second].m_name;
emo.SetNearbyStreets(FilterNearbyStreets(streets.first, street));
}
emo.SetStreet(street);
//TODO: We have to set default and localized name if last one exists.
emo.SetStreet({street, ""});
return true;
}
osm::Editor::SaveResult Framework::SaveEditedMapObject(osm::EditableMapObject const & emo)
{
if (!m_lastTapEvent)

View file

@ -81,15 +81,18 @@ EditorDialog::EditorDialog(QWidget * parent, osm::EditableMapObject & emo)
if (emo.IsAddressEditable())
{ // Address rows.
vector<string> nearbyStreets = emo.GetNearbyStreets();
auto nearbyStreets = emo.GetNearbyStreets();
// If feature does not have a specified street, display empty combo box.
if (emo.GetStreet().empty())
nearbyStreets.insert(nearbyStreets.begin(), "");
if (emo.GetStreet().m_defaultName.empty())
nearbyStreets.insert(nearbyStreets.begin(), {});
grid->addWidget(new QLabel(kStreetObjectName), row, 0);
QComboBox * cmb = new QComboBox();
for (int i = 0; i < nearbyStreets.size(); ++i)
{
cmb->addItem(nearbyStreets[i].c_str());
string street = nearbyStreets[i].m_defaultName;
if (!nearbyStreets[i].m_localizedName.empty())
street += " / " + nearbyStreets[i].m_localizedName;
cmb->addItem(street.c_str());
if (emo.GetStreet() == nearbyStreets[i])
cmb->setCurrentIndex(i);
}
@ -195,7 +198,10 @@ void EditorDialog::OnSave()
if (m_feature.IsAddressEditable())
{
m_feature.SetHouseNumber(findChild<QLineEdit *>(kHouseNumberObjectName)->text().toStdString());
m_feature.SetStreet(findChild<QComboBox *>(kStreetObjectName)->currentText().toStdString());
QString const editedStreet = findChild<QComboBox *>(kStreetObjectName)->currentText();
QStringList const names = editedStreet.split(" / ", QString::SkipEmptyParts);
QString const localized = names.size() > 1 ? names.at(1) : QString();
m_feature.SetStreet({names.at(0).toStdString(), localized.toStdString()});
m_feature.SetPostcode(findChild<QLineEdit *>(kPostcodeObjectName)->text().toStdString());
}