Reputation: 11
I am trying to log weather data for a university hydrological project using java. The data is formated as a json file in 5 minute intervals for the last 24 hours in the following way (example):
{
"1482439800":{
"hu":92,
"te":-2.9,
"dp":-4.5,
"pr":1028.4,
"pa":null,
"ws":1.4,
"wd":180
},
"1482440100":{
"hu":92,
"te":-2.9,
"dp":-4.5,
"pr":1028.4,
"pa":null,
"ws":1.4,
"wd":180
}
}
I have already tried to use the following code to access data from the json file:
private static String readUrl(String urlString) throws Exception {
BufferedReader reader = null;
try {
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1)
buffer.append(chars, 0, read);
return buffer.toString();
} finally {
if (reader != null)
reader.close();
}
}
public static Object[][] getstation1(){
Object[][] data = null;
try {
JSONObject json = new JSONObject(readUrl("http://netzwerk.wetter.com/api/stationdata/14091/24/"));
Iterator keys = json.keys();
while (keys.hasNext()) {
Object key = keys.next();
JSONObject value = json.getJSONObject((String) key);
double hu = value.getDouble("hu");
System.out.println(hu);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
This was somewhat successful as it returned data for humidity (hu) but in a seemingly random order.
Now for my question: How do I read the times and return them alongside the corresponding weather data from newest to oldest inside the Object[][]?
Any help is appreciated. Thank you.
Upvotes: 1
Views: 1207
Reputation: 11
Thanks for the answer but in the end I decided to go a slightly simpler route. I retrieved all the key names, sorted them and then read the corresponding data key by key. And as I was getting frequent errors because of data being null I added protection for that as well (I need them as actual numbers).
public static Object[][] getstation1(){
Object[][] data = null;
try {
JSONObject json = new JSONObject(readUrl("http://netzwerk.wetter.com/api/stationdata/14091/2/"));
System.out.println("Fetching "+"http://netzwerk.wetter.com/api/stationdata/14091/2/");
String[] times = json.getNames(json);
Arrays.sort(times);
data = new Object[times.length][8];
for (int i = 0; i < times.length; i++){
Date temp = new Date((long)Integer.parseInt(times[i])*1000);
data[i][0] = temp;
if (json.getJSONObject(times[i]).isNull("hu")){
data[i][1] = 0;
} else {
data[i][1] = json.getJSONObject(times[i]).getDouble("hu");
}
if (json.getJSONObject(times[i]).isNull("te")){
data[i][2] = 0;
} else {
data[i][2] = json.getJSONObject(times[i]).getDouble("te");
}
if (json.getJSONObject(times[i]).isNull("dp")){
data[i][3] = 0;
} else {
data[i][3] = json.getJSONObject(times[i]).getDouble("dp");
}
if (json.getJSONObject(times[i]).isNull("pr")){
data[i][4] = 0;
} else {
data[i][4] = json.getJSONObject(times[i]).getDouble("pr");
}
if (json.getJSONObject(times[i]).isNull("pa")){
data[i][5] = 0;
} else {
data[i][5] = json.getJSONObject(times[i]).getDouble("pa");
}
if (json.getJSONObject(times[i]).isNull("ws")){
data[i][6] = 0;
} else {
data[i][6] = json.getJSONObject(times[i]).getDouble("ws");
}
if (json.getJSONObject(times[i]).isNull("wd")){
data[i][7] = 0;
} else {
data[i][7] = json.getJSONObject(times[i]).getDouble("wd");
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
Upvotes: 0
Reputation: 7286
A sorted map would be more appropriate than an Object[][]
.
Quickly:
TreeMap<String, Object> sorted = new TreeMap<>(json.toMap());
But that will sort alphanumerically (probably fine in your case as the timestamps are all the same length).
You could do a little more work to sort the results into a typed map:
TreeMap<Date, Map<String, Double>> byDate = json.toMap().entrySet().stream()
.collect(Collectors.toMap(
e -> new Date(Long.valueOf(e.getKey()) * 1000),
e -> (Map) e.getValue(),
(a, b) -> {throw new IllegalArgumentException("Duplicate key " + a);},
TreeMap::new
));
If you really need an Object[][]
you can remap your data once it's sorted:
Object[][] data = sorted.entrySet().stream().map(e -> new Object[] {e.getKey(), e.getValue()}).toArray(Object[][]::new);
Or consider using an object mapper like jackson or gson.
Upvotes: 1