diff --git a/src/main/webapp/js/util.js b/src/main/webapp/js/util.js
index 193a56249727b373aa7f9471f457d27a60bc6296..e92ca9fb10d92473489427ecd62fbb7c704c7dd9 100755
--- a/src/main/webapp/js/util.js
+++ b/src/main/webapp/js/util.js
@@ -17,9 +17,8 @@
  * 
  */
 
-function setFieldValue(theForm, fieldName, value)
-{
-    theForm[fieldName] = value;
+function setFieldValue(theForm, fieldName, value) {
+	theForm[fieldName] = value;
 }
 
 /* An easy way to sort list options alphabetically
@@ -28,43 +27,35 @@ function setFieldValue(theForm, fieldName, value)
  * @param {type} b
  * @returns {Number}
  */
-var compareSelectListOptions = function(a,b)
-{
-	if(a.text < b.text)
-	{
+var compareSelectListOptions = function (a, b) {
+	if (a.text < b.text) {
 		return -1;
 	}
-	if(a.text > b.text)
-	{
+	if (a.text > b.text) {
 		return 1;
 	}
 	return 0;
 };
 
-var sortListAlphabetically = function(theList, keepFirst)
-{
-    keepFirst = keepFirst | 0;
-    var allOptions = [];
-    for(var i=keepFirst;i<theList.options.length;i++)
-    {
-            allOptions.push(theList.options[i]);
-    }
-    allOptions.sort(function(a,b){
-        if(a.label < b.label)
-	{
-		return -1;
+var sortListAlphabetically = function (theList, keepFirst) {
+	keepFirst = keepFirst | 0;
+	var allOptions = [];
+	for (var i = keepFirst; i < theList.options.length; i++) {
+		allOptions.push(theList.options[i]);
 	}
-	if(a.label > b.label)
-	{
-		return 1;
+	allOptions.sort(function (a, b) {
+		if (a.label < b.label) {
+			return -1;
+		}
+		if (a.label > b.label) {
+			return 1;
+		}
+		return 0;
+	});
+	theList.options.length = keepFirst; // Keeping the top items?
+	for (var i = 0; i < allOptions.length; i++) {
+		theList.options[theList.options.length] = allOptions[i];
 	}
-	return 0;
-    });
-    theList.options.length=keepFirst; // Keeping the top items?
-    for(var i=0;i<allOptions.length;i++)
-    {
-            theList.options[theList.options.length] = allOptions[i];
-    }
 };
 
 /**
@@ -73,42 +64,35 @@ var sortListAlphabetically = function(theList, keepFirst)
  * @param language if you want to override system settings, specify language here
  * @returns {String}
  */
-function getLocalizedOrganismName(organism, language)
-{
-    var preferredLanguage = language || environment.currentLanguage;
-    // Fallback in case nothing works
-    if(organism === null)
-    {
-            return gettext("Unnamed");
-    }
-    // Attempting the following languages (in order): current language, default language, English
-    var languages = [preferredLanguage, environment.defaultLanguage, "en"];
-    for(var j in languages)
-    {
-            for(var i in organism.organismLocaleSet)
-            {
-                    var localeSet = organism.organismLocaleSet[i];
-                    //console.log(localeSet);
-                    if(localeSet.organismLocalePK.locale == languages[j])
-                    {
-                            return localeSet.localName;
-                    }
-            }
-    }
-    // Then we try the latin name
-    if(organism.latinName !== null 
-                    && organism.latinName !== "")
-    {
-            return organism.latinName;
-    }
-    // Then the trade name
-    if(organism.tradeName !== null
-                    && organism.tradeName !== "")
-    {
-            return organism.tradeName;
-    }
-    // Then we give up
-    return gettext("Unnamed");
+function getLocalizedOrganismName(organism, language) {
+	var preferredLanguage = language || environment.currentLanguage;
+	// Fallback in case nothing works
+	if (organism === null) {
+		return gettext("Unnamed");
+	}
+	// Attempting the following languages (in order): current language, default language, English
+	var languages = [preferredLanguage, environment.defaultLanguage, "en"];
+	for (var j in languages) {
+		for (var i in organism.organismLocaleSet) {
+			var localeSet = organism.organismLocaleSet[i];
+			//console.log(localeSet);
+			if (localeSet.organismLocalePK.locale == languages[j]) {
+				return localeSet.localName;
+			}
+		}
+	}
+	// Then we try the latin name
+	if (organism.latinName !== null
+		&& organism.latinName !== "") {
+		return organism.latinName;
+	}
+	// Then the trade name
+	if (organism.tradeName !== null
+		&& organism.tradeName !== "") {
+		return organism.tradeName;
+	}
+	// Then we give up
+	return gettext("Unnamed");
 }
 
 /**
@@ -116,30 +100,24 @@ function getLocalizedOrganismName(organism, language)
  * @param cropCategory
  * @returns {String}
  */
-function getLocalizedCropCategoryName(cropCategory)
-{
+function getLocalizedCropCategoryName(cropCategory) {
 	// Fallback in case nothing works
-	if(cropCategory === null)
-	{
+	if (cropCategory === null) {
 		return "Unnamed";
 	}
 	// Attempting the following languages (in order): current language, default language, English
 	var languages = [environment.currentLanguage, environment.defaultLanguage, "en"];
-	for(var j in languages)
-	{
-		for(var i in cropCategory.cropCategoryLocalSet)
-		{
+	for (var j in languages) {
+		for (var i in cropCategory.cropCategoryLocalSet) {
 			var localeSet = cropCategory.cropCategoryLocalSet[i];
-			if(localeSet.cropCategoryLocalPK.locale.trim() == languages[j].trim())
-			{
+			if (localeSet.cropCategoryLocalPK.locale.trim() == languages[j].trim()) {
 				return localeSet.localName;
 			}
 		}
 	}
 	// Then we try the latin name
-	if(cropCategory.defaultName !== null 
-			&& cropCategory.defaultName !== "")
-	{
+	if (cropCategory.defaultName !== null
+		&& cropCategory.defaultName !== "") {
 		return cropCategory.defaultName;
 	}
 	// Then we give up
@@ -147,32 +125,28 @@ function getLocalizedCropCategoryName(cropCategory)
 }
 
 function getLocalizedOptionsHTML(optionsList) {
-    var translatedOptionsHTML = "";
-    var languages = [environment.currentLanguage, environment.defaultLanguage, "en"];
-    
-    for(var i in optionsList){
-        var option = optionsList[i];
-        var label = null;
-        var labelList = option.label;
-	for(var j in languages)
-	{
-		for(var k in labelList)
-		{
-                    if(k === languages[j])
-                    {
-                        label = labelList[k];
-                        break;
-                    }
+	var translatedOptionsHTML = "";
+	var languages = [environment.currentLanguage, environment.defaultLanguage, "en"];
+
+	for (var i in optionsList) {
+		var option = optionsList[i];
+		var label = null;
+		var labelList = option.label;
+		for (var j in languages) {
+			for (var k in labelList) {
+				if (k === languages[j]) {
+					label = labelList[k];
+					break;
+				}
+			}
+			if (label !== null) {
+				break;
+			}
 		}
-            if(label !== null)
-            {
-                break;
-            }
-	}
-        translatedOptionsHTML += '<option value="' + option.value + '"' + (option.selected === "true" ? ' selected="selected"' : '') + ">" + label + "</option>";
-    }
-    
-    return translatedOptionsHTML;
+		translatedOptionsHTML += '<option value="' + option.value + '"' + (option.selected === "true" ? ' selected="selected"' : '') + ">" + label + "</option>";
+	}
+
+	return translatedOptionsHTML;
 }
 
 /** 
@@ -182,24 +156,19 @@ function getLocalizedOptionsHTML(optionsList) {
  * @param {type} ambiguousValue
  * @returns {Number}
  */
-function getUnixTimestampFromJSON(ambiguousValue)
-{
+function getUnixTimestampFromJSON(ambiguousValue) {
 	var possibleDateObject;
-	if(!isMomentJSAvailable())
-	{
+	if (!isMomentJSAvailable()) {
 		possibleDateObject = new Date(ambiguousValue);
 		console.info("Warning: Parsing date without MomentJS. Can't guarantee correct result.");
 	}
-	else
-	{
+	else {
 		possibleDateObject = moment(ambiguousValue).toDate();
 	}
-	if(possibleDateObject.getTime() === NaN && typeof parseInt(ambiguousValue) === "number")
-	{
+	if (possibleDateObject.getTime() === NaN && typeof parseInt(ambiguousValue) === "number") {
 		return parseInt(ambiguousValue);
 	}
-	else
-	{
+	else {
 		return possibleDateObject.getTime();
 	}
 }
@@ -209,15 +178,56 @@ function getUnixTimestampFromJSON(ambiguousValue)
  * 
  * @return {Boolean}
  */
-function isMomentJSAvailable()
-{
+function isMomentJSAvailable() {
 	try {
 		moment();
 		return true;
 	}
-	catch (err)
-	{
+	catch (err) {
 		return false;
 	}
 
-}
\ No newline at end of file
+}
+
+/** Converts numeric degrees to radians 
+ * Essential to make the calculateDistanceBetweenCoordinates to work   
+ **/
+if (typeof Number.prototype.toRad == 'undefined') {
+	Number.prototype.toRad = function () {
+		return this * Math.PI / 180;
+	}
+}
+
+
+
+/**
+	* Reference: <a href="http://www.movable-type.co.uk/scripts/latlong.html">this webpage</a>
+	* <pre>
+	* This uses the "haversine" formula to calculate the great-circle distance between two points ? that is, the shortest distance over the earth?s surface ? giving an ?as-the-crow-flies? distance between the points (ignoring any hills, of course!).
+	Haversine formula:
+			a = sin²(?lat/2) + cos(lat1).cos(lat2).sin²(?long/2)
+			c = 2.atan2(?a, ?(1?a))
+			d = R.c
+	where R is earth's radius (mean radius = 6,371km);
+	Note that angles need to be in radians to pass to trig functions!
+	* </pre>
+	* @param lat1
+	* @param lon1
+	* @param lat2
+	* @param lon2
+	* @return distance in km between to coordinates
+	*/
+function calculateDistanceBetweenCoordinates(lat1, lon1, lat2, lon2) {
+	var R = 6371; // km
+	var dLat = (lat2 - lat1).toRad();
+	var dLon = (lon2 - lon1).toRad();
+	lat1 = lat1.toRad();
+	lat2 = lat2.toRad();
+
+	var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
+		Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
+	var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
+	var d = R * c;
+
+	return d;
+}
diff --git a/src/main/webapp/templates/forecastConfigurationForm.ftl b/src/main/webapp/templates/forecastConfigurationForm.ftl
index 0799bf43865af87052cf051d659562e3ed16abc4..d3a2e3104bd4625c60474abb2dbda70e822b388e 100755
--- a/src/main/webapp/templates/forecastConfigurationForm.ftl
+++ b/src/main/webapp/templates/forecastConfigurationForm.ftl
@@ -50,7 +50,8 @@
             {
                 "pointOfInterestId": "${poi.pointOfInterestId}",
                 "name": "${poi.name?json_string}",
-                "pointOfInterestTypeId": ${poi.pointOfInterestTypeId}
+                "pointOfInterestTypeId": ${poi.pointOfInterestTypeId},
+                "location": <#if poi.longitude?? && poi.latitude??>[${poi.longitude?c}, ${poi.latitude?c}]<#else>null</#if>
             },
             </#list>
         ];
@@ -67,13 +68,19 @@
             };
 
         renderPoiSelect(selectLocationElement, locationList, selectedPoiId);
-        renderWeatherstationSelect(selectWeatherstationElement, locationList, selectedWeatherstationId);
+        
         // Setting weather station select list state correct on page load
         <#if isGridForecastSupported>
         handleUseGridWeatherDataClicked(document.getElementById("useGridWeatherData")<#if forecastConfiguration.weatherStationPointOfInterestId?has_content && forecastConfiguration.weatherStationPointOfInterestId.pointOfInterestId?has_content>,${forecastConfiguration.weatherStationPointOfInterestId.pointOfInterestId}</#if>);
         </#if>
 
-        function renderWeatherstationSelect(selectElement, elementList, selectedId)
+        /**
+        * @param selectElement the select list to render to
+        * @param elementList the list of weather stations to list
+        * @param selectedId the id (optional) to be preselected
+        * @param coordinateToMatch [lon, lat] coordinate to match. Optional. If set:  The 3 closest weather stations are show at top of list, with distance to coordinate.
+        */
+        window.renderWeatherstationSelect = function(selectElement, elementList, selectedId, coordinateToMatch)
         {
             selectElement.options.length = 0;
 
@@ -94,16 +101,42 @@
             ));
 
             // Add all locations that are weatherstations
-            elementList.forEach(poi => {
-                if(poi.pointOfInterestTypeId == POI_TYPE_WEATHERSTATION)
-                {
-                    selectElement.appendChild(createOption(
-                    poi.pointOfInterestId,
-                    poi.name,
-                    selectedId && poi.pointOfInterestId == selectedId
-                ));
-                }
-            });
+            if(coordinateToMatch != null)
+            {
+                let stations = [];
+                elementList.forEach(poi => {
+                    if(poi.pointOfInterestTypeId == POI_TYPE_WEATHERSTATION)
+                    {
+                        poi.distance = calculateDistanceBetweenCoordinates(poi.location[1], poi.location[0], coordinateToMatch[1], coordinateToMatch[0]).toFixed(1);
+                        stations.push(poi);
+                    }
+                });
+                stations.sort(function(a,b){
+                    return a.distance - b.distance;
+                });
+                stations.forEach(poi => {
+                        selectElement.appendChild(createOption(
+                        poi.pointOfInterestId,
+                        poi.name + " (" + poi.distance +" km)",
+                        selectedId && poi.pointOfInterestId == selectedId
+                    ));
+                });
+                
+            }
+            else 
+            {
+                // Render all
+                elementList.forEach(poi => {
+                    if(poi.pointOfInterestTypeId == POI_TYPE_WEATHERSTATION)
+                    {
+                        selectElement.appendChild(createOption(
+                        poi.pointOfInterestId,
+                        poi.name,
+                        selectedId && poi.pointOfInterestId == selectedId
+                    ));
+                    }
+                });
+            }
         }
 
         // Populate select list for point of interest -> NOT GENERAL! Default value is specific to location.
@@ -127,6 +160,8 @@
             });
         }
 
+        renderWeatherstationSelect(selectWeatherstationElement, locationList, selectedWeatherstationId);
+
         window.selectPoi = function(selectElement, selectedId) {
             if (selectedId) {
                 const optionIndex = Array.from(selectElement.options).findIndex(option => option.value == selectedId);
@@ -403,6 +438,7 @@
 
 
           let handleLocationChanged = function(){
+            let weatherstationSelect = document.getElementById("weatherStationPointOfInterestId");
             // Which location has been selected?
             let selectedPoiId = document.getElementById("locationPointOfInterestId").options[document.getElementById("locationPointOfInterestId").selectedIndex].value;
             if(selectedPoiId <= 0)
@@ -414,7 +450,6 @@
             // Enable the weather datasource fieldset
             document.getElementById("weatherDatasourceFieldset").disabled=false;
             
-            
             let selectedLocation = undefined;
             for(let i=0; i<locationList.length;i++)
             {
@@ -424,24 +459,22 @@
                 }
             }
 
-            <#if isGridForecastSupported>
-
-            let gridCheckBox = document.getElementById("useGridWeatherData");
-            gridCheckBox.checked = (selectedLocation.pointOfInterestTypeId != POI_TYPE_WEATHERSTATION);
-            handleUseGridWeatherDataClicked(gridCheckBox, (selectedLocation.pointOfInterestTypeId == POI_TYPE_WEATHERSTATION ? selectedLocation.pointOfInterestId: undefined));
-            
-            <#else>
-            
-            weatherStationList = document.getElementById("weatherStationPointOfInterestId");
             if(selectedLocation.pointOfInterestTypeId == POI_TYPE_WEATHERSTATION)
             {
-                selectPoi(weatherStationList, selectedLocation.pointOfInterestId);
+                renderWeatherstationSelect(weatherstationSelect,locationList, selectedLocation.pointOfInterestId, null);
             }
             else
             {
-                weatherStationList.selectedIndex = 0;
+                renderWeatherstationSelect(weatherstationSelect,locationList, null, selectedLocation.location);
+                weatherstationSelect.selectedIndex = 0;
             }
-            
+
+            <#if isGridForecastSupported>
+
+            let gridCheckBox = document.getElementById("useGridWeatherData");
+            gridCheckBox.checked = (selectedLocation.pointOfInterestTypeId != POI_TYPE_WEATHERSTATION);
+            handleUseGridWeatherDataClicked(gridCheckBox, (selectedLocation.pointOfInterestTypeId == POI_TYPE_WEATHERSTATION ? selectedLocation.pointOfInterestId: undefined));
+
             </#if>
           }
 	</script>
@@ -538,9 +571,9 @@
       <#if isGridForecastSupported>
       <div class="alert alert-info" role="alert">Velg sted ovenfor først, og velg deretter værdatakilde. Du kan enten velge en av de tilgjengelige værstasjonene, 
     eller at ditt valgte steds plassering brukes til å hente værdata fra en ekstern tjeneste. Hvis ditt sted ligger nær
-    en av værstasjonene, gir det som oftest den beste kvaliteten på værdata.</div>
+    en av værstasjonene, gir det som oftest den beste kvaliteten på værdata. Hvis stedet du har valgt ikke er en værstasjon, vil værstasjonslista sorteres etter avstand til ditt sted.</div>
     <#else>
-    <div class="alert alert-info" role="alert">Velg sted ovenfor først, og velg deretter værdatakilde.</div>
+    <div class="alert alert-info" role="alert">Velg sted ovenfor først, og velg deretter værstasjon. Hvis stedet du har valgt ikke er en værstasjon, vil værstasjonslista sorteres etter avstand til ditt sted.</div>
     </#if>
     <fieldset id="weatherDatasourceFieldset" <#if !forecastConfiguration.weatherStationPointOfInterestId?has_content>disabled</#if>>
     <legend style="margin-bottom: 0px;">${i18nBundle.weatherDatasource}</legend>