package it.unito.geosummly.io;
import it.unito.geosummly.BoundingBox;
import it.unito.geosummly.io.templates.VenueTemplate;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.TimeZone;
import com.google.gson.stream.JsonWriter;
public class GeoJSONWriter implements IGeoWriter{
@Override
public void writeStream(BoundingBox bbox, HashMap<Integer, String> labels,
HashMap<Integer, ArrayList<ArrayList<Double>>> cells,
HashMap<Integer, ArrayList<ArrayList<String>>> venues,
HashMap<Integer, Double> cDistance,
HashMap<Integer, Double> cSSE,
HashMap<Integer, Double> cSurface,
HashMap<Integer, Double> cHeterogeneity,
HashMap<Integer, Double> cDensity,
double eps,
String output,
Calendar cal)
{
try {
//Get the current date. Example: 2014-03-19T17:10:57.616Z
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd'T'H:mm:ss.SSS'Z'");
dateFormat.setLenient(false); //now month index starts from 1
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); //set UTC time zone
String date=dateFormat.format(cal.getTime());
//Create GeoJSON
File dir=new File(output); //create the output directory if it doesn't exist
dir.mkdirs();
OutputStream os= new FileOutputStream(new File(dir.getPath().concat("/clustering-output-eps").concat(eps+"").concat(".geojson")));
ArrayList<Integer> keys=new ArrayList<Integer>(labels.keySet()); //keys of clusters
String name; //cluster label
int key; //cluster key
ArrayList<ArrayList<String>> venuesOfCell; //all venues of a cell
DecimalFormat df=new DecimalFormat("#.###############");
JsonWriter writer = new JsonWriter(new OutputStreamWriter(os, "UTF-8"));
writer.setIndent(" ");
writer.beginObject();
writer.name("type").value("FeatureCollection");
writer.name("features");
writer.beginArray();
//iterate for each cluster
for(Integer i: keys)
{
name=labels.get(i);
key=i;
ArrayList<ArrayList<Double>> cellsOfCluster=new ArrayList<ArrayList<Double>>(cells.get(i));
ArrayList<VenueTemplate> vo_array=new ArrayList<VenueTemplate>();
//iterate for each venue of the cluster
Object tmp=venues.get(key);
if(tmp!=null) {
venuesOfCell=new ArrayList<ArrayList<String>>(venues.get(key));
for(ArrayList<String> r: venuesOfCell) {
Long timestamp=Long.parseLong(r.get(0));
Integer bH=Integer.parseInt(r.get(1));
Double vLat=Double.parseDouble(df.format(Double.parseDouble(r.get(3))).replaceAll(",", "."));
Double vLng=Double.parseDouble(df.format(Double.parseDouble(r.get(4))).replaceAll(",", "."));
Double fLat=Double.parseDouble(df.format(Double.parseDouble(r.get(5))).replaceAll(",", "."));
Double fLng=Double.parseDouble(df.format(Double.parseDouble(r.get(6))).replaceAll(",", "."));
//create a VenueObject with the venue informations
VenueTemplate vo=new VenueTemplate(timestamp, bH, r.get(2), vLat, vLng, fLat, fLng, r.get(7));
vo_array.add(vo);
}
}
writer.beginObject();
writer.name("type").value("Feature");
writer.name("id").value(key);
writer.name("cells");
writer.beginArray();
for (ArrayList<Double> cell : cells.get(i))
writer.value(cell.get(0).intValue()); //serialize only the cell id
writer.endArray();
writer.name("geometry");
writer.beginObject();
writer.name("type").value("MultiPoint");
writer.name("coordinates");
writer.beginArray();
// serialize inside the MultiPoint the lat,long of the centroids
//iterate for each cell of the cluster
// for(ArrayList<Double> cl: cellsOfCluster) {
// String s1=df.format(cl.get(1)).replaceAll(",", ".");
// String s2=df.format(cl.get(2)).replaceAll(",", ".");
// writer.beginArray();
// writer.value(Double.parseDouble(s1));
// writer.value(Double.parseDouble(s2));
// writer.endArray();
// }
//serialize inside the MultiPoint lat, long of the venues
for(VenueTemplate obj: vo_array)
{
String s1=df.format(obj.getVenueLatitude()).replaceAll(",", ".");
String s2=df.format(obj.getVenueLongitude()).replaceAll(",", ".");
writer.beginArray();
writer.value(Double.parseDouble(s1));
writer.value(Double.parseDouble(s2));
writer.endArray();
}
writer.endArray();
writer.endObject();
writer.name("properties");
writer.beginObject();
writer.name("clusterId").value(key+1);
writer.name("name").value(name);
writer.name("surface").value(cSurface.get(key));
writer.name("density").value(cDensity.get(key));
writer.name("heterogeneity").value(cHeterogeneity.get(key));
writer.name("sse").value(cSSE.get(key));
writer.name("distance").value(cDistance.get(key));
writer.name("venues");
writer.beginArray();
//write down all the VenueObjects of the cluster
for(VenueTemplate obj: vo_array) {
writer.beginObject();
writer.name("timestamp").value(obj.getTimestamp());
if(obj.getBeenHere()>0)
writer.name("beenHere").value(obj.getBeenHere());
writer.name("id").value(obj.getId());
writer.name("venueLatitude").value(obj.getVenueLatitude());
writer.name("venueLongitude").value(obj.getVenueLongitude());
writer.name("centroidLatitude").value(obj.getCentroidLatitude());
writer.name("centroidLongitude").value(obj.getCentroidLongitude());
writer.name("category").value(obj.getCategory());
writer.endObject();
}
writer.endArray();
writer.endObject();
writer.endObject();
}
writer.endArray();
writer.name("properties");
writer.beginObject();
writer.name("name").value("geosummly");
writer.name("bbox");
writer.beginObject();
writer.name("north").value(bbox.getNorth());
writer.name("east").value(bbox.getEast());
writer.name("south").value(bbox.getSouth());
writer.name("west").value(bbox.getWest());
writer.endObject();
writer.name("date").value(date);
writer.name("eps").value(eps);
writer.endObject();
writer.endObject();
writer.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void writerAfterOptimization(
BoundingBox bbox,
List<Integer> selected,
ArrayList<ArrayList<ArrayList<Double>>> multipoints,
ArrayList<ArrayList<Integer>> cellIDs, ArrayList<Double> surface,
ArrayList<Double> density,
ArrayList<Double> heterogeneity,
ArrayList<Double> sse,
ArrayList<Double> distance,
ArrayList<ArrayList<VenueTemplate>> venues,
ArrayList<String[]> labels,
double eps,
String date,
String output,
String preamble
)
{
try {
//Create GeoJSON
File dir=new File(output); //create the output directory if it doesn't exist
dir.mkdirs();
OutputStream os= new FileOutputStream(
new File(dir.getPath().concat("/" + preamble + "-clustering-output-eps").concat(eps+"").concat(".geojson")));
String name=""; //cluster label
int key; //cluster key
ArrayList<ArrayList<Double>> multipointsOfCluster; //cells informations (cell_lat, cell_lng) of a cluster
JsonWriter writer = new JsonWriter(new OutputStreamWriter(os, "UTF-8"));
writer.setIndent(" ");
writer.beginObject();
writer.name("type").value("FeatureCollection");
writer.name("features");
writer.beginArray();
//iterate for each cluster
for(int i=0;i<multipoints.size();i++)
{
name="";
for(String s: labels.get(i))
name=name.concat(s).concat(",");
name=name.substring(0, name.length()-1); //delete last comma
key=selected.get(i);
multipointsOfCluster=new ArrayList<ArrayList<Double>>(multipoints.get(i)); //get the cells of the ith cluster
writer.beginObject();
writer.name("type").value("Feature");
writer.name("id").value(key-1);
ArrayList<Integer> cells = cellIDs.get(i);
writer.name("cells");
writer.beginArray();
for (Integer cell : cells)
writer.value(cell);
writer.endArray();
writer.name("geometry");
writer.beginObject();
writer.name("type").value("MultiPoint");
writer.name("coordinates");
writer.beginArray();
//iterate for each geometry point of the cluster
for(ArrayList<Double> cl: multipointsOfCluster) {
writer.beginArray();
writer.value(cl.get(0));
writer.value(cl.get(1));
writer.endArray();
}
writer.endArray();
writer.endObject();
writer.name("properties");
writer.beginObject();
writer.name("clusterId").value(key);
writer.name("name").value(name);
writer.name("surface").value(surface.get(selected.get(i)-1));
writer.name("density").value(density.get(selected.get(i)-1));
writer.name("heterogeneity").value(heterogeneity.get(selected.get(i)-1));
writer.name("sse").value(sse.get(selected.get(i)-1));
writer.name("distance").value(distance.get(selected.get(i)-1));
writer.name("venues");
writer.beginArray();
//write down all the VenueObjects of the cluster
for(VenueTemplate obj: venues.get(i)) {
writer.beginObject();
writer.name("timestamp").value(obj.getTimestamp());
if(obj.getBeenHere()>0)
writer.name("beenHere").value(obj.getBeenHere());
writer.name("id").value(obj.getId());
writer.name("venueLatitude").value(obj.getVenueLatitude());
writer.name("venueLongitude").value(obj.getVenueLongitude());
writer.name("centroidLatitude").value(obj.getCentroidLatitude());
writer.name("centroidLongitude").value(obj.getCentroidLongitude());
writer.name("category").value(obj.getCategory());
writer.endObject();
}
writer.endArray();
writer.endObject();
writer.endObject();
}
writer.endArray();
writer.name("properties");
writer.beginObject();
writer.name("name").value("geosummly");
writer.name("bbox");
writer.beginObject();
writer.name("north").value(bbox.getNorth());
writer.name("east").value(bbox.getEast());
writer.name("south").value(bbox.getSouth());
writer.name("west").value(bbox.getWest());
writer.endObject();
writer.name("date").value(date);
writer.name("eps").value(eps);
writer.endObject();
writer.endObject();
writer.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}