## Step 1: Inform User, Ask for Permission to Store Files Locally
## User Input
In this first step we ask the user to give us the "thumbs up" for downloading the required files onto their PC. We specify the location, which is set to "C:/Users/Public/Documents", which is a default file path that can apply to any PC.
In this first step we ask the user to give us the "thumbs up" for downloading the required files onto their PC. We set the default directory to "C:/Users/Public/Documents", which is given on any PC. Nonetheless, we wanted to let the user specify a different directory if they prefer that.
<details><summary> See the Code for the "userInput1.java class here</summary>
<details><summary> See the Code for the "userInput.java class here</summary>
```java
packageeot_Sahinovic_Woehs_Zorenboehmer;
importjava.io.File;
importjava.util.Scanner;
publicclassuserInput1{
publicclassUser_input{
Stringdirectory=GoogleEarthTweetMapper.directory;
publicstaticStringdirectory;
staticvoidaskUser(){
staticStringaskUser1(){
ScanneraskUser=newScanner(System.in);// warning coming from non-closed scanner. Note: if we close it, subsequent scanners fail to work.
Stringanswer;
// welcome and information for user
System.out.println("Hello! Welcome to this Google Earth Tweet and WMS Mapper!\n\n"
+"This programme will:\n"
+"1: download an image of Boston from a WMS\n"
+"2: convert it into a KML structure\n"
+"3: download a tweets.csv file from the web\n"
+"4: convert it into a KML structure\n"
+"5: launch both kml files in Google Earth\n\n"
+"The downloaded files will be stored at C:\\Users\\Public\\Documents\n"
+"If this is fine, please enter Y below and hit enter to continue! If not, we will stop the programme and you can manually change the directory at the very top of this class's code.");
+"5: create a KML file for a tour in Google Earth\n"
+"6: launch all kml files in Google Earth\n\n"
+"By default, the downloaded files will be stored at: C:\\Users\\Public\\Documents"
+"\nIf this is fine, please enter Y below and hit enter to continue! If not, enter anything else to set a new directory.");
answer=askUser.next();
// askUser.close();
StringnewDirectory=null;
// if yes, set directory to the default and return directory
System.out.println("We have created a small tour to show you the WMS and Tweets in Google Earth. It will automatically begin when Google Earth is launched.\n"
+"Would you like to proceed to launch Google Earth now? Type Y for yes or anything else for no and hit enter.");
answer1=askContinue.next();
askContinue.close();
// if yes, proceed with programme execution. Else, exit programme.
By default, the downloaded files will be stored at: C:\Users\Public\Documents
If this is fine, please enter Y below and hit enter to continue! If not, enter anything else to set a new directory.
k
Please enter a new directory below and hit enter:
C:\Users\Christina\Documents\Intentional_error
Wrong file path. Please try again.
C:\Users\Christina\Documents\Test Folder
New directory set to: C:\Users\Christina\Documents\Test Folder
```
</details>
## Step 2: Web Map Service
## Web Map Service
### 2.1: Connecting and Downloading WMS
### Connecting and Downloading WMS
First, we created a [non-executable class "wms_GetMap"](https://git.sbg.ac.at/s1080384/EoT/-/blob/main/Java%20Codes/Previous%20Versions%20(working%20files)/Christina%2004_07_2021/wms_GetMap.java) that contains a method `getMap()` that:
// Get Map Request: ask client to create a GetMapRequest object
GetMapRequestrequest=wms.createGetMapRequest();
...
...
@@ -369,22 +415,34 @@ public class wms_GetMap {
request.setBBox("-71.13,42.32,-71.03,42.42");
// user interaction: offer additional information
ScanneraskServiceInfo=newScanner(System.in);//warning coming from non-closed scanner. Note: if scanner is closed subsequent scanners fail to work.
Stringanswer;
ScanneraskServiceInfo=newScanner(System.in);// warning coming from non-closed scanner. Note: if scanner is closed subsequent scanners fail to work
Stringanswer1;
Stringanswer2;
System.out.println("\nWould you like additional information on the WMS service while the programme runs? Type Y for yes or anything else for no and hit enter.");
System.out.println("\tThe WMS capabilities are being retreived from a server called: "+serverName+"\n\tAnd the server's title is: "+serverTitle+"\n\t"+
"The requested image will be stored as a .png with dimensions of 1000 x 1000 pixels.\n\t"+
"The coordinate reference system is set to ESPG:4326.");
System.out.println("\tThe WMS capabilities are being retreived from a server called: "+capabilities.getService().getName()+"\n\t"// method to access service infos
+"The server's title is: "+capabilities.getService().getTitle()+"\n\t"
+"The requested image will be stored as a .png with dimensions of 1000 x 1000 pixels.\n\t"
+"The coordinate reference system is set to ESPG:4326.\n\t"
+"The requested GetMap URL is: "+request.getFinalURL());
System.out.println("\nPlease let us know when you are done with this step. Type any keyword and press enter:");
The coordinate reference system is set to ESPG:4326.
The requested GetMap URL is: http://maps.heigit.org/osm-wms/service?REQUEST=GetMap&FORMAT=image%2Fpng&SRS=EPSG:4326&BBOX=-71.13,42.32,-71.03,42.42&VERSION=1.1.1&STYLES=default&SERVICE=WMS&WIDTH=1000&HEIGHT=1000&TRANSPARENT=TRUE&LAYERS=osm_auto%3Aall
Please let us know when you are done with this step. Type any keyword and press enter:
ok
Image was successfully saved at: C:\Users\Public\Documents\boston.png
Image was successfully saved at: C:\Users\Christina\Documents\Test Folder\boston.png
--- Step 1 completed. ---
```
...
...
@@ -430,7 +489,7 @@ The result is this image "boston.png":
Here, we created a [non-executable class "wms_ImageToKML"](https://git.sbg.ac.at/s1080384/EoT/-/blob/main/Java%20Codes/Previous%20Versions%20(working%20files)/Christina%2004_07_2021/wms_ImageToKML.java) that contains a method `wmsTOkml()` that:
...
...
@@ -441,32 +500,31 @@ Here, we created a [non-executable class "wms_ImageToKML"](https://git.sbg.ac.at
```java
packageTest2;
packageeot_Sahinovic_Woehs_Zorenboehmer;
importjava.io.File;
importjava.io.FileWriter;
importjava.io.IOException;
publicclasswms_ImageToKML{
publicclassWMS_ImageToKML{
staticvoidwmsTOkml(){
Stringwms_kml=GoogleEarthTweetMapper.wms_kml;
Stringwms_png=GoogleEarthTweetMapper.wms_png;
Stringwms_kml=execute_programme.wms_kml;
Stringwms_png=execute_programme.wms_png;
System.out.println("Turning local .png of Boston into kml format at: "+wms_kml+"... ");
System.out.println("Turning local .png of Boston into kml format ... ");// Inform
System.out.println("Something went wrong in: TryCatch method");
}
System.out.println("Image converted to kml and stored at: "+wms_kml);
}
}
// write and store file locally
try{
Filekml_file=newFile(wms_kml);
kml_file.createNewFile();
FileWriterwriter=newFileWriter(kml_file);
for(Stringi:kmlArray){
writer.write(i);
}
writer.close();
}catch(IOExceptione){
System.out.println("Error while writing the boston.kml file.");
}
System.out.println("Image converted to kml and stored at: "+wms_kml);
}// wmsTOkml()
}// class
```
...
...
@@ -519,17 +576,17 @@ public class wms_ImageToKML {
<details><summary>See Console Output</summary>
```
Turning local .png of Boston into kml format at: C:\Users\Christina\Documents\EoT\wms_kml_structure.kml...
Image found..
Image converted to kml and stored at: C:\Users\Christina\Documents\EoT\wms_kml_structure.kml
Step 2 completed.
Turning local .png of Boston into kml format ...
Image found...
Image converted to kml and stored at: C:\Users\Christina\Documents\Test Folder\boston.kml
--- Step 2 completed. ---
```
</details>
## Step 3: Downloading and Converting Twitter.csv File
## Downloading and Converting Twitter.csv File
### 3.1: Downloading
### Downloading
Although this step was not included in the assignment instructions, we decided it would be nice for the user to not worry about having to download the .csv file themselves. Therefore we created a [non-executable class "tweets_download"](https://git.sbg.ac.at/s1080384/EoT/-/blob/main/Java%20Codes/Previous%20Versions%20(working%20files)/Christina%2004_07_2021/tweets_download.java) that contains the methods `saveFileFromUrlWithCommonsIO()` and `downloadCSV()` that:
...
...
@@ -539,7 +596,7 @@ Although this step was not included in the assignment instructions, we decided i
<details><summary>See the Code for the "tweets_download.java" Class</summary>
```java
packageTest2;
packageeot_Sahinovic_Woehs_Zorenboehmer;
importjava.io.File;
importjava.io.IOException;
...
...
@@ -548,8 +605,9 @@ import java.net.URL;
importorg.apache.commons.io.FileUtils;
publicclasstweets_download{
publicclassTweets_download{
// method for downloading .csv file from web and saving locally
System.out.println("Downloading online tweets.csv and storing locally ... ");
System.out.println("Downloading online tweets.csv and storing locally ... ");// Inform
try{
// call method with relevant parameters
saveFileFromUrlWithCommonsIO(
twitter_csv,
twitter_url);
...
...
@@ -574,9 +633,10 @@ public class tweets_download {
e.printStackTrace();
}
System.out.println("CSV file downloaded and stored at :"+twitter_csv);
}
}
System.out.println("CSV file downloaded and stored at :"+twitter_csv);// Inform
}// downloadCSV()
}// class
```
</details>
...
...
@@ -586,19 +646,19 @@ public class tweets_download {
```
Downloading online tweets.csv and storing locally ...
CSV file downloaded and stored at :C:\Users\Christina\Documents\EoT\tweets.csv
Step 3 completed.
CSV file downloaded and stored at :C:\Users\Christina\Documents\Test Folder\tweets.csv
--- Step 3 completed. ---
```
</details>
### 3.2: Converting .csv into .kml
### Converting .csv into .kml
.....
This step proved to be the most complex one. In the end we used two methods within the tweets_polygons.java class. The first method dynamically determines a colour-code for the placemarks depending on the time of the tweet. The second method creates a kml file that contains 3D polygons for the point locations, with pop-up boxes, time-stamps, and a colour-coded visualisation of the time of the tweet.
**Time Stamp**
In the process of creating this class we had to deal with a few challenges:
After some initial [research](https://developers.google.com/kml/documentation/kmlreference#timestamp) into typical kml-conform time stamps and comparing them to "created_at" column in the tweets.csv file, we chose to aim for a time stamp that was already mostly given in the .csv, but with a few differences:
**Time Stamp:**After some initial [research](https://developers.google.com/kml/documentation/kmlreference#timestamp) into typical kml-conform time stamps and comparing them to "created_at" column in the tweets.csv file, we chose to aim for a time stamp that was already mostly given in the .csv, but with a few differences:
> kml time stamp: 1997-07-16T10:30:15+03:00
...
...
@@ -606,44 +666,430 @@ After some initial [research](https://developers.google.com/kml/documentation/km
We therefore concluded that we needed to add in the "T" where the blank space is and add ":00" at the end.
<details><summary>This is how we created the kml-conform time stamp</summary>
**Creating Polygons from Points:** To solve this, we perfomed some simple math calculations on the lat and lng coordinates of the point locations. This required a few conversions of String to Double and then back into String, to insert the new coordinates into the kml body.
**Colouring the Polygons according to the Time of Tweet:** ....
<details><summary>See the Code for the tweets_polygons.java Class</summary>
// .getTime converts to milliseconds, divide with 1000 to get seconds, additionally divide by 6 to get results within a range of 256 (required for the colouring)
longseconds=date.getTime()/1000/6;// time of current csv row
longsecondsFirstDate=firstDate.getTime()/1000/6;// first time in tweets.csv
// convert to int and calculate time difference since "First Date"
intdifference=(int)(seconds-secondsFirstDate);
// subtract difference from 255 (255 = maximum green colour value)
// this allows us to assign brighter shades to earlier times and darker shades to later times
// if the conversion results in a String with only 1 character, we add another character to fit the required 8-character hexadecimal string
if(changeColor.length()==1){
changeColor="0"+changeColor;
}
// return the formatted colour which is then passed to the kml_color variable to insert into the kml body
// hexadecimal order = alpha(opacity) + blue + green + red
// we dynamically set green according to the tweet time. Opacity and red are at maximum (FF). Blue is 00. This gives dynamic colour ramp from yellow to red.
count++;// count to keep track of how many placemarks are processed
}
br.close();
}catch(IOExceptione){
e.printStackTrace();
}
// turn String array into one single String to then write it into a .kml file
for(inti=1;i<kmlcontent.size();i++){
kmlcontentString=String.join(",",kmlcontent);
}
System.out.println(count+" KML placemarks have been generated.");// Inform
// write and store file
try{
finalFileWriterfw=newFileWriter(twitter_kml);
fw.write(kml_head+kmlcontentString+kml_end);
fw.close();
}catch(IOExceptione){
System.out.println("error");
}
System.out.println("All "+count+" placemarks have been integrated into a single KML file, which is saved at "+twitter_kml);// Inform
}// tweetsToPolygons()
}// class
```
</details>
<details><summary>See the Console Output</summary>
```
Accessing local tweets.csv file and converting into kml file ...
1163 KML placemarks have been generated.
All 1163 placemarks have been integrated into a single KML file, which is saved at C:\Users\Christina\Documents\Test Folder\tweets_polygons.kml
--- Step 4 completed. ---
```
</details>
## Creating a KML Tour
Although not technically required, we though it would improve the user experience to be guided through the results in Google Earth. We therefore created our own KML tour and integrated it into a non-executable .java class that stores the tour.kml locally.
<details><summary>See the Code for the googleEarth_Tour.java Class</summary>