Index: src/lang/english.txt
===================================================================
--- src/lang/english.txt	(revision 20145)
+++ src/lang/english.txt	(working copy)
@@ -1147,7 +1147,7 @@
 STR_CONFIG_SETTING_ERRMSG_DURATION                              :{LTBLUE}Duration of error message: {ORANGE}{STRING1}
 STR_CONFIG_SETTING_HOVER_DELAY                                  :{LTBLUE}Delay of hover events: {ORANGE}{STRING1}
 STR_CONFIG_SETTING_HOVER_DELAY_DISABLED                         :{LTBLUE}Delay of hover events: {ORANGE}disabled
-STR_CONFIG_SETTING_POPULATION_IN_LABEL                          :{LTBLUE}Show town population in the town name label: {ORANGE}{STRING1}
+STR_CONFIG_SETTING_POPULATION_IN_LABEL                          :{LTBLUE}Show extra information in the town name label: {ORANGE}{STRING1}
 
 STR_CONFIG_SETTING_LAND_GENERATOR                               :{LTBLUE}Land generator: {ORANGE}{STRING1}
 STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL                      :Original
@@ -4110,10 +4110,18 @@
 STR_SAVEGAME_NAME_SPECTATOR                                     :Spectator, {1:STRING1}
 
 # Viewport strings
+STR_VIEWPORT_TOWN_POP_VERY_POOR_RATING                          :{WHITE}{TOWN} {RED}({COMMA})
+STR_VIEWPORT_TOWN_POP_MEDIOCRE_RATING                           :{WHITE}{TOWN} {ORANGE}({COMMA})
+STR_VIEWPORT_TOWN_POP_GOOD_RATING                               :{WHITE}{TOWN} {YELLOW}({COMMA})
 STR_VIEWPORT_TOWN_POP                                           :{WHITE}{TOWN} ({COMMA})
+STR_VIEWPORT_TOWN_POP_EXCELLENT_RATING                          :{WHITE}{TOWN} {GREEN}({COMMA})
 STR_VIEWPORT_TOWN                                               :{WHITE}{TOWN}
 STR_VIEWPORT_TOWN_TINY_BLACK                                    :{TINYFONT}{BLACK}{TOWN}
+STR_VIEWPORT_TOWN_TINY_VERY_POOR_RATING                         :{TINYFONT}{RED}{TOWN}
+STR_VIEWPORT_TOWN_TINY_MEDIOCRE_RATING                          :{TINYFONT}{ORANGE}{TOWN}
+STR_VIEWPORT_TOWN_TINY_GOOD_RATING                              :{TINYFONT}{YELLOW}{TOWN}
 STR_VIEWPORT_TOWN_TINY_WHITE                                    :{TINYFONT}{WHITE}{TOWN}
+STR_VIEWPORT_TOWN_TINY_EXCELLENT_RATING                         :{TINYFONT}{GREEN}{TOWN}
 
 STR_VIEWPORT_SIGN_SMALL_BLACK                                   :{TINYFONT}{BLACK}{SIGN}
 STR_VIEWPORT_SIGN_SMALL_WHITE                                   :{TINYFONT}{WHITE}{SIGN}
Index: src/town.h
===================================================================
--- src/town.h	(revision 20145)
+++ src/town.h	(working copy)
@@ -17,6 +17,9 @@
 #include "command_type.h"
 #include "town_map.h"
 #include "subsidy_type.h"
