Skip to content

Commit

Permalink
IsNumberGeographical public + better detection of "geographical numbe…
Browse files Browse the repository at this point in the history
…rs" in geocoder (#1277)

Making function IsNumberGeographical public. This function operates on
the type of number and the country it belongs to only, so may have some
false positives.

Using this in the geocoder so that geocoding now limited to numbers that
we consider geographical, based on their type and country, rather than
just based on their type. The C++ geocoder did not previously check the
number type/country at all.

Indonesian and Chinese mobile numbers have now been added to the list of
possibly-geographical numbers.
  • Loading branch information
lararennie authored and keghani committed Aug 23, 2016
1 parent 0c3b2c3 commit 7c84d36
Show file tree
Hide file tree
Showing 15 changed files with 792 additions and 631 deletions.
14 changes: 12 additions & 2 deletions cpp/src/phonenumbers/geocoding/phonenumber_offline_geocoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,27 @@ string PhoneNumberOfflineGeocoder::GetDescriptionForValidNumber(

string PhoneNumberOfflineGeocoder::GetDescriptionForNumber(
const PhoneNumber& number, const Locale& locale) const {
if (!phone_util_->IsValidNumber(number)) {
PhoneNumberUtil::PhoneNumberType number_type =
phone_util_->GetNumberType(number);
if (number_type == PhoneNumberUtil::UNKNOWN) {
return "";
} else if (!phone_util_->IsNumberGeographical(number_type,
number.country_code())) {
return GetCountryNameForNumber(number, locale);
}
return GetDescriptionForValidNumber(number, locale);
}

string PhoneNumberOfflineGeocoder::GetDescriptionForNumber(
const PhoneNumber& number, const Locale& language,
const string& user_region) const {
if (!phone_util_->IsValidNumber(number)) {
PhoneNumberUtil::PhoneNumberType number_type =
phone_util_->GetNumberType(number);
if (number_type == PhoneNumberUtil::UNKNOWN) {
return "";
} else if (!phone_util_->IsNumberGeographical(number_type,
number.country_code())) {
return GetCountryNameForNumber(number, language);
}
return GetDescriptionForValidNumber(number, language, user_region);
}
Expand Down
33 changes: 30 additions & 3 deletions cpp/src/phonenumbers/phonenumberutil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,15 @@ class PhoneNumberRegExpsAndMappings {

mobile_token_mappings_.insert(std::make_pair(52, '1'));
mobile_token_mappings_.insert(std::make_pair(54, '9'));
geo_mobile_countries_without_mobile_area_codes_.insert(86); // China
geo_mobile_countries_.insert(52); // Mexico
geo_mobile_countries_.insert(54); // Argentina
geo_mobile_countries_.insert(55); // Brazil
// Indonesia: some prefixes only (fixed CMDA wireless)
geo_mobile_countries_.insert(62);
geo_mobile_countries_.insert(
geo_mobile_countries_without_mobile_area_codes_.begin(),
geo_mobile_countries_without_mobile_area_codes_.end());
}

// Small string helpers since StrCat has a maximum number of arguments. These
Expand Down Expand Up @@ -448,6 +454,13 @@ class PhoneNumberRegExpsAndMappings {
// the length of the mobile token.
map<int, char> mobile_token_mappings_;

// Set of country codes that have geographically assigned mobile numbers (see
// geo_mobile_countries_ below) which are not based on *area codes*. For
// example, in China mobile numbers start with a carrier indicator, and beyond
// that are geographically assigned: this carrier indicator is not considered
// to be an area code.
set<int> geo_mobile_countries_without_mobile_area_codes_;

// Set of country calling codes that have geographically assigned mobile
// numbers. This may not be complete; we add calling codes case by case, as we
// find geographical mobile numbers or hear from user reports.
Expand Down Expand Up @@ -538,6 +551,7 @@ class PhoneNumberRegExpsAndMappings {
alpha_phone_mappings_(),
all_plus_number_grouping_symbols_(),
mobile_token_mappings_(),
geo_mobile_countries_without_mobile_area_codes_(),
geo_mobile_countries_(),
unique_international_prefix_(regexp_factory_->CreateRegExp(
/* "[\\d]+(?:[~⁓∼~][\\d]+)?" */
Expand Down Expand Up @@ -2148,11 +2162,15 @@ bool PhoneNumberUtil::IsValidNumberForRegion(const PhoneNumber& number,

bool PhoneNumberUtil::IsNumberGeographical(
const PhoneNumber& phone_number) const {
PhoneNumberType number_type = GetNumberType(phone_number);
return IsNumberGeographical(GetNumberType(phone_number),
phone_number.country_code());
}

bool PhoneNumberUtil::IsNumberGeographical(
PhoneNumberType number_type, int country_calling_code) const {
return number_type == PhoneNumberUtil::FIXED_LINE ||
number_type == PhoneNumberUtil::FIXED_LINE_OR_MOBILE ||
(reg_exps_->geo_mobile_countries_.find(phone_number.country_code())
(reg_exps_->geo_mobile_countries_.find(country_calling_code)
!= reg_exps_->geo_mobile_countries_.end() &&
number_type == PhoneNumberUtil::MOBILE);
}
Expand Down Expand Up @@ -2293,7 +2311,16 @@ int PhoneNumberUtil::GetLengthOfGeographicalAreaCode(
return 0;
}

if (!IsNumberGeographical(number)) {
PhoneNumberType type = GetNumberType(number);
int country_calling_code = number.country_code();
if (type == PhoneNumberUtil::MOBILE &&
reg_exps_->geo_mobile_countries_without_mobile_area_codes_.find(
country_calling_code) !=
reg_exps_->geo_mobile_countries_without_mobile_area_codes_.end()) {
return 0;
}

if (!IsNumberGeographical(type, country_calling_code)) {
return 0;
}

Expand Down
19 changes: 14 additions & 5 deletions cpp/src/phonenumbers/phonenumberutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,20 @@ class PhoneNumberUtil : public Singleton<PhoneNumberUtil> {
const string& number,
const string& region_dialing_from) const;

// Tests whether a phone number has a geographical association. It checks if
// the number is associated to a certain region in the country where it
// belongs to. Note that this doesn't verify if the number is actually in use.
bool IsNumberGeographical(const PhoneNumber& phone_number) const;

// Tests whether a phone number has a geographical association, as represented
// by its type and the country it belongs to.
//
// This version of IsNumberGeographical exists since calculating the phone
// number type is expensive; if we have already done this, we don't want to do
// it again.
bool IsNumberGeographical(PhoneNumberType phone_number_type,
int country_calling_code) const;

// Gets a valid fixed-line number for the specified region. Returns false if
// the region was unknown, or the region 001 is passed in. For 001
// (representing non-geographical numbers), call
Expand Down Expand Up @@ -719,11 +733,6 @@ class PhoneNumberUtil : public Singleton<PhoneNumberUtil> {
// Trims unwanted end characters from a phone number string.
void TrimUnwantedEndChars(string* number) const;

// Tests whether a phone number has a geographical association. It checks if
// the number is associated to a certain region in the country where it
// belongs to. Note that this doesn't verify if the number is actually in use.
bool IsNumberGeographical(const PhoneNumber& phone_number) const;

// Helper function to check region code is not unknown or null.
bool IsValidRegionCode(const string& region_code) const;

Expand Down
Loading

0 comments on commit 7c84d36

Please sign in to comment.