package it.polito.sol;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
import genVtypeprobe.TimestepType;
import genVtypeprobe.VtypeprobesType;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class ParseXML {
//modifica le cose in modo da lavorare su mappa istanziata nella factory e "passata" alle varie funzioni penso migliori //FIXME
private Constant c;
public ParseXML(Constant c,int i,Boolean piccolo,HashMap<Float, ArrayList<Vehicle>> time_map,HashMap<String, TreeMap<Float, Vehicle>> all_vehicles, Map<String, String> keymapHashMap) throws MyException {
this.c=c;
try {
System.out.println("file: "+i);
System.out.println("ParseXML start unmarshal dimensione heap:");
c.printMemory();
System.out.println("parsing the schema........");
JAXBContext jaxbC_vtypeprobe = JAXBContext
.newInstance("genVtypeprobe");
Unmarshaller unmarshallerV = jaxbC_vtypeprobe.createUnmarshaller();
SchemaFactory schemaF = SchemaFactory
.newInstance(W3C_XML_SCHEMA_NS_URI);
Schema schema_V = schemaF.newSchema(new File(
"xsd/vtypeprobe.xsd"));
unmarshallerV.setSchema(schema_V);
JAXBElement<VtypeprobesType> elem_v;
if(piccolo){
// elem_v=(JAXBElement<VtypeprobesType>)unmarshallerV.unmarshal(new File("xml/Cologne_150sec.xml"));
/**62205**/ elem_v=(JAXBElement<VtypeprobesType>)unmarshallerV.unmarshal(new File("xml/fileS"+i+".xml"));
}else{
/**62205**/ elem_v=(JAXBElement<VtypeprobesType>)unmarshallerV.unmarshal(new File("xml_fasulli/file"+i+".xml"));
}
//elem_v=(JAXBElement<VtypeprobesType>)unmarshallerV.unmarshal(new File("xml/file_small"+i+".xml"));
//elem_v=(JAXBElement<VtypeprobesType>)unmarshallerV.unmarshal(new File("xml/small.xml"));
/**62205**///elem_v=(JAXBElement<VtypeprobesType>)unmarshallerV.unmarshal(new File("xml/Cologne_150sec.xml"));
/**343k**/ //elem_v=(JAXBElement<VtypeprobesType>)unmarshallerV.unmarshal(new File("xml/Cologne_vtypeprobe.xml"));
System.out.println("ParseXML unmarshal finito dimensione heap:");
c.printMemory();
loadInfo(keymapHashMap, elem_v, all_vehicles,time_map);
} catch (SAXParseException spe) {
throw new MyException(spe.getMessage()+" cause: "+spe.getCause());
} catch (JAXBException je) {
throw new MyException(je.getMessage()+" cause: "+je.getCause());
} catch (SAXException sxe) {
throw new MyException(sxe.getMessage()+" cause: "+sxe.getCause());
} catch (SecurityException se) {
throw new MyException(se.getMessage()+" cause: "+se.getCause());
} catch (NullPointerException npe) {
throw new MyException(npe.getMessage()+" cause: "+npe.getCause());
} catch (IllegalArgumentException iae) {
throw new MyException(iae.getMessage()+" cause: "+iae.getCause());
}
//System.out.println(System.currentTimeMillis());
}
public void loadInfo(Map<String, String> keymap, JAXBElement<VtypeprobesType> elem_v, HashMap<String, TreeMap<Float, Vehicle>> all_vehicles, HashMap<Float, ArrayList<Vehicle>> time_map) throws MyException { // carico info dei veicoli e tempo
Integer i = 0;
System.out.println("loading info........");
ArrayList<Vehicle> vehicle_array;
TreeMap<Float, Vehicle> time_vehicle;
Vehicle objv = null;
VtypeprobesType v = elem_v.getValue();
List<TimestepType> timestepList = v.getTimestep();
for(TimestepType timeS:timestepList){// scorro tempi
//System.out.println(System.currentTimeMillis()+" inizio parse tempo: "+timeS.getTime());
if (timeS.getTime() == null) {
throw new MyException("time must exist");
}
Float time = new Float(timeS.getTime().floatValue());
List<genVtypeprobe.VehicleType> Vlist = timeS.getVehicle();
vehicle_array = new ArrayList<Vehicle>();
for(genVtypeprobe.VehicleType ve: Vlist){ //scorro veicoli
// needed value check
if (ve.getId() == null) {
throw new MyException("Id must exist");
}
if (ve.getLon() == null) {
throw new MyException("longitudine mst exist");
}
if (ve.getLat() == null) {
throw new MyException("latitudine mst exist");
}
if (ve.getSpeed() == null) {
throw new MyException("speed mst exist");
}
String idv=null;
if(keymap.containsKey(ve.getId())){
idv = keymap.get(ve.getId());
}else{
idv=new String(ve.getId());
keymap.put(idv, idv);
}
Float lon = new Float(ve.getLon().floatValue());
Float lat = new Float(ve.getLat());
Float speed = new Float(ve.getSpeed().floatValue());
objv = new Vehicle(idv,lat,lon,speed,time);
//countVehicles++; // numero di oggetti veicolo totali
/*** inserisco i veicoli nella mappa di tutti i veicoli senza doppioni**/
if (!all_vehicles.containsKey(idv)) { // se la mappa non contiene quel veicolo lo aggiungo
time_vehicle = new TreeMap<Float, Vehicle>();
time_vehicle.put(time, objv);
all_vehicles.put(idv, time_vehicle);
} else { // se la mappa contiene idveicolo
all_vehicles.get(idv).put(time, objv); // aggiungo solo alla time_vehicle map
}
fillDistances(objv, vehicle_array); //TODO here
vehicle_array.add(objv);
}// fine while per mappa veicoli
i++;
time_map.put(time, vehicle_array);
//System.out.println(System.currentTimeMillis()+"fine parse tempo: "+timeS.getTime());
}// fine while per la mappa dei tempi
System.out.println("count time: "+time_map.size());
//stampaTuttiVeicoli(all_vehicles);
}
/**
* aggiunge nella mappa solo i veicoli a distanza 100m (in generale dmax-dmin)
* @param newVehicle
* @param arrayV
*/
private void fillDistances(Vehicle newVehicle, ArrayList<Vehicle> arrayV) {//FIXME
Double d;
for (Vehicle oldvehicle : arrayV) { // scorro array dei veicoli
/*** calcolo distanza tra due veicoli oldvehicle e newvehicle ***/
d = new Double(distance(oldvehicle.getLat(), newVehicle.getLat(),
oldvehicle.getLon(), newVehicle.getLon(), 0, 0));
if (d <= this.c.getDmax() && d >= this.c.getDmin()){
newVehicle.addDistances(d.floatValue(), oldvehicle, this.c.getDmin(),this.c.getDmax()); // aggiungo dist alla mappa dist del veicolo nuovo
oldvehicle.addDistances(d.floatValue(), newVehicle,this.c.getDmin(),this.c.getDmax()); // aggiungo dist alla mappa dist veicolo vecchio
}
}
}
/**
* Calculate distance between two points in latitude and longitude taking
* into account height difference. If you are not interested in height
* difference pass 0.0. Uses,aversine method as its base.
*
* lat1, lon1 Start point lat2, lon2 End point el1 Start altitude in meters
* el2 End altitude in meters
*/
private double distance(double lat1, double lat2, double lon1, double lon2,
double el1, double el2) {
final int R = 6371; // Radius of the earth
Double latDistance = deg2rad(lat2 - lat1);
Double lonDistance = deg2rad(lon2 - lon1);
Double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
+ Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
* Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double distance = R * c * 1000; // convert to meters
double height = el1 - el2;
distance = Math.pow(distance, 2) + Math.pow(height, 2);
return Math.sqrt(distance);
}
private double deg2rad(double deg) {
return (deg * Math.PI / 180);
}
/***
* =========================================== STAMPE ===================================================
***/
/*
private void stampaTuttiVeicoli(HashMap<String, TreeMap<Float, Vehicle>> map) {
for (Entry<String, TreeMap<Float, Vehicle>> entry : all_vehicles.entrySet()) {
System.out.println(" ID veicolo...." + entry.getKey());
for (Entry<Float, Vehicle> entry2 : entry.getValue().entrySet()) {
System.out.println(" time...." + entry2.getKey()
+ " oggetto id...." + entry2.getValue().getId());
}
}
System.out.println(" size...." + all_vehicles.size());
}
*/
}