+#include "openttd.h"
+#include "table/strings.h"
+#include "company_func.h"
 
 template <typename T>
 struct BuildingCounts {
@@ -66,6 +69,7 @@
 	CompanyByte exclusivity;       ///< which company has exclusivity
 	uint8 exclusive_counter;       ///< months till the exclusivity expires
 	int16 ratings[MAX_COMPANIES];
+	StringID town_label;           ///< Label dependent on _local_company rating.
 
 	/* Maximum amount of passengers and mail that can be transported. */
 	uint32 max_pass;
@@ -122,6 +126,30 @@
 
 	void InitializeLayout(TownLayout layout);
 
+	void UpdateLabel();
+
+	/**
+	 * Returns the correct town label, based on rating.
+	 */
+	FORCEINLINE StringID Label() const{
+		if (!(_game_mode == GM_EDITOR) && (_local_company < MAX_COMPANIES)) {
+			return STR_VIEWPORT_TOWN_POP_VERY_POOR_RATING + this->town_label;
+		} else {
+			return _settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN;
+		}
+	}
+
+	/**
+	 * Returns the correct town small label, based on rating.
+	 */
+	FORCEINLINE StringID SmallLabel() const{
+		if (!(_game_mode == GM_EDITOR) && (_local_company < MAX_COMPANIES)) {
+			return STR_VIEWPORT_TOWN_TINY_VERY_POOR_RATING + this->town_label;
+		} else {
+			return STR_VIEWPORT_TOWN_TINY_WHITE;
+		}
+	}
+
 	/** Calculate the max town noise
 	 * The value is counted using the population divided by the content of the
 	 * entry in town_noise_population corespondig to the town's tolerance.
Index: src/town_cmd.cpp
===================================================================
--- src/town_cmd.cpp	(revision 20145)
+++ src/town_cmd.cpp	(working copy)
@@ -153,6 +153,26 @@
 	return Town::Get(index);
 }
 
+/**
+ * Updates the town label of the town after changes in rating. The colour scheme is:
+ * Red: Appalling and Very poor ratings.
+ * Orange: Poor and mediocre ratings.
+ * Yellow: Good rating.
+ * White: Very good rating (standard).
+ * Green: Excellent and outstanding ratings.
+ */
+void Town::UpdateLabel()
+{
+	if (!(_game_mode == GM_EDITOR) && (_local_company < MAX_COMPANIES)) {
+		int r = this->ratings[_local_company];
+		(this->town_label = 0, r <= RATING_VERYPOOR)  || // Appalling and Very Poor
+		(this->town_label++,   r <= RATING_MEDIOCRE)  || // Poor and Mediocre
+		(this->town_label++,   r <= RATING_GOOD)      || // Good
+		(this->town_label++,   r <= RATING_VERYGOOD)  || // Very Good
+		(this->town_label++,   true);                    // Excellent and Outstanding
+	}
+}
+
 Money HouseSpec::GetRemovalCost() const
 {
 	return (_price[PR_CLEAR_HOUSE] * this->removal_cost) >> 8;
@@ -342,11 +362,11 @@
  */
 void Town::UpdateVirtCoord()
 {
+	this->UpdateLabel();
 	Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
 	SetDParam(0, this->index);
 	SetDParam(1, this->population);
-	this->sign.UpdatePosition(pt.x, pt.y - 24,
-		_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN);
+	this->sign.UpdatePosition(pt.x, pt.y - 24, this->Label());
 
 	SetWindowDirty(WC_TOWN_VIEW, this->index);
 }
@@ -2467,6 +2487,7 @@
 		 */
 		if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
 			t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
+			t->UpdateVirtCoord();
 			SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
 		}
 	} else {
@@ -2593,6 +2614,7 @@
 		t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
 	}
 
+	t->UpdateVirtCoord();
 	SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
 
 	ClrBit(t->flags, TOWN_IS_FUNDED);
@@ -2803,6 +2825,7 @@
 	} else {
 		SetBit(t->have_ratings, _current_company);
 		t->ratings[_current_company] = rating;
+		t->UpdateVirtCoord();
 		SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
 	}
 }
Index: src/company_cmd.cpp
===================================================================
--- src/company_cmd.cpp	(revision 20145)
+++ src/company_cmd.cpp	(working copy)
@@ -506,6 +506,8 @@
 
 	c->num_engines = CallocT<uint16>(Engine::GetPoolSize());
 
+	if (!is_ai) UpdateAllTownVirtCoords();
+
 	return c;
 }
 
Index: src/viewport.cpp
===================================================================
--- src/viewport.cpp	(revision 20145)
+++ src/viewport.cpp	(working copy)
@@ -1127,8 +1127,7 @@
 	const Town *t;
 	FOR_ALL_TOWNS(t) {
 		ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &t->sign,
-				_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN,
-				STR_VIEWPORT_TOWN_TINY_WHITE, STR_VIEWPORT_TOWN_TINY_BLACK,
+				t->Label(), t->SmallLabel(), STR_VIEWPORT_TOWN_TINY_BLACK,
 				t->index, t->population);
 	}
 }
