A lot #1

Merged
Vulpovile merged 2 commits from feature/current_conditions into master 2025-04-27 04:30:38 +00:00
5 changed files with 306 additions and 85 deletions
Showing only changes of commit 61281e6167 - Show all commits

View File

@@ -67,9 +67,23 @@ public class CanadaDatamartProvider extends ForecastProvider {
String code = data[0].trim(); String code = data[0].trim();
String town = data[1].trim(); String town = data[1].trim();
String province = data[2].trim(); String province = data[2].trim();
String supportedDisplaysString = propertyManager.getStringNoSet("displays-enabled.code."+code, "");
if(supportedDisplaysString.trim().length() <= 0)
supportedDisplaysString = propertyManager.getString("displays-enabled.town."+town.toLowerCase().replaceAll("\\s", "_")+"."+province.toLowerCase().replace("\\s", "_"), "");
float latitude = Float.parseFloat(data[3].trim().substring(0, data[3].length()-1)); float latitude = Float.parseFloat(data[3].trim().substring(0, data[3].length()-1));
float longitude = Float.parseFloat(data[4].trim().substring(0, data[4].length()-1)); float longitude = Float.parseFloat(data[4].trim().substring(0, data[4].length()-1));
towns.add(new TownInfo(code, town, province, latitude, longitude, priority)); TownInfo townInfo = new TownInfo(code, town, province, latitude, longitude, priority);
if(supportedDisplaysString.trim().length() > 0)
{
String[] displays = supportedDisplaysString.split(",");
for(int i = 0; i < displays.length; i++)
{
displays[i] = displays[i].trim();
}
townInfo.setSupportedDisplays(displays);
}
towns.add(townInfo);
} }
} }
} }

View File

