OpenTREP Logo  0.07.11
C++ Open Travel Request Parsing Library
Place.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 // OpenTrep
11 #include <opentrep/bom/Place.hpp>
13 
14 namespace OPENTREP {
15 
16  // //////////////////////////////////////////////////////////////////////
17  Place::Place() :
18  _world (NULL), _placeHolder (NULL), _mainPlace (NULL),
19  _location (IATACode_T (""), IATAType::LAST_VALUE, 0,
20  ICAOCode_T (""), FAACode_T (""),
21  CommonName_T (""), ASCIIName_T (""), 0,
22  Date_T (1970, 01, 01), Date_T (2999, 12, 31), Comment_T (""),
24  StateCode_T (""),
25  CountryCode_T (""), AltCountryCode_T (""), CountryName_T (""),
26  0, WACName_T (""),
27  CurrencyCode_T (""), ContinentName_T (""),
28  0.0, 0.0,
29  FeatureClass_T (""), FeatureCode_T (""),
30  Admin1Code_T (""), Admin1UTFName_T (""), Admin1ASCIIName_T (""),
31  Admin2Code_T (""), Admin2UTFName_T (""), Admin2ASCIIName_T (""),
32  Admin3Code_T (""), Admin4Code_T (""),
33  0, 0, 0, TimeZone_T (""), 0, 0, 0,
34  Date_T (2000, 01, 01), TvlPORListString_T (""),
35  WikiLink_T (""), 0.0, 0.0, K_DEFAULT_PAGE_RANK, "", "", 0, 0, 0,
36  RawDataString_T ("")),
37  _docID (0) {
38  }
39 
40  // //////////////////////////////////////////////////////////////////////
41  Place::Place (const LocationKey& iKey) :
42  _world (NULL), _placeHolder (NULL), _mainPlace (NULL),
43  _location (iKey.getIataCode(), iKey.getIataType(), iKey.getGeonamesID(),
44  ICAOCode_T (""), FAACode_T (""),
45  CommonName_T (""), ASCIIName_T (""), 0,
46  Date_T (1970, 01, 01), Date_T (2999, 12, 31), Comment_T (""),
48  StateCode_T (""),
49  CountryCode_T (""), AltCountryCode_T (""), CountryName_T (""),
50  0, WACName_T (""),
51  CurrencyCode_T (""), ContinentName_T (""),
52  0.0, 0.0,
53  FeatureClass_T (""), FeatureCode_T (""),
54  Admin1Code_T (""), Admin1UTFName_T (""), Admin1ASCIIName_T (""),
55  Admin2Code_T (""), Admin2UTFName_T (""), Admin2ASCIIName_T (""),
56  Admin3Code_T (""), Admin4Code_T (""),
57  0, 0, 0, TimeZone_T (""), 0, 0, 0,
58  Date_T (2000, 01, 01), TvlPORListString_T (""),
59  WikiLink_T (""), 0.0, 0.0, K_DEFAULT_PAGE_RANK, "", "", 0, 0, 0,
60  RawDataString_T ("")),
61  _docID (0) {
62  }
63 
64  // //////////////////////////////////////////////////////////////////////
65  Place::Place (const Location& iLocation) :
66  _world (NULL), _placeHolder (NULL), _mainPlace (NULL),
67  _location (iLocation), _docID (0) {
68  }
69 
70  // //////////////////////////////////////////////////////////////////////
71  Place::Place (const Place& iPlace) :
72  _world (iPlace._world), _placeHolder (iPlace._placeHolder),
73  _mainPlace (iPlace._mainPlace),
74  _location (iPlace._location),
75  _docID (iPlace._docID),
76  _termSetMap (iPlace._termSetMap), _spellingSet (iPlace._spellingSet),
77  _stemmingSet (iPlace._stemmingSet), _synonymSet (iPlace._synonymSet) {
78  }
79 
80  // //////////////////////////////////////////////////////////////////////
81  Place::~Place() {
82  }
83 
84  // //////////////////////////////////////////////////////////////////////
85  std::string Place::toString() const {
86  std::ostringstream oStr;
87  oStr << _location.toString();
88  oStr << ", " << _docID
89  << ". ";
90 
91  if (_extraPlaceList.empty() == false) {
92  oStr << "; Extra matches: {";
93  unsigned short idx = 0;
94  for (PlaceOrderedList_T::const_iterator itLoc = _extraPlaceList.begin();
95  itLoc != _extraPlaceList.end(); ++itLoc, ++idx) {
96  if (idx != 0) {
97  oStr << "; ";
98  }
99  const Place* lExtraPlace_ptr = *itLoc;
100  assert (lExtraPlace_ptr != NULL);
101  oStr << lExtraPlace_ptr->toShortString();
102  }
103  oStr << "}";
104  }
105 
106  if (_alternatePlaceList.empty() == false) {
107  oStr << "; Alternate matches: {";
108  unsigned short idx = 0;
109  for (PlaceOrderedList_T::const_iterator itLoc =
110  _alternatePlaceList.begin();
111  itLoc != _alternatePlaceList.end(); ++itLoc, ++idx) {
112  if (idx != 0) {
113  oStr << "; ";
114  }
115  const Place* lAlternatePlace_ptr = *itLoc;
116  assert (lAlternatePlace_ptr != NULL);
117  oStr << lAlternatePlace_ptr->toShortString();
118  }
119  oStr << "}";
120  }
121 
122  return oStr.str();
123  }
124 
125  // //////////////////////////////////////////////////////////////////////
126  std::string Place::toShortString() const {
132  std::ostringstream oStr;
133  oStr << _location.toShortString();
134  oStr << ", " << _docID;
135 
136  if (_extraPlaceList.empty() == false) {
137  oStr << " " << _extraPlaceList.size() << " extra match(es)";
138  }
139 
140  if (_alternatePlaceList.empty() == false) {
141  oStr << " " << _alternatePlaceList.size() << " alternate match(es)";
142  }
143 
144  return oStr.str();
145  }
146 
147  // //////////////////////////////////////////////////////////////////////
148  void Place::toStream (std::ostream& ioOut) const {
149  ioOut << toString();
150  }
151 
152  // //////////////////////////////////////////////////////////////////////
153  void Place::fromStream (std::istream& ioIn) {
154  }
155 
156  // //////////////////////////////////////////////////////////////////////
157  std::string Place::describeSets() const {
158  std::ostringstream oStr;
159 
160  // Xapian index for the current place/POR (point of reference)
161  oStr << "[index] ";
162  short idx_map = 0;
163  for (TermSetMap_T::const_iterator itStringSet = _termSetMap.begin();
164  itStringSet != _termSetMap.end(); ++itStringSet, ++idx_map) {
165  if (idx_map != 0) {
166  oStr << " - ";
167  }
168  // Retrieve the weight and display it
169  const Weight_T& lWeight = itStringSet->first;
170  oStr << "[" << lWeight << "] ";
171 
172  // Retrieve and browse the set of strings for that weight
173  const StringSet_T& lStringSet = itStringSet->second;
174  short idx_set = 0;
175  for (StringSet_T::const_iterator itString = lStringSet.begin();
176  itString != lStringSet.end(); ++itString, ++idx_set) {
177  if (idx_set != 0) {
178  oStr << ", ";
179  }
180  const std::string& lString = *itString;
181  oStr << lString;
182  }
183  }
184 
185  // Xapian spelling dictionary
186  oStr << "; [spelling] ";
187  short idx = 0;
188  for (StringSet_T::const_iterator itTerm = _spellingSet.begin();
189  itTerm != _spellingSet.end(); ++itTerm, ++idx) {
190  if (idx != 0) {
191  oStr << ", ";
192  }
193  const std::string& lTerm = *itTerm;
194  oStr << lTerm;
195  }
196  oStr << ";";
197 
198  return oStr.str();
199  }
200 
201  // //////////////////////////////////////////////////////////////////////
202  std::string Place::shortDisplay() const {
203  /* When the city code is empty, it means that the place is a city and
204  not an airport. The city code is thus the same as the place code
205  itself. */
206  std::ostringstream oStr;
207  oStr << _location.toBasicString();
208  oStr << ", " << _docID;
209  return oStr.str();
210  }
211 
212  // //////////////////////////////////////////////////////////////////////
213  std::string Place::display() const {
214  std::ostringstream oStr;
215  oStr << shortDisplay() << std::endl;
216  return oStr.str();
217  }
218 
219  // //////////////////////////////////////////////////////////////////////
221  _termSetMap.clear();
222  _spellingSet.clear();
223  _stemmingSet.clear();
224  _synonymSet.clear();
225  }
226 
227  // //////////////////////////////////////////////////////////////////////
229  // Initialise an empty string set
230  StringSet_T oTermSet;
231 
232  // If existing, retrieve the string set for that weight.
233  TermSetMap_T::const_iterator itTermSet = _termSetMap.find (iWeight);
234  if (itTermSet != _termSetMap.end()) {
235  oTermSet = itTermSet->second;
236  }
237 
238  return oTermSet;
239  }
240 
241  // //////////////////////////////////////////////////////////////////////
242  bool Place::addTermSet (const Weight_T& iWeight, const StringSet_T& iTermSet) {
243  bool hasInsertBeenSuccessful = true;
244 
245  // If existing, retrieve the string set for that weight.
246  TermSetMap_T::iterator itTermSet = _termSetMap.find (iWeight);
247 
248  if (itTermSet == _termSetMap.end()) {
249  // If there was no string set for that weight yet, insert it
250  hasInsertBeenSuccessful =
251  _termSetMap.insert (TermSetMap_T::value_type (iWeight, iTermSet)).second;
252 
253  // Sanity check
254  assert (hasInsertBeenSuccessful == true);
255 
256  } else {
257  // Otherwise, add the given string set, string by string,
258  // to the existing one
259  StringSet_T& lStringSet = itTermSet->second;
260  for (StringSet_T::const_iterator itString = iTermSet.begin();
261  itString != iTermSet.end(); ++itString) {
262  const std::string& lString = *itString;
263  lStringSet.insert (lString);
264  }
265  }
266 
267  return hasInsertBeenSuccessful;
268  }
269 
270  // //////////////////////////////////////////////////////////////////////
271  void Place::addNameToXapianSets (const Weight_T& iWeight,
272  const std::string& iBaseName,
273  const FeatureCode_T& iFeatureCode) {
274  // Retrieve the string set for the given weight, if existing
275  // (empty otherwise)
276  StringSet_T lTermSet = getTermSet (iWeight);
277 
284  const FeatureNameList_T& lFeatureNameList =
285  Location::getFeatureList (iFeatureCode);
286  for (FeatureNameList_T::const_iterator itFeatName = lFeatureNameList.begin();
287  itFeatName != lFeatureNameList.end(); ++itFeatName) {
288  const FeatureName_T& lFeatureName = *itFeatName;
289 
290  lTermSet.insert (iBaseName + " " + lFeatureName);
291  }
292 
293  // Insert (or replace) the newly created (or just altered) string set
294  addTermSet (iWeight, lTermSet);
295  }
296 
297  // //////////////////////////////////////////////////////////////////////
298  void Place::addNameToXapianSets (const Weight_T& iWeight,
299  const LocationName_T& iLocationName,
300  const FeatureCode_T& iFeatureCode,
301  const CityNameList_T& iCityUtfNameList,
302  const CityNameList_T& iCityAsciiNameList,
303  const Admin1UTFName_T& iAdm1UtfName,
304  const Admin1ASCIIName_T& iAdm1AsciiName,
305  const Admin2UTFName_T& iAdm2UtfName,
306  const Admin2ASCIIName_T& iAdm2AsciiName,
307  const StateCode_T& iStateCode,
308  const CountryCode_T& iCountryCode,
309  const CountryName_T& iCountryName,
310  const ContinentName_T& iContinentName,
311  const OTransliterator& iTransliterator) {
312  // Retrieve the string set for the given weight, if existing
313  // (empty otherwise)
314  StringSet_T lTermSet = getTermSet (iWeight);
315 
316  // Tokenise the name. Some of the names contain punctuation characters.
317  // For instance, "Paris/FR/Gare" is transformed into "Paris FR Gare".
318  WordList_T lWordList;
319  tokeniseStringIntoWordList (iLocationName, lWordList);
320  const std::string lTokenisedName = createStringFromWordList (lWordList);
321 
322  // Add the tokenised name to the Xapian index
323  lTermSet.insert (lTokenisedName);
324 
325  // Add the (tokenised name, feature name) pair to the Xapian index
326  addNameToXapianSets (iWeight, lTokenisedName, iFeatureCode);
327 
328  // Add the (tokenised name, UTF8 name) pair to the Xapian index
329  for (CityNameList_T::const_iterator itCityUtfName = iCityUtfNameList.begin();
330  itCityUtfName != iCityUtfNameList.end(); ++itCityUtfName) {
331  const std::string& lCityUtfName = *itCityUtfName;
332  if (lCityUtfName.empty() == false) {
333  lTermSet.insert (lTokenisedName + " " + lCityUtfName);
334  }
335  }
336 
337  // Add the (tokenised name, ASCII city name) pair to the Xapian index
338  for (CityNameList_T::const_iterator itCityAsciiName =
339  iCityAsciiNameList.begin();
340  itCityAsciiName != iCityAsciiNameList.end(); ++itCityAsciiName) {
341  const std::string& lCityAsciiName = *itCityAsciiName;
342  if (lCityAsciiName.empty() == false) {
343  lTermSet.insert (lTokenisedName + " " + lCityAsciiName);
344  }
345  }
346 
347  // Add the (tokenised name, UTF8 admin level 1 name) pair to the Xapian index
348  if (iAdm1UtfName.empty() == false) {
349  lTermSet.insert (lTokenisedName + " " + iAdm1UtfName);
350  }
351 
352  // Add the (tokenised name, ASCII adm level 1 name) pair to the Xapian index
353  if (iAdm1AsciiName.empty() == false) {
354  lTermSet.insert (lTokenisedName + " " + iAdm1AsciiName);
355  }
356 
357  // Add the (tokenised name, UTF8 admin level 2 name) pair to the Xapian index
358  if (iAdm2UtfName.empty() == false) {
359  lTermSet.insert (lTokenisedName + " " + iAdm2UtfName);
360  }
361 
362  // Add the (tokenised name, ASCII adm level 2 name) pair to the Xapian index
363  if (iAdm2AsciiName.empty() == false) {
364  lTermSet.insert (lTokenisedName + " " + iAdm2AsciiName);
365  }
366 
367  // Add the (tokenised name, state code) pair to the Xapian index
368  lTermSet.insert (lTokenisedName + " " + iStateCode);
369 
370  // Add the (tokenised name, country code) pair to the Xapian index
371  lTermSet.insert (lTokenisedName + " " + iCountryCode);
372 
373  // Add the (tokenised name, country name) pair to the Xapian index
374  lTermSet.insert (lTokenisedName + " " + iCountryName);
375 
376  // Add the (tokenised name, continent name) pair to the Xapian index
377  lTermSet.insert (lTokenisedName + " " + iContinentName);
378 
379  // Add the tokenised name to the Xapian spelling dictionary
380  _spellingSet.insert (lTokenisedName);
381 
382  // Normalise, according to the Unicode standard, the given name.
383  // Note that it is important to normalise after the tokenisation process,
384  // as the punctuation is eliminated (and not replaced by space)
385  // by that latter.
386  const std::string& lNormalisedCommonName =
387  iTransliterator.normalise (lTokenisedName);
388 
389  // Add the tokenised and normalised name to the Xapian index
390  lTermSet.insert (lNormalisedCommonName);
391 
392  // Add the (tokenised and normalised name, feature name) pair
393  // to the Xapian index
394  addNameToXapianSets (iWeight, lNormalisedCommonName, iFeatureCode);
395 
396  // Add the (tokenised and normalised name, UTF8 city name) pair
397  // to the Xapian index
398  for (CityNameList_T::const_iterator itCityUtfName = iCityUtfNameList.begin();
399  itCityUtfName != iCityUtfNameList.end(); ++itCityUtfName) {
400  const std::string& lCityUtfName = *itCityUtfName;
401  if (lCityUtfName.empty() == false) {
402  lTermSet.insert (lNormalisedCommonName + " " + lCityUtfName);
403  }
404  }
405 
406  // Add the (tokenised and normalised name, ASCII city name) pair
407  // to the Xapian index
408  for (CityNameList_T::const_iterator itCityAsciiName =
409  iCityAsciiNameList.begin();
410  itCityAsciiName != iCityAsciiNameList.end(); ++itCityAsciiName) {
411  const std::string& lCityAsciiName = *itCityAsciiName;
412  if (lCityAsciiName.empty() == false) {
413  lTermSet.insert (lNormalisedCommonName + " " + lCityAsciiName);
414  }
415  }
416 
417  // Add the (tokenised and normalised name, UTF8 admin level 1 name) pair
418  // to the Xapian index
419  if (iAdm1UtfName.empty() == false) {
420  lTermSet.insert (lNormalisedCommonName + " " + iAdm1UtfName);
421  }
422 
423  // Add the (tokenised and normalised name, ASCII adm level 1 name) pair
424  // to the Xapian index
425  if (iAdm1AsciiName.empty() == false) {
426  lTermSet.insert (lNormalisedCommonName + " " + iAdm1AsciiName);
427  }
428 
429  // Add the (tokenised and normalised name, UTF8 admin level 2 name) pair
430  // to the Xapian index
431  if (iAdm2UtfName.empty() == false) {
432  lTermSet.insert (lNormalisedCommonName + " " + iAdm2UtfName);
433  }
434 
435  // Add the (tokenised and normalised name, ASCII adm level 2 name) pair
436  // to the Xapian index
437  if (iAdm2AsciiName.empty() == false) {
438  lTermSet.insert (lNormalisedCommonName + " " + iAdm2AsciiName);
439  }
440 
441  // Add the (tokenised and normalised name, state code) pair to the
442  // Xapian index
443  lTermSet.insert (lNormalisedCommonName + " " + iStateCode);
444 
445  // Add the (tokenised and normalised name, country code) pair to the
446  // Xapian index
447  lTermSet.insert (lNormalisedCommonName + " " + iCountryCode);
448 
449  // Add the (tokenised and normalised name, country name) pair to the
450  // Xapian index
451  lTermSet.insert (lNormalisedCommonName + " " + iCountryName);
452 
453  // Add the (tokenised and normalised name, continent name) pair to the
454  // Xapian index
455  lTermSet.insert (lNormalisedCommonName + " " + iContinentName);
456 
457  // Add the tokenised and normalised name to the Xapian spelling dictionary
458  _spellingSet.insert (lNormalisedCommonName);
459 
460  // Insert (or replace) the newly created (or just altered) string set
461  addTermSet (iWeight, lTermSet);
462  }
463 
464  // //////////////////////////////////////////////////////////////////////
465  void Place::buildIndexSets (const OTransliterator& iTransliterator) {
466 
477  // Retrieve the PageRank
478  const PageRank_T& lPageRankDouble = _location.getPageRank();
479  //const Weight_T lPageRank =
480  // (lPageRankDouble == K_DEFAULT_PAGE_RANK)?
481  // K_DEFAULT_INDEXING_EXTRA_WEIGHT:
482  // static_cast<const Weight_T> (lPageRankDouble);
483  const Weight_T lPageRank = K_DEFAULT_INDEXING_EXTRA_WEIGHT
484  + static_cast<const Weight_T> (lPageRankDouble / 5.0);
485 
486  // Retrieve the string set for the given weight, if existing
487  // (empty otherwise)
488  StringSet_T lWeightedTermSet = getTermSet (lPageRank);
489 
490  // Retrieve the string set for the given weight, if existing
491  // (empty otherwise)
493 
494  // Retrieve the feature code
495  const FeatureCode_T& lFeatureCode = _location.getFeatureCode();
496 
497  // Add the IATA code
498  const std::string& lIataCode = _location.getIataCode();
499  if (lIataCode.empty() == false) {
500  lWeightedTermSet.insert (lIataCode);
501  _spellingSet.insert (lIataCode);
502 
503  // Add the (IATA code, feature name) to the Xapian index, where the
504  // feature name is derived from the feature code.
505  addNameToXapianSets (lPageRank, lIataCode, lFeatureCode);
506  }
507 
508  // Add the ICAO code
509  const std::string& lIcaoCode = _location.getIcaoCode();
510  if (lIcaoCode.empty() == false) {
511  lWeightedTermSet.insert (lIcaoCode);
512  _spellingSet.insert (lIcaoCode);
513 
514  // Add the (ICAO code, feature name) to the Xapian index, where the
515  // feature name is derived from the feature code.
516  addNameToXapianSets (lPageRank, lIcaoCode, lFeatureCode);
517  }
518 
519  // Add the FAA code
520  const std::string& lFaaCode = _location.getFaaCode();
521  if (lFaaCode.empty() == false) {
522  lWeightedTermSet.insert (lFaaCode);
523  _spellingSet.insert (lFaaCode);
524 
525  // Add the (FAA code, feature name) to the Xapian index, where the
526  // feature name is derived from the feature code.
527  addNameToXapianSets (lPageRank, lFaaCode, lFeatureCode);
528  }
529 
530  // Add the UN/LOCODE codes
531  const UNLOCodeList_T& lUNLOCodeList = _location.getUNLOCodeList();
532  for (UNLOCodeList_T::const_iterator itUNLOCode = lUNLOCodeList.begin();
533  itUNLOCode != lUNLOCodeList.end(); ++itUNLOCode) {
534  const UNLOCode_T& lUNLOCode = *itUNLOCode;
535  if (lUNLOCode.empty() == false) {
536  lWeightedTermSet.insert (lUNLOCode);
537  _spellingSet.insert (lUNLOCode);
538 
539  // Add the (UN/LOCODE code, feature name) to the Xapian index, where the
540  // feature name is derived from the feature code.
541  addNameToXapianSets (lPageRank, lUNLOCode, lFeatureCode);
542  }
543  }
544 
545  // Add the UIC codes
546  const UICCodeList_T& lUICCodeList = _location.getUICCodeList();
547  for (UICCodeList_T::const_iterator itUICCode = lUICCodeList.begin();
548  itUICCode != lUICCodeList.end(); ++itUICCode) {
549  const UICCode_T& lUICCode = *itUICCode;
550  if (lUICCode != 0) {
551  std::stringstream oStr;
552  oStr << lUICCode;
553  const std::string lUICCodeStr = oStr.str();
554  lWeightedTermSet.insert (lUICCodeStr);
555  _spellingSet.insert (lUICCodeStr);
556 
557  // Add the (UIC code, feature name) to the Xapian index, where the
558  // feature name is derived from the feature code.
559  addNameToXapianSets (lPageRank, lUICCodeStr, lFeatureCode);
560  }
561  }
562 
563  // Add the Geonames ID
564  const GeonamesID_T& lGeonamesID = _location.getGeonamesID();
565  if (lGeonamesID != 0) {
566  std::stringstream oStr;
567  oStr << lGeonamesID;
568  const std::string lGeonamesIDStr = oStr.str();
569  lStdTermSet.insert (lGeonamesIDStr);
570  _spellingSet.insert (lGeonamesIDStr);
571  }
572 
573  // Add the feature code
574  if (lFeatureCode.empty() == false) {
575  lWeightedTermSet.insert (lFeatureCode);
576  _spellingSet.insert (lFeatureCode);
577  }
578 
579  // Add the details of the served cities
580  CityNameList_T lCityUtfNameList;
581  CityNameList_T lCityAsciiNameList;
582  const CityDetailsList_T& lCityList = _location.getCityList();
583  for (CityDetailsList_T::const_iterator itCity = lCityList.begin();
584  itCity != lCityList.end(); ++itCity) {
585  const CityDetails& lCity = *itCity;
586 
587  // Add the city IATA code
588  const std::string& lCityCode = lCity.getIataCode();
589  if (lCityCode.empty() == false && lCityCode != lIataCode) {
590  lWeightedTermSet.insert (lCityCode);
591  _spellingSet.insert (lCityCode);
592  }
593 
594  // Add the city UTF8 name
595  const std::string& lCityUtfName = lCity.getUtfName();
596  if (lCityUtfName.empty() == false) {
597  lCityUtfNameList.push_back(lCityUtfName);
598  lWeightedTermSet.insert (lCityUtfName);
599  _spellingSet.insert (lCityUtfName);
600  }
601 
602  // Add the city ASCII name
603  const std::string& lCityAsciiName = lCity.getAsciiName();
604  if (lCityAsciiName.empty() == false) {
605  lCityAsciiNameList.push_back(lCityAsciiName);
606  lWeightedTermSet.insert (lCityAsciiName);
607  _spellingSet.insert (lCityAsciiName);
608  }
609  }
610 
611  // Add the state code
612  const std::string& lStateCode = _location.getStateCode();
613  if (lStateCode.empty() == false) {
614  lWeightedTermSet.insert (lStateCode);
615  _spellingSet.insert (lStateCode);
616  }
617 
618  // Add the country code
619  const std::string& lCountryCode = _location.getCountryCode();
620  lWeightedTermSet.insert (lCountryCode);
621 
622  // Add the country name
623  const std::string& lCountryName = _location.getCountryName();
624  if (lCountryName.empty() == false) {
625  lWeightedTermSet.insert (lCountryName);
626  _spellingSet.insert (lCountryName);
627  }
628 
629  // Add the administrative level 1 code
630  const std::string& lAdm1Code = _location.getAdmin1Code();
631  if (lAdm1Code.empty() == false) {
632  lWeightedTermSet.insert (lAdm1Code);
633  }
634 
635  // Add the administrative level 1 UTF8 name
636  const std::string& lAdm1UtfName = _location.getAdmin1UtfName();
637  if (lAdm1UtfName.empty() == false) {
638  lWeightedTermSet.insert (lAdm1UtfName);
639  _spellingSet.insert (lAdm1UtfName);
640  }
641 
642  // Add the administrative level 1 ASCII name
643  const std::string& lAdm1AsciiName = _location.getAdmin1AsciiName();
644  if (lAdm1AsciiName.empty() == false) {
645  lWeightedTermSet.insert (lAdm1AsciiName);
646  _spellingSet.insert (lAdm1AsciiName);
647  }
648 
649  // Add the administrative level 2 code
650  const std::string& lAdm2Code = _location.getAdmin1Code();
651  if (lAdm2Code.empty() == false) {
652  lWeightedTermSet.insert (lAdm2Code);
653  }
654 
655  // Add the administrative level 2 UTF8 name
656  const std::string& lAdm2UtfName = _location.getAdmin2UtfName();
657  if (lAdm2UtfName.empty() == false) {
658  lWeightedTermSet.insert (lAdm2UtfName);
659  _spellingSet.insert (lAdm2UtfName);
660  }
661 
662  // Add the administrative level 2 ASCII name
663  const std::string& lAdm2AsciiName = _location.getAdmin2AsciiName();
664  if (lAdm2AsciiName.empty() == false) {
665  lWeightedTermSet.insert (lAdm2AsciiName);
666  _spellingSet.insert (lAdm2AsciiName);
667  }
668 
669  // Add the continent name
670  const std::string& lContinentName = _location.getContinentName();
671  lWeightedTermSet.insert (lContinentName);
672 
673  // Add the common name (usually in American English, but not necessarily
674  // in ASCII).
675  const std::string& lCommonName = _location.getCommonName();
676  if (lCommonName.empty() == false) {
678  LocationName_T (lCommonName),
679  FeatureCode_T (lFeatureCode),
680  lCityUtfNameList, lCityAsciiNameList,
681  Admin1UTFName_T (lAdm1UtfName),
682  Admin1ASCIIName_T (lAdm1AsciiName),
683  Admin2UTFName_T (lAdm2UtfName),
684  Admin2ASCIIName_T (lAdm2AsciiName),
685  StateCode_T (lStateCode),
686  CountryCode_T (lCountryCode),
687  CountryName_T (lCountryName),
688  ContinentName_T (lContinentName), iTransliterator);
689  }
690 
691  // Add the ASCII name (not necessarily in English).
692  const std::string& lASCIIName = _location.getAsciiName();
693  if (lASCIIName.empty() == false) {
695  LocationName_T (lASCIIName),
696  FeatureCode_T (lFeatureCode),
697  lCityUtfNameList, lCityAsciiNameList,
698  Admin1UTFName_T (lAdm1UtfName),
699  Admin1ASCIIName_T (lAdm1AsciiName),
700  Admin2UTFName_T (lAdm2UtfName),
701  Admin2ASCIIName_T (lAdm2AsciiName),
702  StateCode_T (lStateCode),
703  CountryCode_T (lCountryCode),
704  CountryName_T (lCountryName),
705  ContinentName_T (lContinentName), iTransliterator);
706  }
707 
708  // Retrieve the place names in all the available languages
709  const NameMatrix& lNameMatrixFull = _location.getNameMatrix();
710  const NameMatrix_T& lNameMatrix = lNameMatrixFull.getNameMatrix();
711  for (NameMatrix_T::const_iterator itNameList = lNameMatrix.begin();
712  itNameList != lNameMatrix.end(); ++itNameList) {
713  // Retrieve the language code and locale
714  // const LanguageCode_T& lLanguage = itNameList->first;
715  const Names& lNames = itNameList->second;
716 
717  // For a given language, retrieve the list of place names
718  const NameList_T& lNameList = lNames.getNameList();
719 
720  for (NameList_T::const_iterator itName = lNameList.begin();
721  itName != lNameList.end(); ++itName) {
722  const std::string& lName = *itName;
723 
724  // Add the alternate name, which can be made of several words
725  // (e.g., 'san francisco').
726  if (lName.empty() == false) {
727  // Create a list made of all the word combinations of the
728  // initial string
729  WordCombinationHolder lWordCombinationHolder (lName);
730 
731  // Browse the list of unique strings (word combinations)
732  const WordCombinationHolder::StringList_T& lStringList =
733  lWordCombinationHolder._list;
734  for (WordCombinationHolder::StringList_T::const_iterator itString =
735  lStringList.begin();
736  itString != lStringList.end(); ++itString) {
737  const std::string& lWordCombination = *itString;
738  const std::string& lNormalisedWordCombination =
739  iTransliterator.normalise (lWordCombination);
740 
741  // Add that combination of words into the set of terms
742  lStdTermSet.insert (lWordCombination);
743  _spellingSet.insert (lWordCombination);
744 
745  // Add the normalised combination of words into the set of terms
746  lStdTermSet.insert (lNormalisedWordCombination);
747  _spellingSet.insert (lNormalisedWordCombination);
748  }
749  }
750  }
751  }
752 
753  // Insert (or replace) the newly created (or just altered) string set
754  addTermSet (lPageRank, lWeightedTermSet);
755 
756  // Insert (or replace) the newly created (or just altered) string set
758  }
759 
760  // //////////////////////////////////////////////////////////////////////
762 
763  NameList_T lNameList;
764  LanguageCode_T K_DEFAULT_LANGUAGE_CODE ("en_US");
765  const bool hasFoundNameList = getNameList (K_DEFAULT_LANGUAGE_CODE,
766  lNameList);
767 
768  if (hasFoundNameList == false) {
769  //
770  std::ostringstream errorStr;
771  errorStr << "No list of names in (American) English ("
772  << K_DEFAULT_LANGUAGE_CODE
773  << " locale) can be found for the following place: "
774  << toShortString();
775  OPENTREP_LOG_ERROR (errorStr.str());
776  // throw LanguageCodeNotDefinedInNameTableException (errorStr.str());
777  }
778  // assert (hasFoundNameList == true);
779 
780  // Add extra matching locations, whenever they exist
781  if (_extraPlaceList.empty() == false) {
782  for (PlaceOrderedList_T::const_iterator itLoc = _extraPlaceList.begin();
783  itLoc != _extraPlaceList.end(); ++itLoc) {
784  const Place* lExtraPlace_ptr = *itLoc;
785  assert (lExtraPlace_ptr != NULL);
786 
787  // Add the extra matching location
788  const Location& lExtraLocation = lExtraPlace_ptr->getLocation();
789  _location.addExtraLocation (lExtraLocation);
790  }
791  }
792 
793  // Add alternate matching locations, whenever they exist
794  if (_alternatePlaceList.empty() == false) {
795  for (PlaceOrderedList_T::const_iterator itLoc =
796  _alternatePlaceList.begin();
797  itLoc != _alternatePlaceList.end(); ++itLoc) {
798  const Place* lAlternatePlace_ptr = *itLoc;
799  assert (lAlternatePlace_ptr != NULL);
800 
801  // Add the alternate matching location
802  const Location& lAlternateLocation = lAlternatePlace_ptr->getLocation();
803  _location.addAlternateLocation (lAlternateLocation);
804  }
805  }
806 
807  return _location;
808  }
809 }
const Percentage_T K_DEFAULT_PAGE_RANK
#define OPENTREP_LOG_ERROR(iToBeLogged)
Definition: Logger.hpp:24
std::set< std::string > StringSet_T
Definition: Place.hpp:40
void addExtraLocation(const Location &iExtraLocation)
Definition: Location.hpp:875
std::string normalise(const std::string &iString) const
void addNameToXapianSets(const Weight_T &, const LocationName_T &, const FeatureCode_T &, const CityNameList_T &iCityUtfNameList, const CityNameList_T &iCityAsciiNameList, const Admin1UTFName_T &, const Admin1ASCIIName_T &, const Admin2UTFName_T &, const Admin2ASCIIName_T &, const StateCode_T &, const CountryCode_T &, const CountryName_T &, const ContinentName_T &, const OTransliterator &)
Definition: Place.cpp:298
Class modelling the elementary details of a city.
Definition: CityDetails.hpp:30
std::list< UNLOCode_T > UNLOCodeList_T
std::string toString() const
Definition: Location.cpp:282
unsigned int GeonamesID_T
const ContinentName_T & getContinentName() const
Definition: Location.hpp:214
StringSet_T getTermSet(const Weight_T &) const
Definition: Place.cpp:228
Structure modelling a (geographical) location.
Definition: Location.hpp:25
double PageRank_T
std::string toShortString() const
Definition: Location.cpp:258
bool addTermSet(const Weight_T &, const StringSet_T &)
Definition: Place.cpp:242
unsigned short Weight_T
const Admin1Code_T & getAdmin1Code() const
Definition: Location.hpp:277
std::string toString() const
Definition: Place.cpp:85
std::list< UICCode_T > UICCodeList_T
const NameMatrix_T & getNameMatrix() const
Definition: NameMatrix.hpp:44
static FeatureNameList_T getFeatureList(const FeatureCode_T &)
Definition: Location.cpp:421
std::string describeSets() const
Definition: Place.cpp:157
std::list< FeatureName_T > FeatureNameList_T
boost::gregorian::date Date_T
std::list< Word_T > WordList_T
const FAACode_T & getFaaCode() const
Definition: Location.hpp:73
std::list< std::string > NameList_T
Definition: Names.hpp:20
std::string createStringFromWordList(const WordList_T &iWordList, const NbOfWords_T iSplitIdx, const bool iFromBeginningFlag)
Definition: Utilities.cpp:43
std::string shortDisplay() const
Definition: Place.cpp:202
const PageRank_T & getPageRank() const
Definition: Location.hpp:354
const CityUTFName_T & getUtfName() const
Definition: CityDetails.hpp:50
const Location & completeLocation()
Definition: Place.cpp:761
void toStream(std::ostream &) const
Definition: Place.cpp:148
const Admin2ASCIIName_T & getAdmin2AsciiName() const
Definition: Location.hpp:312
const CountryCode_T & getCountryCode() const
Definition: Location.hpp:165
unsigned int UICCode_T
const IATACode_T & getIataCode() const
Definition: CityDetails.hpp:36
const NameList_T & getNameList() const
Definition: Names.hpp:60
std::string display() const
Definition: Place.cpp:213
const UICCodeList_T & getUICCodeList() const
Definition: Location.hpp:87
const Admin1UTFName_T & getAdmin1UtfName() const
Definition: Location.hpp:284
Class modelling a place/POR (point of reference).
Definition: Place.hpp:29
std::string toBasicString() const
Definition: Location.cpp:218
const UNLOCodeList_T & getUNLOCodeList() const
Definition: Location.hpp:80
const IATACode_T & getIataCode() const
Definition: Location.hpp:38
void buildIndexSets(const OTransliterator &)
Definition: Place.cpp:465
const NameMatrix & getNameMatrix() const
Definition: Location.hpp:389
std::list< std::string > StringList_T
const ICAOCode_T & getIcaoCode() const
Definition: Location.hpp:66
const StateCode_T & getStateCode() const
Definition: Location.hpp:158
bool getNameList(const LanguageCode_T &iLanguageCode, NameList_T &ioNameList) const
Definition: Place.hpp:423
const ASCIIName_T & getAsciiName() const
Definition: Location.hpp:102
const CountryName_T & getCountryName() const
Definition: Location.hpp:179
void fromStream(std::istream &)
Definition: Place.cpp:153
const Weight_T K_DEFAULT_INDEXING_STD_WEIGHT
const Admin2UTFName_T & getAdmin2UtfName() const
Definition: Location.hpp:305
std::string toShortString() const
Definition: Place.cpp:126
void tokeniseStringIntoWordList(const std::string &iPhrase, WordList_T &ioWordList)
Definition: Utilities.cpp:19
std::map< LanguageCode_T, Names > NameMatrix_T
Definition: Names.hpp:149
void addAlternateLocation(const Location &iAlternateLocation)
Definition: Location.hpp:882
const CommonName_T & getCommonName() const
Definition: Location.hpp:95
void resetIndexSets()
Definition: Place.cpp:220
const GeonamesID_T & getGeonamesID() const
Definition: Location.hpp:52
std::list< std::string > CityNameList_T
Definition: Place.hpp:42
std::list< CityDetails > CityDetailsList_T
A list of cities, for instance the list of cities served by a travel-/transport-related POR (point of...
const CityASCIIName_T & getAsciiName() const
Definition: CityDetails.hpp:58
const FeatureCode_T & getFeatureCode() const
Definition: Location.hpp:270
const Location & getLocation() const
Definition: Place.hpp:52
const CityDetailsList_T & getCityList() const
Definition: Location.hpp:151
const Admin1ASCIIName_T & getAdmin1AsciiName() const
Definition: Location.hpp:291
const Weight_T K_DEFAULT_INDEXING_EXTRA_WEIGHT