// class_travel_application.h (c) Kari Laitinen // 09.02.2001 File created. // 06.03.2001 Modification. // 2013-11-15 Last modification. #ifndef CLASS_TRAVEL_APPLICATION_H #define CLASS_TRAVEL_APPLICATION_H #include "class_place_on_earth.h" class Travel_application { protected: vector places_on_earth ; Place_on_earth current_place ; int index_of_current_place ; stringstream itinerary_text ; public: Travel_application() { load_travel_data_from_file() ; } void standardize_geographical_name( string& geographical_name ) ; bool search_place_name( string& place_name_to_search, int index_where_to_start_search, Place_on_earth& place_data_to_caller, int& index_of_found_place ) ; bool search_country_name( string& country_name_to_search, int index_where_to_start_search, Place_on_earth& place_data_to_caller, int& index_of_found_place ) ; bool search_place_in_country( string& given_place_name, string& given_country_name, Place_on_earth& place_data_to_caller, int& place_index_to_caller ) ; bool search_place_in_country( string& given_place_name, string& given_country_name, Place_on_earth& place_data_to_caller ) ; void search_place_or_country( string& given_name ) ; void set_current_place() ; void print_distance_between_places( string& name_of_place_to_leave, string& name_of_country_to_leave, string& name_of_place_to_go_to, string& name_of_country_to_go_to ) ; bool print_data_of_place_in_country( string& given_place_name, string& given_country_name ) ; void store_itinerary_text_to_file() ; void load_travel_data_from_file() ; virtual void run() ; } ; void Travel_application::standardize_geographical_name( string& geographical_name ) { // Standardization means here that a geographical name // is capitalized, and if it consists of several words // each word is capitalized, leaving only one space // between the words. String USA is not capitalized. // Standardization is needed, because all geographical // names are written in standard way in the large // table "places_on_earth". stringstream name_as_stream ; name_as_stream << geographical_name ; string standardized_name ; string word_in_name ; while ( name_as_stream >> word_in_name ) { if ( word_in_name == "usa" ) { word_in_name = "USA" ; } if ( word_in_name != "USA" ) { capitalize_string( word_in_name ) ; } standardized_name = standardized_name + word_in_name + " " ; } // Let's get rid of the extra space in the end. // If the geographical name was just white space, it is // possible that the length of the name is zero. // Function "erase" does not work if we try to erase // position -1. if ( standardized_name.length() > 0 ) { standardized_name.erase( standardized_name.length() - 1 ) ; } geographical_name = standardized_name ; } bool Travel_application::search_place_name( string& place_name_to_search, int index_where_to_start_search, Place_on_earth& place_data_to_caller, int& index_of_found_place ) { unsigned int place_index = index_where_to_start_search ; bool place_data_has_been_found = false ; while ( place_index < places_on_earth.size() && place_data_has_been_found == false ) { if ( places_on_earth[ place_index ]. place_name_contains_string( place_name_to_search ) ) { place_data_has_been_found = true ; place_data_to_caller = places_on_earth[ place_index ] ; index_of_found_place = place_index ; } place_index ++ ; } return place_data_has_been_found ; } bool Travel_application::search_country_name( string& country_name_to_search, int index_where_to_start_search, Place_on_earth& place_data_to_caller, int& index_of_found_place ) { unsigned int place_index = index_where_to_start_search ; bool place_data_has_been_found = false ; while ( place_index < places_on_earth.size() && place_data_has_been_found == false ) { if ( places_on_earth[ place_index ]. country_name_contains_string( country_name_to_search ) ) { place_data_has_been_found = true ; place_data_to_caller = places_on_earth[ place_index ] ; index_of_found_place = place_index ; } place_index ++ ; } return place_data_has_been_found ; } bool Travel_application::search_place_in_country( string& given_place_name, string& given_country_name, Place_on_earth& place_data_to_caller, int& place_index_to_caller ) { standardize_geographical_name( given_place_name ) ; standardize_geographical_name( given_country_name ) ; unsigned int place_index = 0 ; bool searched_data_have_been_found = false ; while ( place_index < places_on_earth.size() && searched_data_have_been_found == false ) { if ( places_on_earth[ place_index ]. place_name_contains_string( given_place_name ) && places_on_earth[ place_index ]. country_name_contains_string( given_country_name ) ) { searched_data_have_been_found = true ; place_data_to_caller = places_on_earth[ place_index ] ; place_index_to_caller = place_index ; } place_index ++ ; } return searched_data_have_been_found ; } bool Travel_application::search_place_in_country( string& given_place_name, string& given_country_name, Place_on_earth& place_data_to_caller ) { int unused_place_index ; return search_place_in_country( given_place_name, given_country_name, place_data_to_caller, unused_place_index ) ; } void Travel_application::search_place_or_country( string& given_name ) { standardize_geographical_name( given_name ) ; int place_index = 0 ; bool given_name_is_place_name = false ; Place_on_earth found_place ; while ( search_place_name( given_name, place_index, found_place, place_index ) ) { given_name_is_place_name = true ; string short_place_info ; found_place.get_short_place_info( short_place_info ) ; cout << short_place_info ; itinerary_text << short_place_info ; place_index ++ ; // start new search from following place } if ( given_name_is_place_name == false ) { // We'll try to search a country with the given name // because it didn't match with any place name. place_index = 0 ; while ( search_country_name( given_name, place_index, found_place, place_index ) ) { string short_place_info ; found_place.get_short_place_info( short_place_info ) ; cout << short_place_info ; itinerary_text << short_place_info ; place_index ++ ; // start new search from following place } } } void Travel_application::set_current_place() { string given_place_name, given_country_name ; cout << "\n Give place name: " ; getline( cin, given_place_name ) ; cout << " Give country name: " ; getline( cin, given_country_name ) ; if ( search_place_in_country( given_place_name, given_country_name, current_place, index_of_current_place ) ) { string long_place_info ; current_place.get_long_place_info( long_place_info ) ; itinerary_text << long_place_info ; cout << "\n CURRENT PLACE IS: \n" << long_place_info ; } else { cout << "\n No data of \"" << given_place_name << "\" in \"" << given_country_name << "\" was found.\n" ; itinerary_text << "\n No data of \"" << given_place_name << "\" in \"" << given_country_name << "\" was found.\n" ; } } bool Travel_application::print_data_of_place_in_country( string& given_place_name, string& given_country_name ) { standardize_geographical_name( given_place_name ) ; standardize_geographical_name( given_country_name ) ; Place_on_earth found_place ; if ( search_place_in_country( given_place_name, given_country_name, found_place ) ) { string long_place_info ; found_place.get_long_place_info( long_place_info ) ; cout << long_place_info ; itinerary_text << long_place_info ; return true ; } else { cout << "\n No data of \"" << given_place_name << "\" in \"" << given_country_name << "\" was found.\n" ; itinerary_text << "\n No data of \"" << given_place_name << "\" in \"" << given_country_name << "\" was found.\n" ; return false ; } } void Travel_application::print_distance_between_places( string& name_of_place_to_leave, string& name_of_country_to_leave, string& name_of_place_to_go_to, string& name_of_country_to_go_to ) { standardize_geographical_name( name_of_place_to_leave ) ; standardize_geographical_name( name_of_country_to_leave ) ; standardize_geographical_name( name_of_place_to_go_to ) ; standardize_geographical_name( name_of_country_to_go_to ) ; Place_on_earth place_to_leave ; Place_on_earth place_to_go_to ; int index_of_place_to_leave ; int index_of_place_to_go_to ; if ( search_place_in_country( name_of_place_to_leave, name_of_country_to_leave, place_to_leave ) ) { if ( search_place_in_country( name_of_place_to_go_to, name_of_country_to_go_to, place_to_go_to ) ) { long distance_in_kilometers ; place_to_leave.get_distance_to( place_to_go_to, distance_in_kilometers ) ; long distance_in_miles = (long) ( (double) distance_in_kilometers / 1.609344 ) ; stringstream distance_info_as_stream ; distance_info_as_stream << " " << distance_in_kilometers << " km (" << distance_in_miles << " miles) " ; string distance_info ; getline( distance_info_as_stream, distance_info ) ; int number_of_dashes_to_append = ( 40 - distance_info.length() ) / 2 ; string surrounding_dashes( number_of_dashes_to_append, '-' ) ; distance_info = surrounding_dashes + distance_info + surrounding_dashes ; cout << "\n\n " << place_to_leave.get_place_name() << " " << distance_info << " " << place_to_go_to.get_place_name() ; cout << "\n " << place_to_leave.get_country_name() << " " << string( distance_info.length() + (place_to_leave.get_place_name()).length() - (place_to_leave.get_country_name()).length(), ' ' ) << " " << place_to_go_to.get_country_name() ; cout << "\n\n" ; itinerary_text << "\n\n " << place_to_leave.get_place_name() << " " << distance_info << " " << place_to_go_to.get_place_name() ; itinerary_text << "\n " << place_to_leave.get_country_name() << " " << string( distance_info.length() + (place_to_leave.get_place_name()).length() - (place_to_leave.get_country_name()).length(), ' ' ) << " " << place_to_go_to.get_country_name() ; itinerary_text << "\n\n" ; } else { cout << "\n Could not find \"" << name_of_place_to_go_to << "\" in \"" << name_of_country_to_go_to << "\".\n" ; itinerary_text << "\n Could not find \"" << name_of_place_to_go_to << "\" in \"" << name_of_country_to_go_to << "\".\n" ; } } else { cout << "\n Could not find \"" << name_of_place_to_leave << "\" in \"" << name_of_country_to_leave << "\".\n" ; itinerary_text << "\n Could not find \"" << name_of_place_to_leave << "\" in \"" << name_of_country_to_leave << "\".\n" ; } } void Travel_application::store_itinerary_text_to_file() { ofstream itinerary_file( "itinerary.txt" ) ; if ( itinerary_file.fail() ) { cout << "\n\n Error in opening \"itinerary.txt\" \n\n" ; } else { cout << "\n \"itinerary.txt\" is being created ... \n" ; string line_to_file ; while ( getline( itinerary_text, line_to_file ) ) { itinerary_file << line_to_file << "\n" ; } } } void Travel_application::load_travel_data_from_file() { ifstream travel_data_file( "travel_database.data", ios::binary ) ; if ( travel_data_file.fail() ) { cout << "\n ERROR -- could not read travel data file.\n" ; } else { places_on_earth.clear() ; // deleting old place data. int number_of_place_records_to_read ; travel_data_file.read( (char*) &number_of_place_records_to_read, sizeof( int ) ) ; for ( int place_index = 0 ; place_index < number_of_place_records_to_read ; place_index ++ ) { Place_on_earth place_from_file ; place_from_file.load_from_binary_file( travel_data_file ) ; places_on_earth.push_back( place_from_file ) ; } current_place = places_on_earth[ 0 ] ; index_of_current_place = 0 ; } } void Travel_application::run() { string user_selection = "????" ; cout << "\n This program is a system to help you to plan your" "\n international travels. Note that" "\n " "\n - to calculate distances between places you have to" "\n first set a current place" "\n " "\n - the program can search information also when you" "\n type only a part of a place name" "\n " "\n - before exiting the program you should choose 'i'" "\n to create \"itinerary.txt\" which contains all" "\n information that was found during the run of the" "\n program\n" "\n Press to continue ... " ; getline( cin, user_selection ) ; user_selection = "????" ; cout << "\n Select from the menu by typing in a letter." ; while ( user_selection[ 0 ] != 'e' && user_selection[ 0 ] != 'q' && user_selection[ 0 ] != 'x' ) { cout << "\n" "\n 'c' Set current place. " "\n 's' Search place or country by name." "\n 'a' All possible data of a place." "\n 'd' Distance from current place." "\n 'i' Create itinerary file." "\n 'x' or 'q' or 'e' Exit the program.\n\n " ; getline( cin, user_selection ) ; if ( user_selection[ 0 ] == 'c' ) { set_current_place() ; } else if ( user_selection[ 0 ] == 's' ) { cout << "\n Give name of a place or a country: " ; string given_name ; getline( cin, given_name ) ; search_place_or_country( given_name ) ; } else if ( user_selection[ 0 ] == 'a' ) { string place_name, country_name ; cout << "\n Give place name: " ; getline( cin, place_name ) ; cout << " Give country name: " ; getline( cin, country_name ) ; if ( place_name.length() == 0 && country_name.length() == 0 ) { place_name = current_place.get_place_name() ; country_name = current_place.get_country_name() ; } print_data_of_place_in_country( place_name, country_name ) ; } else if ( user_selection[ 0 ] == 'd' ) { string place_to_go_to, country_to_go_to ; cout << " Give place to go to: " ; getline( cin, place_to_go_to ) ; cout << " Give country to go to: " ; getline( cin, country_to_go_to ) ; string place_to_leave = current_place.get_place_name() ; string country_to_leave = current_place.get_country_name() ; print_distance_between_places( place_to_leave, country_to_leave, place_to_go_to, country_to_go_to ) ; } else if ( user_selection[ 0 ] == 'i' ) { store_itinerary_text_to_file() ; } } } #endif // end of include guard.