@@ -4,6 +4,7 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
import com.flaremicro.util.Util; import com.flaremicro.util.Util;
import com.flaremicro.visualforecast.icons.IconProvider; import com.flaremicro.visualforecast.icons.IconProvider;
@@ -12,6 +13,7 @@ public class DatamartTranslation {
private HashMap<Integer, Byte> iconTranslation = new HashMap<Integer, Byte>(); private HashMap<Integer, Byte> iconTranslation = new HashMap<Integer, Byte>();
private HashMap<String, WeatherLines> stringTranslation = new HashMap<String, WeatherLines>(); private HashMap<String, WeatherLines> stringTranslation = new HashMap<String, WeatherLines>();
private HashMap<String, WeatherLines> fallBacks = new HashMap<String, WeatherLines>();
public DatamartTranslation() { public DatamartTranslation() {
iconTranslation.put(0, IconProvider.SUN.id); iconTranslation.put(0, IconProvider.SUN.id);
@@ -71,10 +73,12 @@ public class DatamartTranslation {
if (info.length == 2) if (info.length == 2)
{ {
stringTranslation.put(info[0].toLowerCase(), new WeatherLines(info[1], "")); stringTranslation.put(info[0].toLowerCase(), new WeatherLines(info[1], ""));
fallBacks.put(info[1], new WeatherLines(info[1], ""));
} }
else if (info.length == 3) else if (info.length == 3)
{ {
stringTranslation.put(info[0].toLowerCase(), new WeatherLines(info[1], info[2])); stringTranslation.put(info[0].toLowerCase(), new WeatherLines(info[1], info[2]));
fallBacks.put(info[1] + " " + info[2], new WeatherLines(info[1], info[2]));
} }
} }
} }
@@ -100,10 +104,154 @@ public class DatamartTranslation {
if (lines == null) if (lines == null)
{ {
System.out.println("FAILED:" + desc.toLowerCase()); System.out.println("FAILED:" + desc.toLowerCase());
return new WeatherLines("TRANSLAT.", "FAILURE"); return getClosestMatching(desc);
} }
else return lines; else return lines;
} }
public WeatherLines getClosestMatching(String desc) {
WeatherLines bestMatch = new WeatherLines("TRANSLAT.", "FAILURE");
desc = desc.toLowerCase();
double bestRatio = Integer.MAX_VALUE;
for (Map.Entry<String, WeatherLines> set : fallBacks.entrySet())
{
double ratio2 = getLevenshteinDistance(desc, set.getKey());
if (ratio2 < bestRatio)
{
bestRatio = ratio2;
bestMatch = set.getValue();
}
}
System.out.println("Got " + bestMatch.line1 + " " + bestMatch.line2 + " for desc " + desc);
return bestMatch;
}
public static int getLevenshteinDistance(CharSequence s, CharSequence t) {
if (s == null || t == null)
{
throw new IllegalArgumentException("Strings must not be null");
}
int n = s.length();
int m = t.length();
if (n == 0)
{
return m;
}
else if (m == 0)
{
return n;
}
if (n > m)
{
// swap the input strings to consume less memory
final CharSequence tmp = s;
s = t;
t = tmp;
n = m;
m = t.length();
}
final int[] p = new int[n + 1];
// indexes into strings s and t
int i; // iterates through s
int j; // iterates through t
int upper_left;
int upper;
char t_j; // jth character of t
int cost;
for (i = 0; i <= n; i++)
{
p[i] = i;
}
for (j = 1; j <= m; j++)
{
upper_left = p[0];
t_j = t.charAt(j - 1);
p[0] = j;
for (i = 1; i <= n; i++)
{
upper = p[i];
cost = s.charAt(i - 1) == t_j ? 0 : 1;
// minimum of cell to the left+1, to the top+1, diagonally left and up +cost
p[i] = Math.min(Math.min(p[i - 1] + 1, p[i] + 1), upper_left + cost);
upper_left = upper;
}
}
return p[n];
}
double findSimilarityRatio(String sentence1, String sentence2) {
HashMap<String, Integer> firstSentenceMap = new HashMap<String, Integer>();
HashMap<String, Integer> secondSentenceMap = new HashMap<String, Integer>();
String[] firstSentenceWords = sentence1.split(" ");
String[] secondSentenceWords = sentence2.split(" ");
for (String word : firstSentenceWords)
{
if (firstSentenceMap.containsKey(word))
{
firstSentenceMap.put(word, firstSentenceMap.get(word) + 1);
}
else
{
firstSentenceMap.put(word, 1);
}
}
for (String word : secondSentenceWords)
{
if (secondSentenceMap.containsKey(word))
{
secondSentenceMap.put(word, secondSentenceMap.get(word) + 1);
}
else
{
secondSentenceMap.put(word, 1);
}
}
double totalWords = 0;
double totalHits = 0;
if (firstSentenceWords.length >= secondSentenceWords.length)
{
totalWords = firstSentenceWords.length;
for (Map.Entry<String, Integer> entry : firstSentenceMap.entrySet())
{
String key = entry.getKey();
if (secondSentenceMap.containsKey(key))
{
totalHits = totalHits + Math.min(secondSentenceMap.get(key), firstSentenceMap.get(key));
}
}
}
else
{
totalWords = secondSentenceWords.length;
for (Map.Entry<String, Integer> entry : secondSentenceMap.entrySet())
{
String key = entry.getKey();
if (firstSentenceMap.containsKey(key))
{
totalHits = totalHits + Math.min(secondSentenceMap.get(key), firstSentenceMap.get(key));
}
}
}
return totalHits / totalWords;
}
} }
class WeatherLines { class WeatherLines {

View File

@@ -11,7 +11,6 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
@@ -26,6 +25,7 @@ import org.xml.sax.SAXException;
import com.flaremicro.util.Util; import com.flaremicro.util.Util;
import com.flaremicro.visualforecast.forecast.DayForecast; import com.flaremicro.visualforecast.forecast.DayForecast;
import com.flaremicro.visualforecast.forecast.DetailedForecast;
import com.flaremicro.visualforecast.forecast.ForecastDetails; import com.flaremicro.visualforecast.forecast.ForecastDetails;
import com.flaremicro.visualforecast.forecast.HourlyForecast; import com.flaremicro.visualforecast.forecast.HourlyForecast;
import com.flaremicro.visualforecast.forecast.TownForecast; import com.flaremicro.visualforecast.forecast.TownForecast;
@@ -77,7 +77,7 @@ public class ForecastProcessor implements Runnable {
return -1; return -1;
} }
public void processHourlyForecast(TownForecast forecast, Document doc) { public HourlyForecast[] processHourlyForecast(Document doc) {
DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmm"); DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmm");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
NodeList hourlyForecast = doc.getElementsByTagName("hourlyForecast"); NodeList hourlyForecast = doc.getElementsByTagName("hourlyForecast");
@@ -106,7 +106,7 @@ public class ForecastProcessor implements Runnable {
} }
} }
} }
forecast.setHourlyForecast(hourlyForecastArray.toArray(new HourlyForecast[0])); return hourlyForecastArray.toArray(new HourlyForecast[0]);
} }
public void processForecasts() { public void processForecasts() {
@@ -115,7 +115,6 @@ public class ForecastProcessor implements Runnable {
ArrayList<TownForecast> townForecasts = new ArrayList<TownForecast>(); ArrayList<TownForecast> townForecasts = new ArrayList<TownForecast>();
for (TownInfo townInfo : towns) for (TownInfo townInfo : towns)
{ {
DayForecast[] dayForecasts = new DayForecast[8];
InputStream is = null; InputStream is = null;
Document doc = null; Document doc = null;
try try
@@ -145,6 +144,41 @@ public class ForecastProcessor implements Runnable {
if (doc != null) if (doc != null)
{ {
TownForecast tf = new TownForecast(townInfo.townName + ", " + townInfo.province, process7DayForecast(doc));
townForecasts.add(tf);
tf.setHourlyForecast(this.processHourlyForecast(doc));
tf.setDetailedForecast(process36HourForecast(doc));
tf.setSupportedDisplays(townInfo.getSupportedDisplays());
}
}
forecastDetails.setTownForecast(townForecasts.toArray(new TownForecast[0]));
setMostRecentForecast(forecastDetails);
}
private DetailedForecast[] process36HourForecast(Document doc)
{
DetailedForecast[] detailedForecast = new DetailedForecast[3];
NodeList nodeList = doc.getElementsByTagName("forecast");
for (int i = 0; i < Math.min(detailedForecast.length, nodeList.getLength()); i++)
{
if (nodeList.item(1).getNodeType() == Node.ELEMENT_NODE)
{
if (nodeList.item(1).getNodeType() == Node.ELEMENT_NODE)
{
Element node = (Element) nodeList.item(i);
String title = XMLUtils.getStringFromTagAttribute(node, "period", "textForecastName");
String textForecast = XMLUtils.getStringFromTag(node, "textSummary");
detailedForecast[i] = new DetailedForecast(title, textForecast);
}
}
}
return detailedForecast;
}
private DayForecast[] process7DayForecast(Document doc)
{
DayForecast[] dayForecasts = new DayForecast[8];
NodeList nodeList = doc.getElementsByTagName("forecast"); NodeList nodeList = doc.getElementsByTagName("forecast");
for (int i = 0; i < nodeList.getLength(); i++) for (int i = 0; i < nodeList.getLength(); i++)
{ {
@@ -224,25 +258,21 @@ public class ForecastProcessor implements Runnable {
dayForecasts[i] = new DayForecast(); dayForecasts[i] = new DayForecast();
} }
} }
TownForecast tf = new TownForecast(townInfo.townName + ", " + townInfo.province, dayForecasts); return dayForecasts;
townForecasts.add(tf);
this.processHourlyForecast(tf, doc);
}
}
forecastDetails.setTownForecast(townForecasts.toArray(new TownForecast[0]));
setMostRecentForecast(forecastDetails);
} }
public void begin() { public void begin() {
if (!running) if (!running)
{ {
running = true; running = true;
new Thread(this).start(); self = new Thread(this);
self.start();
} }
} }
public void end() { public void end() {
running = false; running = false;
if(self != null)
self.interrupt(); self.interrupt();
} }
@@ -262,7 +292,6 @@ public class ForecastProcessor implements Runnable {
@Override @Override
public void run() { public void run() {
self = Thread.currentThread();
while (running) while (running)
{ {
try try

View File

@@ -1,5 +1,11 @@
package com.flaremicro.visualforecast.datamart; package com.flaremicro.visualforecast.datamart;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class TownInfo implements Comparable<TownInfo> { public class TownInfo implements Comparable<TownInfo> {
public final String code; public final String code;
public final String townName; public final String townName;
@@ -7,6 +13,7 @@ public class TownInfo implements Comparable<TownInfo> {
public final float northLat; public final float northLat;
public final float westLong; public final float westLong;
public final int priority; public final int priority;
private Set<String> displays = new HashSet<String>();
public TownInfo(String code, String townName, String province, float northLat, float westLong, int priority) { public TownInfo(String code, String townName, String province, float northLat, float westLong, int priority) {
this.code = code; this.code = code;
@@ -21,4 +28,24 @@ public class TownInfo implements Comparable<TownInfo> {
public int compareTo(TownInfo o) { public int compareTo(TownInfo o) {
return priority - o.priority; return priority - o.priority;
} }
public void addSupportedDisplay(String display)
{
this.displays.add(display);
}
public void setSupportedDisplays(String ... displays){
setSupportedDisplays(Arrays.asList(displays));
}
public void setSupportedDisplays(Collection<String> displays){
this.displays.clear();
this.displays.addAll(displays);
}
public Set<String> getSupportedDisplays()
{
return Collections.unmodifiableSet(displays);
}
} }

View File

@@ -14,10 +14,11 @@ partly cloudy,Partly,Cloudy,
showers or drizzle,Showers/,Drizzle showers or drizzle,Showers/,Drizzle
Chance of showers,Chance,Showers Chance of showers,Chance,Showers
A few showers,Few,Showers A few showers,Few,Showers
chance of drizzle,Chance,Drizzle
Chance of drizzle or rain,Chance,Drizzle Chance of drizzle or rain,Chance,Drizzle
A few flurries or rain showers,Flurries/,Showers A few flurries or rain showers,Flurries/,Showers
Chance of flurries or rain showers,Flurries/,Showers Chance of flurries or rain showers,Flurries/,Showers
Chance of rain showers or flurries,Showers/Flurries Chance of rain showers or flurries,Showers/,Flurries
chance of rain showers or wet flurries,Showers/,Flurries chance of rain showers or wet flurries,Showers/,Flurries
A few flurries,Flurries, A few flurries,Flurries,
Chance of flurries,Chance,Flurries Chance of flurries,Chance,Flurries
@@ -34,6 +35,7 @@ Overcast,Overcast,
Showers,Showers, Showers,Showers,
Chance of showers,Chance,Showers Chance of showers,Chance,Showers
Periods of rain,Scattered,Rain Periods of rain,Scattered,Rain
Periods of drizzle,Scattered,Rain
Mostly Cloudy,Mostly,Cloudy Mostly Cloudy,Mostly,Cloudy
Rain at times heavy,Heavy,Rain Rain at times heavy,Heavy,Rain
A few showers or drizzle,Drizzle A few showers or drizzle,Drizzle
@@ -102,3 +104,4 @@ Snow and blowing snow,Blowing,Snow
Windy,Windy Windy,Windy
Smoke,Smoke Smoke,Smoke
rain showers or flurries,Showers/,Flurries rain showers or flurries,Showers/,Flurries
chance of wet flurries,Wet,Flurries
1 Flurries or rain showers Flurries/ Showers
14 showers or drizzle Showers/ Drizzle
15 Chance of showers Chance Showers
16 A few showers Few Showers
17 chance of drizzle Chance Drizzle
18 Chance of drizzle or rain Chance Drizzle
19 A few flurries or rain showers Flurries/ Showers
20 Chance of flurries or rain showers Flurries/ Showers
21 Chance of rain showers or flurries Showers/Flurries Showers/ Flurries
22 chance of rain showers or wet flurries Showers/ Flurries
23 A few flurries Flurries
24 Chance of flurries Chance Flurries
35 Showers Showers
36 Chance of showers Chance Showers
37 Periods of rain Scattered Rain
38 Periods of drizzle Scattered Rain
39 Mostly Cloudy Mostly Cloudy
40 Rain at times heavy Heavy Rain
41 A few showers or drizzle Drizzle
104 Windy Windy
105 Smoke Smoke
106 rain showers or flurries Showers/ Flurries
107 chance of wet flurries Wet Flurries