├── .gitignore ├── .idea ├── vcs.xml ├── .gitignore ├── encodings.xml ├── misc.xml ├── compiler.xml ├── jarRepositories.xml └── uiDesigner.xml ├── src ├── test │ └── java │ │ └── es │ │ └── joseluisgs │ │ └── dam │ │ └── AppTest.java └── main │ ├── java │ └── es │ │ └── joseluisgs │ │ └── dam │ │ ├── model │ │ ├── Informe.java │ │ ├── Estadistica.java │ │ ├── Medicion.java │ │ └── Resumen.java │ │ ├── App.java │ │ ├── service │ │ ├── CSVService.java │ │ ├── XPATHService.java │ │ ├── XMLService.java │ │ └── JAXBService.java │ │ ├── utils │ │ └── FileResources.java │ │ └── controller │ │ └── R2D2Controller.java │ └── resources │ └── data │ ├── data03.csv │ └── data03.xml ├── LICENSE ├── data ├── data03.csv └── data03.xml ├── README.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /out 2 | /target 3 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Datasource local storage ignored files 5 | /dataSources/ 6 | /dataSources.local.xml 7 | # Editor-based HTTP Client requests 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/test/java/es/joseluisgs/dam/AppTest.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | { 12 | /** 13 | * Rigorous Test :-) 14 | */ 15 | @Test 16 | public void shouldAnswerWithTrue() 17 | { 18 | assertTrue( true ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/es/joseluisgs/dam/model/Informe.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam.model; 2 | 3 | import jakarta.xml.bind.annotation.*; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @XmlAccessorType(XmlAccessType.FIELD) 15 | @XmlRootElement(name = "informe") 16 | public class Informe { 17 | @XmlElementWrapper(name = "estadisticas") 18 | @XmlElement(name = "estadistica") 19 | private List estadisticas = new ArrayList(); 20 | } 21 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/es/joseluisgs/dam/App.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam; 2 | 3 | import es.joseluisgs.dam.controller.R2D2Controller; 4 | 5 | import java.net.URISyntaxException; 6 | 7 | /** 8 | * Hello world! 9 | */ 10 | public class App { 11 | public static void main(String[] args) throws URISyntaxException { 12 | System.out.println("Hola RD-D2 Data DAM"); 13 | 14 | var ini = System.currentTimeMillis(); 15 | 16 | R2D2Controller controller = R2D2Controller.getInstance(); 17 | 18 | controller.loadData(); 19 | 20 | controller.proccessData(); 21 | 22 | controller.saveData(); 23 | 24 | var fin = System.currentTimeMillis(); 25 | 26 | System.out.println("Tiempo total: " + (fin - ini) + " ms"); 27 | 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/es/joseluisgs/dam/model/Estadistica.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam.model; 2 | 3 | import jakarta.xml.bind.annotation.*; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @AllArgsConstructor 10 | @NoArgsConstructor 11 | @XmlAccessorType(XmlAccessType.FIELD) 12 | @XmlRootElement(name = "estadistica") 13 | public class Estadistica { 14 | 15 | // Si comento los campos, si tiene sentido el tipo 16 | @XmlElement(name = "NO2") 17 | Resumen NO2 = new Resumen("NO2"); 18 | @XmlElement(name = "Temperatura") 19 | Resumen Temperatura = new Resumen("Temperatura"); 20 | @XmlElement(name = "CO") 21 | Resumen CO = new Resumen("CO"); 22 | @XmlElement(name = "Ozone") 23 | Resumen Ozone = new Resumen("Ozone"); 24 | @XmlAttribute 25 | private String id; 26 | @XmlAttribute 27 | private String fecha; 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 José Luis González Sánchez 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/java/es/joseluisgs/dam/model/Medicion.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.Objects; 8 | 9 | @Data 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class Medicion { 13 | private int id; 14 | private String fecha; 15 | private String tipo; 16 | private double NO2; 17 | private double temperatura; 18 | private double CO; 19 | private double ozone; 20 | 21 | // Uso el equals para luego poder obtener los elementos distintos 22 | @Override 23 | public boolean equals(Object o) { 24 | if (this == o) return true; 25 | if (!(o instanceof Medicion)) return false; 26 | Medicion medicion = (Medicion) o; 27 | return id == medicion.id && Double.compare(medicion.NO2, NO2) == 0 && Double.compare(medicion.temperatura, temperatura) == 0 && Double.compare(medicion.CO, CO) == 0 && Double.compare(medicion.ozone, ozone) == 0 && Objects.equals(fecha, medicion.fecha) && Objects.equals(tipo, medicion.tipo); 28 | } 29 | 30 | @Override 31 | public int hashCode() { 32 | return Objects.hash(id, fecha, tipo, NO2, temperatura, CO, ozone); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/es/joseluisgs/dam/model/Resumen.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam.model; 2 | 3 | import jakarta.xml.bind.annotation.XmlAccessType; 4 | import jakarta.xml.bind.annotation.XmlAccessorType; 5 | import jakarta.xml.bind.annotation.XmlAttribute; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.UUID; 11 | 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | @XmlAccessorType(XmlAccessType.FIELD) 16 | public class Resumen { 17 | @XmlAttribute 18 | private String id = UUID.randomUUID().toString(); 19 | @XmlAttribute 20 | private String tipo; 21 | // Por cada valor que nos piden 22 | private double maxValue; 23 | private String maxDate; 24 | private double minValue; 25 | private String minDate; 26 | private double averageValue; 27 | 28 | public Resumen(String tipo) { 29 | this.tipo = tipo; 30 | } 31 | 32 | public String toMarkDown() { 33 | return "Valores {" + 34 | "maxValue=" + maxValue + 35 | ", maxDate='" + maxDate + '\'' + 36 | ", minValue=" + minValue + 37 | ", minDate='" + minDate + '\'' + 38 | ", averageValue=" + averageValue + 39 | '}'; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /data/data03.csv: -------------------------------------------------------------------------------- 1 | dc:identifier,dc:modified,ayto:type,ayto:latitude,ayto:longitude,ayto:NO2,ayto:ozone,ayto:odometer,ayto:altitude,ayto:temperature,ayto:CO,ayto:particles,ayto:course,ayto:speed,"uri " 2 | 3047,2021-08-27T07:47:39Z,AirQualityObserved,43.449,-3.8677,116.0,120.0,,,22.9,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3047.csv " 3 | 3006,2021-08-27T07:47:34Z,AirQualityObserved,43.4618,-3.8126,115.0,3.0,,,24.1,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3006.csv " 4 | 3011,2021-08-27T07:47:14Z,AirQualityObserved,43.4602,-3.85356,115.0,5.0,,,27.0,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3011.csv " 5 | 3058,2021-08-27T07:47:12Z,AirQualityObserved,43.448,-3.86846,54.0,121.0,,,24.9,0.2,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3058.csv " 6 | 3114,2021-08-27T07:47:00Z,AirQualityObserved,43.4678,-3.83473,110.0,118.0,,,33.4,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3114.csv " 7 | 3078,2021-08-27T07:46:47Z,AirQualityObserved,43.4655,-3.79677,115.0,120.0,,,23.9,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3078.csv " 8 | 3005,2021-08-27T07:46:41Z,AirQualityObserved,43.4629,-3.79301,114.0,11.0,,,23.2,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3005.csv " 9 | 3001,2021-08-27T07:46:33Z,AirQualityObserved,43.4482,-3.86826,84.0,3.0,,,24.2,0.3,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3001.csv " 10 | 3018,2021-08-27T07:46:29Z,AirQualityObserved,43.461,-3.84883,115.0,34.0,,,26.8,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3018.csv " 11 | 3015,2021-08-27T07:46:27Z,AirQualityObserved,43.4393,-3.84471,110.0,120.0,,,23.6,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3015.csv " -------------------------------------------------------------------------------- /src/main/resources/data/data03.csv: -------------------------------------------------------------------------------- 1 | dc:identifier,dc:modified,ayto:type,ayto:latitude,ayto:longitude,ayto:NO2,ayto:ozone,ayto:odometer,ayto:altitude,ayto:temperature,ayto:CO,ayto:particles,ayto:course,ayto:speed,"uri " 2 | 3047,2021-08-27T07:47:39Z,AirQualityObserved,43.449,-3.8677,116.0,120.0,,,22.9,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3047.csv " 3 | 3006,2021-08-27T07:47:34Z,AirQualityObserved,43.4618,-3.8126,115.0,3.0,,,24.1,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3006.csv " 4 | 3011,2021-08-27T07:47:14Z,AirQualityObserved,43.4602,-3.85356,115.0,5.0,,,27.0,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3011.csv " 5 | 3058,2021-08-27T07:47:12Z,AirQualityObserved,43.448,-3.86846,54.0,121.0,,,24.9,0.2,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3058.csv " 6 | 3114,2021-08-27T07:47:00Z,AirQualityObserved,43.4678,-3.83473,110.0,118.0,,,33.4,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3114.csv " 7 | 3078,2021-08-27T07:46:47Z,AirQualityObserved,43.4655,-3.79677,115.0,120.0,,,23.9,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3078.csv " 8 | 3005,2021-08-27T07:46:41Z,AirQualityObserved,43.4629,-3.79301,114.0,11.0,,,23.2,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3005.csv " 9 | 3001,2021-08-27T07:46:33Z,AirQualityObserved,43.4482,-3.86826,84.0,3.0,,,24.2,0.3,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3001.csv " 10 | 3018,2021-08-27T07:46:29Z,AirQualityObserved,43.461,-3.84883,115.0,34.0,,,26.8,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3018.csv " 11 | 3015,2021-08-27T07:46:27Z,AirQualityObserved,43.4393,-3.84471,110.0,120.0,,,23.6,0.1,,,,"http://datos.santander.es/api/datos/sensores_smart_mobile/3015.csv " -------------------------------------------------------------------------------- /src/main/java/es/joseluisgs/dam/service/CSVService.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam.service; 2 | 3 | import es.joseluisgs.dam.model.Medicion; 4 | import es.joseluisgs.dam.utils.FileResources; 5 | 6 | import java.io.IOException; 7 | import java.net.URISyntaxException; 8 | import java.nio.file.Files; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | import java.util.stream.Stream; 12 | 13 | public class CSVService { 14 | private final static String CSV_FILE = "data/data03.csv"; 15 | private static CSVService instance; 16 | private List mediciones; 17 | 18 | private CSVService() { 19 | } 20 | 21 | public static CSVService getInstance() { 22 | if (instance == null) { 23 | instance = new CSVService(); 24 | } 25 | return instance; 26 | } 27 | 28 | public List loadData() throws IOException, URISyntaxException { 29 | FileResources res = FileResources.getInstance(); 30 | Stream lineas = Files.lines(res.getFileFromResource(CSV_FILE).toPath()); 31 | // Skip para saltarnos la primera lineas 32 | return lineas.skip(1).parallel().map(this::parse).collect(Collectors.toList()); 33 | 34 | // Me salto la primera linea y proceso las demas, solo me interesan los datos de la medicion. Voy poco a poco 35 | /*lineas.skip(1).forEach(l -> { 36 | 37 | // Lo demás paso... 38 | //tokenizer.nextToken(); // particles 39 | //tokenizer.nextToken(); // course 40 | //tokenizer.nextToken(); // speed 41 | //tokenizer.nextToken(); // uri 42 | listaMediciones.add(med); 43 | });*/ 44 | // return mediciones; 45 | } 46 | 47 | private Medicion parse(String linea) { 48 | // dc:identifier,dc:modified,ayto:type,ayto:latitude,ayto:longitude,ayto:NO2,ayto:ozone,ayto:odometer,ayto:altitude,ayto:temperature,ayto:CO,ayto:particles,ayto:course,ayto:speed,"uri " 49 | // StringTokenizer tokenizer = new StringTokenizer(linea, ","); 50 | String[] datos = linea.split(","); 51 | Medicion med = new Medicion(); 52 | med.setId(Integer.parseInt(datos[0])); 53 | med.setFecha(datos[1]); 54 | med.setTipo(datos[2]); 55 | med.setNO2(Double.parseDouble(datos[5])); 56 | med.setOzone(Double.parseDouble(datos[6])); 57 | med.setTemperatura(Double.parseDouble(datos[9])); 58 | med.setCO(Double.parseDouble(datos[10])); 59 | return med; 60 | } 61 | 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/es/joseluisgs/dam/service/XPATHService.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam.service; 2 | 3 | 4 | import es.joseluisgs.dam.model.Resumen; 5 | import org.jdom2.Element; 6 | import org.jdom2.filter.Filters; 7 | import org.jdom2.input.DOMBuilder; 8 | import org.jdom2.output.Format; 9 | import org.jdom2.output.XMLOutputter; 10 | import org.jdom2.xpath.XPathExpression; 11 | import org.jdom2.xpath.XPathFactory; 12 | import org.w3c.dom.Document; 13 | 14 | import java.io.IOException; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | public class XPATHService { 19 | private static XPATHService instance; 20 | private static Document document; 21 | // sinq ue sirva de precedentes voy a usar XPATH con JDOM 22 | private static org.jdom2.Document dom; 23 | 24 | 25 | 26 | private XPATHService() { 27 | } 28 | 29 | public static XPATHService getInstance(Document domDocument) { 30 | if (instance == null) { 31 | instance = new XPATHService(); 32 | } 33 | instance.document = domDocument; 34 | instance.dom = instance.convertDOMtoJDOM(domDocument); 35 | return instance; 36 | } 37 | 38 | public List getInfo(String elementTag) throws IOException { 39 | //XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat()); 40 | //xmlOutputter.output(dom, System.out); 41 | 42 | 43 | XPathFactory xpath = XPathFactory.instance(); 44 | XPathExpression expr = xpath.compile("//"+elementTag, Filters.element()); 45 | List values = expr.evaluate(this.dom); 46 | List list = new ArrayList<>(); 47 | values.forEach(element -> { 48 | Resumen resumen = new Resumen(); 49 | //System.out.println(element.getValue()); 50 | resumen.setMaxValue(Double.parseDouble(element.getChild("maxValue").getValue())); 51 | resumen.setMaxDate(element.getChild("maxDate").getValue()); 52 | resumen.setMinValue(Double.parseDouble(element.getChild("minValue").getValue())); 53 | resumen.setMinDate(element.getChild("minDate").getValue()); 54 | resumen.setAverageValue(Double.parseDouble(element.getChild("averageValue").getValue())); 55 | 56 | //System.out.println(resumen); 57 | list.add(resumen); 58 | }); 59 | return list; 60 | } 61 | 62 | // Fucniones axisiales 63 | 64 | public org.jdom2.Document convertDOMtoJDOM(org.w3c.dom.Document input) { 65 | DOMBuilder builder = new DOMBuilder(); 66 | org.jdom2.Document output = builder.build(input); 67 | return output; 68 | } 69 | 70 | // public org.w3c.dom.Document convertJDOMToDOM(org.jdom.Document jdomDoc) throws JDOMException { 71 | // 72 | // DOMOutputter outputter = new DOMOutputter(); 73 | // return outputter.output(jdomDoc); 74 | // } 75 | 76 | private void printDOM() { 77 | XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat()); 78 | try { 79 | xmlOutputter.output(dom, System.out); 80 | } catch (IOException e) { 81 | e.printStackTrace(); 82 | } 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/es/joseluisgs/dam/service/XMLService.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam.service; 2 | 3 | import es.joseluisgs.dam.model.Medicion; 4 | import es.joseluisgs.dam.utils.FileResources; 5 | import org.jdom2.Document; 6 | import org.jdom2.Element; 7 | import org.jdom2.JDOMException; 8 | import org.jdom2.input.SAXBuilder; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.net.URISyntaxException; 13 | import java.util.List; 14 | import java.util.StringTokenizer; 15 | import java.util.stream.Collectors; 16 | 17 | public class XMLService { 18 | private static XMLService instance; 19 | private final static String XML_FILE = "data/data03.xml"; 20 | private List mediciones; 21 | 22 | private XMLService() { 23 | } 24 | 25 | public static XMLService getInstance() { 26 | if (instance == null) { 27 | instance = new XMLService(); 28 | } 29 | return instance; 30 | } 31 | 32 | public List loadData() throws IOException, JDOMException, URISyntaxException { 33 | FileResources res = FileResources.getInstance(); 34 | SAXBuilder sax = new SAXBuilder(); 35 | // XML is a local file 36 | Document doc = sax.build(res.getFileFromResource(XML_FILE)); 37 | // Voy al directorio raíz 38 | Element rootNode = doc.getRootElement(); 39 | // Cojo el elemento resouces 40 | Element resources = rootNode.getChild("resources"); 41 | // me quedo con sus resouces hijos 42 | List resourceList = resources.getChildren("resource"); 43 | System.out.println("Cantidad de recursos: " +resourceList.size()); 44 | // Ahora proceso cada uno 45 | return resourceList.parallelStream().map(this::parse).collect(Collectors.toList()); 46 | } 47 | 48 | private Medicion parse(Element resource) { 49 | /* 50 | 51 | 116.0 52 | AirQualityObserved 53 | 43.449 54 | 22.9 55 | 56 | 57 | 0.1 58 | 2021-08-27T07:47:39Z 59 | 3047 60 | -3.8677 61 | 62 | 63 | 120.0 64 | http://datos.santander.es/api/datos/sensores_smart_mobile/3047.xml 65 | */ 66 | 67 | Medicion med = new Medicion(); 68 | // Elementos str 69 | List strs = resource.getChildren("str"); 70 | // El 1 es NO2 // Otra forma es hacerlo con XPATH 71 | med.setNO2(Double.parseDouble(strs.get(1).getText())); 72 | med.setTipo(strs.get(2).getText()); 73 | med.setCO(Double.parseDouble(strs.get(7).getText())); 74 | med.setId(Integer.parseInt(strs.get(8).getText())); 75 | med.setOzone(Double.parseDouble(strs.get(12).getText())); 76 | // Ahira recorro los str 77 | // Elemento date 78 | med.setFecha(resource.getChild("date").getValue()); 79 | return med; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/es/joseluisgs/dam/utils/FileResources.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam.utils; 2 | 3 | import java.io.*; 4 | import java.net.URISyntaxException; 5 | import java.net.URL; 6 | import java.nio.charset.StandardCharsets; 7 | import java.nio.file.Files; 8 | import java.nio.file.Path; 9 | import java.nio.file.Paths; 10 | import java.util.List; 11 | 12 | public class FileResources { 13 | private static FileResources instance; 14 | 15 | private FileResources() { 16 | } 17 | 18 | public static FileResources getInstance() { 19 | if (instance == null) { 20 | instance = new FileResources(); 21 | } 22 | return instance; 23 | } 24 | 25 | 26 | public InputStream getFileFromResourceAsStream(String fileName) { 27 | ClassLoader classLoader = getClass().getClassLoader(); 28 | InputStream inputStream = classLoader.getResourceAsStream(fileName); 29 | if (inputStream == null) { 30 | throw new IllegalArgumentException("Fichero no encontrado " + fileName); 31 | } else { 32 | return inputStream; 33 | } 34 | } 35 | 36 | public void makeDir(String dir) throws IOException, URISyntaxException { 37 | Path source = Paths.get(this.getClass().getResource("/").getPath()); 38 | Path newFolder = Paths.get(source.toAbsolutePath() + dir); 39 | Files.createDirectories(newFolder); 40 | } 41 | 42 | public void deleteFiles(String dir) throws IOException, URISyntaxException { 43 | Path source = Paths.get(this.getClass().getResource("/").getPath()); 44 | Path folder = Paths.get(source.toAbsolutePath() + dir); 45 | Files.walk(folder) 46 | .filter(Files::isRegularFile) 47 | .map(Path::toFile) 48 | .forEach(File::delete); 49 | } 50 | 51 | public File getPath(String file) throws IOException, URISyntaxException { 52 | Path source = Paths.get(this.getClass().getResource("/").getPath()); 53 | Path fileName = Paths.get(source.toAbsolutePath() + file); 54 | return fileName.toFile(); 55 | } 56 | 57 | 58 | public File getFileFromResource(String fileName) throws URISyntaxException { 59 | ClassLoader classLoader = getClass().getClassLoader(); 60 | URL resource = classLoader.getResource(fileName); 61 | if (resource == null) { 62 | throw new IllegalArgumentException("Fichero no encotrado " + fileName); 63 | } else { 64 | // Falla si hay espacios o carcateres raros... 65 | return new File(resource.toURI()); 66 | } 67 | } 68 | public void printInputStream(InputStream is) { 69 | try (InputStreamReader streamReader = 70 | new InputStreamReader(is, StandardCharsets.UTF_8); 71 | BufferedReader reader = new BufferedReader(streamReader)) { 72 | 73 | String line; 74 | while ((line = reader.readLine()) != null) { 75 | System.out.println(line); 76 | } 77 | 78 | } catch (IOException e) { 79 | e.printStackTrace(); 80 | } 81 | 82 | } 83 | 84 | public void printFile(File file) { 85 | List lines; 86 | try { 87 | lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8); 88 | lines.forEach(System.out::println); 89 | } catch (IOException e) { 90 | e.printStackTrace(); 91 | } 92 | 93 | } 94 | 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/es/joseluisgs/dam/service/JAXBService.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam.service; 2 | 3 | import es.joseluisgs.dam.model.Estadistica; 4 | import es.joseluisgs.dam.model.Informe; 5 | import es.joseluisgs.dam.model.Medicion; 6 | import es.joseluisgs.dam.model.Resumen; 7 | import es.joseluisgs.dam.utils.FileResources; 8 | import jakarta.xml.bind.*; 9 | import org.w3c.dom.Document; 10 | 11 | import javax.xml.parsers.DocumentBuilder; 12 | import javax.xml.parsers.DocumentBuilderFactory; 13 | import javax.xml.parsers.ParserConfigurationException; 14 | import javax.xml.transform.Result; 15 | import javax.xml.transform.stream.StreamResult; 16 | import java.io.File; 17 | import java.io.IOException; 18 | import java.net.URISyntaxException; 19 | 20 | public class JAXBService { 21 | private static JAXBService instance; 22 | private Marshaller marshaller; 23 | private Unmarshaller unmarshaller; 24 | 25 | private JAXBService() { 26 | } 27 | 28 | public static JAXBService getInstance() { 29 | if (instance == null) { 30 | instance = new JAXBService(); 31 | } 32 | return instance; 33 | } 34 | 35 | private void convertObjectToXML(Informe items) throws JAXBException { 36 | // Creamos el contexto 37 | JAXBContext context = JAXBContext.newInstance(Informe.class); 38 | // Marshall --> Object to XML 39 | this.marshaller = context.createMarshaller(); 40 | this.marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 41 | 42 | } 43 | 44 | public void writeXMLFile(String fileName, Informe informe) throws JAXBException, IOException, URISyntaxException { 45 | FileResources resources = FileResources.getInstance(); 46 | File file = resources.getPath(fileName); 47 | convertObjectToXML(informe); 48 | this.marshaller.marshal(informe, file); 49 | System.out.println("Fichero XML generado con éxito"); 50 | } 51 | 52 | public Document toDOM(Informe informe) throws JAXBException, ParserConfigurationException { 53 | // Creamos el documento con JDOM vacío 54 | DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 55 | DocumentBuilder domBuilder = domFactory.newDocumentBuilder(); 56 | Document domDocument = domBuilder.newDocument(); 57 | 58 | convertObjectToXML(informe); 59 | this.marshaller.marshal(informe, domDocument); 60 | return domDocument; 61 | } 62 | 63 | public void printXML(Informe informe) throws JAXBException { 64 | convertObjectToXML(informe); 65 | this.marshaller.marshal(informe, System.out); 66 | } 67 | 68 | private Informe convertXMLToObject(String uri) throws JAXBException { 69 | // Creamos el contexto 70 | JAXBContext context = JAXBContext.newInstance(Informe.class); 71 | this.unmarshaller = context.createUnmarshaller(); 72 | // Unmarshall --> XML toObject 73 | return (Informe) this.unmarshaller.unmarshal(new File(uri)); 74 | } 75 | 76 | // Obtiene el esquema de la clase 77 | public void writeXSDFile(String fileName) throws IOException, URISyntaxException, JAXBException { 78 | JAXBContext context = JAXBContext.newInstance(Informe.class, Estadistica.class, Medicion.class, Resumen.class); 79 | context.generateSchema(new MySchemaOutputResolver(fileName)); 80 | } 81 | 82 | class MySchemaOutputResolver extends SchemaOutputResolver { 83 | FileResources resources = FileResources.getInstance(); 84 | File file; 85 | 86 | 87 | MySchemaOutputResolver(String fileName) throws IOException, URISyntaxException { 88 | file = resources.getPath(fileName); 89 | } 90 | 91 | public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException { 92 | return new StreamResult(file); 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # R2D2 y las Lunas de Endor - AccesoDatos-2021-2022 2 | Nuestro amigo R2-D2 ha sido enviado junto a Luke Skywalker debido a una serie de problemas relacionados con la contaminación en la Luna de Endor. Problema de API Stream, XML para Acceso a Datos. 3 | 4 | [![Java](https://img.shields.io/badge/Code-Java%20v11-blue)](https://www.java.com/es/) 5 | [![LISENCE](https://img.shields.io/badge/Lisence-MIT-green)]() 6 | ![GitHub](https://img.shields.io/github/last-commit/joseluisgs/R2D2-Endor-AccesoDatos) 7 | 8 | 9 | ![imagen](https://cdnb.artstation.com/p/assets/images/images/016/922/017/large/serhii-sirenko-r2-art-3.jpg) 10 | 11 | - [R2D2 y las Lunas de Endor - AccesoDatos-2021-2022](#r2d2-y-las-lunas-de-endor---accesodatos-2021-2022) 12 | - [Enunciado](#enunciado) 13 | - [Autor](#autor) 14 | - [Contacto](#contacto) 15 | - [Licencia](#licencia) 16 | 17 | ## Enunciado 18 | Nuestro amigo R2-D2 ha sido enviado junto a Luke Skywalker debido a una serie de problemas relacionados con la contaminación en la Luna de Endor. Es por ello que mientras Luke se queda investigando, nuestro gran “Arturito” ha usado todos sus sensores para obtener datos del entorno y enviarlos al Halcón Milenario para ser procesados. 19 | 20 | Para ello R2-D2 ha tomado muestras en dos ficheros. Data03.csv y Data03.xml. Pero se ha dado cuenta que el primero de ellos debido a una tormenta eléctrica ha quedado corrupto, por lo que debe completar las mediciones antes de procesarlas con el segundo, solo si esa muestra no existe en base a su identificador. 21 | 22 | De las muestras nos interesan solamente: 23 | 24 | - Identifier: identificador de la muestra 25 | - Modified: Fecha de la medición 26 | - NO2: concentración de dióxido de azufre 27 | - Temperature: temperatura 28 | - CO: concentración de carbono 29 | - Ozone: concentración de ozono 30 | 31 | Todas estas mediciones las meterá en una lista de memoria para poder procesarlas. Para leer el XML se recomienda JDOM 32 | 33 | R2-D2, inicia el procesado de los datos para obtener unos resultados. Para ello nos interesa: 34 | - Nivel máximo, mínimo y media de NO2 y la fecha en la que se registro. 35 | - Nivel máximo, mínimo y media de Temperatura y la fecha en la que se registro. 36 | - Nivel máximo, mínimo y media de Ozono y la fecha en la que se registro 37 | 38 | Una vez que ha procesado los datos usando API STREAM (¡¡¡R2-D2 es la leche para eso!!!), pero los vamos a procesar de 25 en 25, y finalmente los que sobren. realizando los cálculos necesarios en esos 25 registros y salvándolos en una base de datos de registros. 39 | Así hasta que los procesemos todos en grupos de 25, aunque el último puede que tenga menos. 40 | 41 | Cada vez que R2-D2 termine con un grupo de 25 mediciones obteniendo su Resumen, debemos añadirlos a nuestro registros de resuenes o mediciones, teniendo en cuenta que debemos añadirle a cada grupo su identificador y fecha. Esta base de datos de será JAXB. 42 | 43 | Además, vamos a crear los esquemas de las clases y resultados tratados para facilitar su tratamiento desde el Halcón Milenario. 44 | 45 | 46 | Finalmente, con el XML de nuestras base de datos de resúmenes y usando XPATH, R2-D2 nos mostrará los datos de NO2 y Ozono por pantalla y en fichero tipo Markdown llamado informe.md pues parece ser que son los causantes de los problemas detectados. 47 | 48 | ## Autor 49 | 50 | Codificado con :sparkling_heart: por [José Luis González Sánchez](https://twitter.com/joseluisgonsan) 51 | 52 | [![Twitter](https://img.shields.io/twitter/follow/joseluisgonsan?style=social)](https://twitter.com/joseluisgonsan) 53 | [![GitHub](https://img.shields.io/github/followers/joseluisgs?style=social)](https://github.com/joseluisgs) 54 | 55 | ### Contacto 56 |

57 | Cualquier cosa que necesites házmelo saber por si puedo ayudarte 💬. 58 |

59 |

60 | 61 | 63 |    64 | 65 | 67 |    68 | 69 | 71 |    72 | 73 | 75 | 76 |

77 | 78 | 79 | ## Licencia 80 | 81 | Este proyecto está licenciado bajo licencia **MIT**, si desea saber más, visite el fichero [LICENSE](./LICENSE) para su uso docente y educativo. 82 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | es.joseluisgs.dam 8 | rdd2-data 9 | 1.0-SNAPSHOT 10 | 11 | rdd2-data 12 | 13 | http://www.example.com 14 | 15 | 16 | UTF-8 17 | 11 18 | 11 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | 4.11 26 | test 27 | 28 | 29 | org.projectlombok 30 | lombok 31 | RELEASE 32 | compile 33 | 34 | 35 | 36 | 37 | org.jdom 38 | jdom2 39 | 2.0.6.1 40 | 41 | 42 | 43 | jaxen 44 | jaxen 45 | 1.2.0 46 | 47 | 48 | 49 | 50 | jakarta.xml.bind 51 | jakarta.xml.bind-api 52 | 4.0.0 53 | 54 | 55 | 56 | 57 | com.sun.xml.bind 58 | jaxb-impl 59 | 4.0.1 60 | runtime 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | maven-clean-plugin 70 | 3.1.0 71 | 72 | 73 | 74 | maven-resources-plugin 75 | 3.0.2 76 | 77 | 78 | maven-compiler-plugin 79 | 3.8.0 80 | 81 | 82 | maven-surefire-plugin 83 | 2.22.1 84 | 85 | 86 | maven-jar-plugin 87 | 3.0.2 88 | 89 | 90 | maven-install-plugin 91 | 2.5.2 92 | 93 | 94 | maven-deploy-plugin 95 | 2.8.2 96 | 97 | 98 | 99 | maven-site-plugin 100 | 3.7.1 101 | 102 | 103 | maven-project-info-reports-plugin 104 | 3.0.0 105 | 106 | 107 | 108 | 109 | 110 | org.apache.maven.plugins 111 | maven-compiler-plugin 112 | 113 | 11 114 | 11 115 | 116 | 117 | 118 | 119 | 120 | 122 | org.codehaus.mojo 123 | jaxb2-maven-plugin 124 | 2.3 125 | 126 | 127 | schemagen 128 | 129 | schemagen 130 | 131 | 132 | 133 | 134 | 135 | src/main/java/es/joseluisgs/dam/model 136 | 137 | src/main/resources 138 | false 139 | 140 | 141 | /jaxb/gen 142 | user 143 | user-gen.xsd 144 | 145 | 146 | 147 | 148 | 149 | 150 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /src/main/java/es/joseluisgs/dam/controller/R2D2Controller.java: -------------------------------------------------------------------------------- 1 | package es.joseluisgs.dam.controller; 2 | 3 | import es.joseluisgs.dam.model.Estadistica; 4 | import es.joseluisgs.dam.model.Informe; 5 | import es.joseluisgs.dam.model.Medicion; 6 | import es.joseluisgs.dam.model.Resumen; 7 | import es.joseluisgs.dam.service.CSVService; 8 | import es.joseluisgs.dam.service.JAXBService; 9 | import es.joseluisgs.dam.service.XMLService; 10 | import es.joseluisgs.dam.service.XPATHService; 11 | import es.joseluisgs.dam.utils.FileResources; 12 | import jakarta.xml.bind.JAXBException; 13 | import org.jdom2.JDOMException; 14 | 15 | import javax.xml.parsers.ParserConfigurationException; 16 | import java.io.File; 17 | import java.io.FileWriter; 18 | import java.io.IOException; 19 | import java.io.PrintWriter; 20 | import java.net.URISyntaxException; 21 | import java.time.Instant; 22 | import java.util.Comparator; 23 | import java.util.List; 24 | import java.util.Map; 25 | import java.util.UUID; 26 | import java.util.concurrent.ConcurrentHashMap; 27 | import java.util.function.Function; 28 | import java.util.function.Predicate; 29 | import java.util.stream.Collectors; 30 | import java.util.stream.Stream; 31 | 32 | // Lee los ficheros y los procesa 33 | public class R2D2Controller { 34 | private static R2D2Controller instance; 35 | private List medicionesCSV; 36 | private List medicionesXML; 37 | private List mediciones; 38 | private Informe informe; 39 | 40 | private R2D2Controller() { 41 | } 42 | 43 | public static R2D2Controller getInstance() { 44 | if (instance == null) { 45 | instance = new R2D2Controller(); 46 | } 47 | return instance; 48 | } 49 | 50 | // Para quitra con un predicado y no hacer un for if 51 | private static Predicate distinctByKey( 52 | Function keyExtractor) { 53 | Map seen = new ConcurrentHashMap<>(); 54 | return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; 55 | } 56 | 57 | public void loadData() { 58 | loadCSV(); 59 | loadXML(); 60 | // Ahora vamos a fusionar las dios nediciones 61 | fusionData(); 62 | } 63 | 64 | private void fusionData() { 65 | // La forma más sencilla, es concatenar los streams y eliminar los repetidos 66 | Stream combinedStream = Stream.concat( 67 | medicionesXML.stream(), 68 | medicionesCSV.stream()); 69 | // Elimino los repetidos, podria hacerlo con for y si no existe lo miro, o buscando de uno en otro... mil formas 70 | mediciones = combinedStream 71 | //.filter(distinctByKey(Medicion::getId)) 72 | .distinct() // Necesita el méttodo equals en la clase Medicion 73 | .collect(Collectors.toList()); 74 | 75 | //mediciones.forEach(System.out::println); 76 | //System.out.println(mediciones.size()); 77 | } 78 | 79 | private void loadXML() { 80 | XMLService xml = XMLService.getInstance(); 81 | try { 82 | medicionesXML = xml.loadData(); 83 | //medicionesXML.forEach(System.out::println); 84 | } catch (IOException | JDOMException | URISyntaxException e) { 85 | System.err.println("Error al leer el fichero XML"); 86 | } 87 | } 88 | 89 | private void loadCSV() { 90 | CSVService csv = CSVService.getInstance(); 91 | try { 92 | medicionesCSV = csv.loadData(); 93 | //medicionesCSV.forEach(System.out::println); 94 | 95 | } catch (IOException | URISyntaxException e) { 96 | System.err.println("Error al leer el fichero CSV"); 97 | } 98 | } 99 | 100 | // Vamos a procesar de 25 en 25 101 | public void proccessData() { 102 | informe = new Informe(); 103 | final int PAGE_SIZE = 25; 104 | final int NUM_PAGES = (int) Math.ceil(mediciones.size() / (double) PAGE_SIZE); 105 | for (int i = 0; i < NUM_PAGES; i++) { 106 | //System.out.println("Procesando página " + i); 107 | // Dois formas de saxcar las paginas, con sublistas o con stream 108 | //mediciones.stream().skip(i*PAGE_SIZE).limit(PAGE_SIZE).forEach(System.out::println); 109 | //System.out.println(mediciones.stream().skip(i*PAGE_SIZE).limit(PAGE_SIZE).count()); 110 | 111 | // Debemos salvarlo poco a poco por lo que vamos paginando dentro del for... 112 | // los resultados van a informe 113 | informe.getEstadisticas() 114 | .add( 115 | getEstadistica( 116 | // mediciones.subList(i * PAGE_SIZE, Math.min((i + 1) * PAGE_SIZE, mediciones.size())) 117 | mediciones.parallelStream().skip((long) i * PAGE_SIZE).limit(PAGE_SIZE).collect(Collectors.toList()) 118 | ) 119 | ); 120 | } 121 | 122 | } 123 | 124 | private Estadistica getEstadistica(List list) { 125 | // Mil maneras de hacerlo... 126 | // Por ejemplo así por cada medicion 127 | // DoubleSummaryStatistics stats = list.stream().mapToDouble(Medicion::getNO2).summaryStatistics(); 128 | // System.out.println(stats); 129 | // Ahora buscamos las fechas por esos resultados... 130 | 131 | // O así por cada medicion, pero como quiero la fecha lo voy a hacer así 132 | 133 | 134 | /*stream.max((m1, m2) -> Double.compare(m1.getNO2(), m2.getNO2())) 135 | .ifPresent(max -> System.out.println("Maximum found is " + max.getId() + " with value " + max.getNO2())); 136 | stream.min((m1, m2) -> Double.compare(m1.getNO2(), m2.getNO2())) 137 | .ifPresent(min -> System.out.println("Min found is " + min.getId() + " with value " + min.getNO2()));*/ 138 | 139 | Estadistica es = new Estadistica(); 140 | es.setId(UUID.randomUUID().toString()); 141 | es.setFecha(Instant.now().toString()); 142 | 143 | // NO2 144 | // Max 145 | list.parallelStream().max(Comparator.comparingDouble(Medicion::getNO2)) 146 | .ifPresent(max -> { 147 | es.getNO2().setMaxValue(max.getNO2()); 148 | es.getNO2().setMaxDate(max.getFecha()); 149 | }); 150 | // Min 151 | list.parallelStream().min(Comparator.comparingDouble(Medicion::getNO2)) 152 | .ifPresent(min -> { 153 | es.getNO2().setMinValue(min.getNO2()); 154 | es.getNO2().setMinDate(min.getFecha()); 155 | }); 156 | // Media 157 | list.parallelStream().mapToDouble(Medicion::getNO2).average() 158 | .ifPresent(x -> es.getNO2().setAverageValue(x)); 159 | 160 | // Temperatura 161 | list.parallelStream().max(Comparator.comparingDouble(Medicion::getTemperatura)) 162 | .ifPresent(max -> { 163 | es.getTemperatura().setMaxValue(max.getTemperatura()); 164 | es.getTemperatura().setMaxDate(max.getFecha()); 165 | }); 166 | list.stream().min(Comparator.comparingDouble(Medicion::getTemperatura)) 167 | .ifPresent(min -> { 168 | es.getTemperatura().setMinValue(min.getTemperatura()); 169 | es.getTemperatura().setMinDate(min.getFecha()); 170 | }); 171 | list.parallelStream().mapToDouble(Medicion::getTemperatura).average() 172 | .ifPresent(x -> es.getTemperatura().setAverageValue(x)); 173 | 174 | // CO2 175 | list.parallelStream().max(Comparator.comparingDouble(Medicion::getCO)) 176 | .ifPresent(max -> { 177 | es.getCO().setMaxValue(max.getCO()); 178 | es.getCO().setMaxDate(max.getFecha()); 179 | }); 180 | list.parallelStream().min(Comparator.comparingDouble(Medicion::getCO)) 181 | .ifPresent(min -> { 182 | es.getCO().setMinValue(min.getCO()); 183 | es.getCO().setMinDate(min.getFecha()); 184 | }); 185 | list.parallelStream().mapToDouble(Medicion::getCO).average() 186 | .ifPresent(x -> es.getCO().setAverageValue(x)); 187 | 188 | // Ozone 189 | list.parallelStream().max(Comparator.comparingDouble(Medicion::getOzone)) 190 | .ifPresent(max -> { 191 | es.getOzone().setMaxValue(max.getOzone()); 192 | es.getOzone().setMaxDate(max.getFecha()); 193 | }); 194 | list.parallelStream().min(Comparator.comparingDouble(Medicion::getOzone)) 195 | .ifPresent(min -> { 196 | es.getOzone().setMinValue(min.getOzone()); 197 | es.getOzone().setMinDate(min.getFecha()); 198 | }); 199 | list.parallelStream().mapToDouble(Medicion::getOzone).average() 200 | .ifPresent(x -> es.getOzone().setAverageValue(x)); 201 | 202 | return es; 203 | } 204 | 205 | private void printXML() { 206 | //informe.getEstadisticas().forEach(System.out::println); 207 | // Cargamos JAXB 208 | JAXBService jaxb = JAXBService.getInstance(); 209 | try { 210 | jaxb.printXML(informe); 211 | } catch (JAXBException e) { 212 | e.printStackTrace(); 213 | } 214 | } 215 | 216 | private void saveXML(String dir) { 217 | String fileName = dir + "/" + "informe.xml"; 218 | JAXBService jaxb = JAXBService.getInstance(); 219 | try { 220 | jaxb.writeXMLFile(fileName, informe); 221 | } catch (JAXBException | IOException | URISyntaxException e) { 222 | e.printStackTrace(); 223 | } 224 | } 225 | 226 | private void saveXSD(String dir) { 227 | String fileName = dir + "/" + "esquemas.xsd"; 228 | JAXBService jaxb = JAXBService.getInstance(); 229 | try { 230 | jaxb.writeXSDFile(fileName); 231 | } catch (JAXBException | IOException | URISyntaxException e) { 232 | e.printStackTrace(); 233 | } 234 | } 235 | 236 | public void saveData() { 237 | printXML(); 238 | FileResources resources = FileResources.getInstance(); 239 | final String dir = "/res"; 240 | try { 241 | // Creamos el directorio si no existe 242 | resources.makeDir(dir); 243 | // Borramos todos los ficheros 244 | resources.deleteFiles(dir); 245 | // salvamos el informe 246 | saveXML(dir); 247 | 248 | // Salvamos el XSD 249 | saveXSD(dir); 250 | 251 | // Vamos con el xPATH 252 | XPATHService xpath = XPATHService.getInstance(JAXBService.getInstance().toDOM(informe)); 253 | 254 | List listNO2 = xpath.getInfo("NO2"); 255 | List listOzone = xpath.getInfo("Ozone"); 256 | 257 | saveMarkdown(dir, listNO2, listOzone); 258 | 259 | } catch (IOException | URISyntaxException | JAXBException | ParserConfigurationException e) { 260 | e.printStackTrace(); 261 | } 262 | // Lo primero que vamos a hacer es salvar el informe en nuestro directorio res03 263 | } 264 | 265 | private void saveMarkdown(String dir, List listNO2, List listOzone) throws IOException, URISyntaxException { 266 | String fileName = dir + "/" + "informe.md"; 267 | FileResources resources = FileResources.getInstance(); 268 | File file = resources.getPath(fileName); 269 | final PrintWriter f = new PrintWriter(new FileWriter(file, true)); 270 | try { 271 | f.println("# RESUMEN DE DATOS"); 272 | f.println("## NO2"); 273 | listNO2.forEach(x -> f.println("- " + x.toMarkDown())); 274 | f.println(""); 275 | f.println("##Ozone"); 276 | listOzone.forEach(x -> f.println("- " + x.toMarkDown())); 277 | } finally { 278 | try { 279 | f.close(); 280 | } catch (Exception e2) { 281 | e2.printStackTrace(); 282 | } 283 | } 284 | 285 | 286 | } 287 | } 288 | -------------------------------------------------------------------------------- /data/data03.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 116.0 8 | AirQualityObserved 9 | 43.449 10 | 22.9 11 | 12 | 13 | 0.1 14 | 2021-08-27T07:47:39Z 15 | 3047 16 | -3.8677 17 | 18 | 19 | 120.0 20 | http://datos.santander.es/api/datos/sensores_smart_mobile/3047.xml 21 | 22 | 23 | 115.0 24 | AirQualityObserved 25 | 43.4618 26 | 24.1 27 | 28 | 29 | 0.1 30 | 2021-08-27T07:47:34Z 31 | 3006 32 | -3.8126 33 | 34 | 35 | 3.0 36 | http://datos.santander.es/api/datos/sensores_smart_mobile/3006.xml 37 | 38 | 39 | 115.0 40 | AirQualityObserved 41 | 43.4602 42 | 27.0 43 | 44 | 45 | 0.1 46 | 2021-08-27T07:47:14Z 47 | 3011 48 | -3.85356 49 | 50 | 51 | 5.0 52 | http://datos.santander.es/api/datos/sensores_smart_mobile/3011.xml 53 | 54 | 55 | 54.0 56 | AirQualityObserved 57 | 43.448 58 | 24.9 59 | 60 | 61 | 0.2 62 | 2021-08-27T07:47:12Z 63 | 3058 64 | -3.86846 65 | 66 | 67 | 121.0 68 | http://datos.santander.es/api/datos/sensores_smart_mobile/3058.xml 69 | 70 | 71 | 110.0 72 | AirQualityObserved 73 | 43.4678 74 | 33.4 75 | 76 | 77 | 0.1 78 | 2021-08-27T07:47:00Z 79 | 3114 80 | -3.83473 81 | 82 | 83 | 118.0 84 | http://datos.santander.es/api/datos/sensores_smart_mobile/3114.xml 85 | 86 | 87 | 115.0 88 | AirQualityObserved 89 | 43.4655 90 | 23.9 91 | 92 | 93 | 0.1 94 | 2021-08-27T07:46:47Z 95 | 3078 96 | -3.79677 97 | 98 | 99 | 120.0 100 | http://datos.santander.es/api/datos/sensores_smart_mobile/3078.xml 101 | 102 | 103 | 114.0 104 | AirQualityObserved 105 | 43.4629 106 | 23.2 107 | 108 | 109 | 0.1 110 | 2021-08-27T07:46:41Z 111 | 3005 112 | -3.79301 113 | 114 | 115 | 11.0 116 | http://datos.santander.es/api/datos/sensores_smart_mobile/3005.xml 117 | 118 | 119 | 84.0 120 | AirQualityObserved 121 | 43.4482 122 | 24.2 123 | 124 | 125 | 0.3 126 | 2021-08-27T07:46:33Z 127 | 3001 128 | -3.86826 129 | 130 | 131 | 3.0 132 | http://datos.santander.es/api/datos/sensores_smart_mobile/3001.xml 133 | 134 | 135 | 115.0 136 | AirQualityObserved 137 | 43.461 138 | 26.8 139 | 140 | 141 | 0.1 142 | 2021-08-27T07:46:29Z 143 | 3018 144 | -3.84883 145 | 146 | 147 | 34.0 148 | http://datos.santander.es/api/datos/sensores_smart_mobile/3018.xml 149 | 150 | 151 | 110.0 152 | AirQualityObserved 153 | 43.4393 154 | 23.6 155 | 156 | 157 | 0.1 158 | 2021-08-27T07:46:27Z 159 | 3015 160 | -3.84471 161 | 162 | 163 | 120.0 164 | http://datos.santander.es/api/datos/sensores_smart_mobile/3015.xml 165 | 166 | 167 | 165.0 168 | AirQualityObserved 169 | 43.4582 170 | 31.9 171 | 172 | 173 | 0.0 174 | 2021-08-27T07:46:07Z 175 | 3196 176 | -3.84073 177 | 178 | 179 | 0.0 180 | http://datos.santander.es/api/datos/sensores_smart_mobile/3196.xml 181 | 182 | 183 | 107.0 184 | AirQualityObserved 185 | 43.1379 186 | 31.5 187 | 188 | 189 | 0.1 190 | 2021-08-27T07:46:00Z 191 | 3119 192 | -2.07384 193 | 194 | 195 | 5.0 196 | http://datos.santander.es/api/datos/sensores_smart_mobile/3119.xml 197 | 198 | 199 | 114.0 200 | AirQualityObserved 201 | 43.4615 202 | 24.8 203 | 204 | 205 | 0.1 206 | 2021-08-27T07:45:55Z 207 | 3077 208 | -3.80977 209 | 210 | 211 | 120.0 212 | http://datos.santander.es/api/datos/sensores_smart_mobile/3077.xml 213 | 214 | 215 | 91.0 216 | AirQualityObserved 217 | 43.469 218 | 21.9 219 | 220 | 221 | 0.1 222 | 2021-08-27T07:45:41Z 223 | 3008 224 | -3.77699 225 | 226 | 227 | 10.0 228 | http://datos.santander.es/api/datos/sensores_smart_mobile/3008.xml 229 | 230 | 231 | 115.0 232 | AirQualityObserved 233 | 43.4594 234 | 23.7 235 | 236 | 237 | 0.1 238 | 2021-08-27T07:45:38Z 239 | 3059 240 | -3.8109 241 | 242 | 243 | 119.0 244 | http://datos.santander.es/api/datos/sensores_smart_mobile/3059.xml 245 | 246 | 247 | 116.0 248 | AirQualityObserved 249 | 43.4631 250 | 24.3 251 | 252 | 253 | 0.1 254 | 2021-08-27T07:45:36Z 255 | 3044 256 | -3.79629 257 | 258 | 259 | 120.0 260 | http://datos.santander.es/api/datos/sensores_smart_mobile/3044.xml 261 | 262 | 263 | 115.0 264 | AirQualityObserved 265 | 43.4635 266 | 24.1 267 | 268 | 269 | 0.1 270 | 2021-08-27T07:45:23Z 271 | 3021 272 | -3.78825 273 | 274 | 275 | 118.0 276 | http://datos.santander.es/api/datos/sensores_smart_mobile/3021.xml 277 | 278 | 279 | 115.0 280 | AirQualityObserved 281 | 43.4739 282 | 24.1 283 | 284 | 285 | 0.1 286 | 2021-08-27T07:45:19Z 287 | 3022 288 | -3.78579 289 | 290 | 291 | 9.0 292 | http://datos.santander.es/api/datos/sensores_smart_mobile/3022.xml 293 | 294 | 295 | 108.0 296 | AirQualityObserved 297 | 43.4818 298 | 24.4 299 | 300 | 301 | 0.1 302 | 2021-08-27T07:45:01Z 303 | 3019 304 | -3.78823 305 | 306 | 307 | 111.0 308 | http://datos.santander.es/api/datos/sensores_smart_mobile/3019.xml 309 | 310 | 311 | 116.0 312 | AirQualityObserved 313 | 43.4731 314 | 24.6 315 | 316 | 317 | 1.6 318 | 2021-08-27T07:45:00Z 319 | 3103 320 | -3.80707 321 | 322 | 323 | 9.0 324 | http://datos.santander.es/api/datos/sensores_smart_mobile/3103.xml 325 | 326 | 327 | 115.0 328 | AirQualityObserved 329 | 43.4705 330 | 24.3 331 | 332 | 333 | 0.6 334 | 2021-08-27T07:45:00Z 335 | 3111 336 | -3.80025 337 | 338 | 339 | 3.0 340 | http://datos.santander.es/api/datos/sensores_smart_mobile/3111.xml 341 | 342 | 343 | 25.0 344 | AirQualityObserved 345 | 43.4488 346 | 25.1 347 | 348 | 349 | 0.1 350 | 2021-08-27T07:44:57Z 351 | 3032 352 | -3.86758 353 | 354 | 355 | 11.0 356 | http://datos.santander.es/api/datos/sensores_smart_mobile/3032.xml 357 | 358 | 359 | 115.0 360 | AirQualityObserved 361 | 43.458 362 | 23.7 363 | 364 | 365 | 0.1 366 | 2021-08-27T07:44:37Z 367 | 3055 368 | -3.85411 369 | 370 | 371 | 23.0 372 | http://datos.santander.es/api/datos/sensores_smart_mobile/3055.xml 373 | 374 | 375 | 115.0 376 | AirQualityObserved 377 | 43.4778 378 | 21.1 379 | 380 | 381 | 0.1 382 | 2021-08-27T07:44:27Z 383 | 3025 384 | -3.79128 385 | 386 | 387 | 13.0 388 | http://datos.santander.es/api/datos/sensores_smart_mobile/3025.xml 389 | 390 | 391 | 86.0 392 | AirQualityObserved 393 | 43.4682 394 | 26.5 395 | 396 | 397 | 0.1 398 | 2021-08-27T07:44:00Z 399 | 3115 400 | -3.80962 401 | 402 | 403 | 53.0 404 | http://datos.santander.es/api/datos/sensores_smart_mobile/3115.xml 405 | 406 | 407 | 115.0 408 | AirQualityObserved 409 | 43.4486 410 | 24.3 411 | 412 | 413 | 0.1 414 | 2021-08-27T07:43:36Z 415 | 3026 416 | -3.86787 417 | 418 | 419 | 8.0 420 | http://datos.santander.es/api/datos/sensores_smart_mobile/3026.xml 421 | 422 | 423 | 115.0 424 | AirQualityObserved 425 | 43.4614 426 | 24.9 427 | 428 | 429 | 0.1 430 | 2021-08-27T07:43:03Z 431 | 3054 432 | -3.80708 433 | 434 | 435 | 92.0 436 | http://datos.santander.es/api/datos/sensores_smart_mobile/3054.xml 437 | 438 | 439 | 60.0 440 | AirQualityObserved 441 | 43.4452 442 | 31.5 443 | 444 | 445 | 10.8 446 | 2021-08-27T07:43:00Z 447 | 3068 448 | -3.85358 449 | 450 | 451 | 57.0 452 | http://datos.santander.es/api/datos/sensores_smart_mobile/3068.xml 453 | 454 | 455 | 116.0 456 | AirQualityObserved 457 | 43.4399 458 | 21.2 459 | 460 | 461 | 0.3 462 | 2021-08-27T07:43:00Z 463 | 3125 464 | -3.89176 465 | 466 | 467 | 120.0 468 | http://datos.santander.es/api/datos/sensores_smart_mobile/3125.xml 469 | 470 | 471 | 114.0 472 | AirQualityObserved 473 | 43.457 474 | 24.5 475 | 476 | 477 | 0.1 478 | 2021-08-27T07:42:32Z 479 | 3056 480 | -3.83142 481 | 482 | 483 | 120.0 484 | http://datos.santander.es/api/datos/sensores_smart_mobile/3056.xml 485 | 486 | 487 | 81.0 488 | AirQualityObserved 489 | 43.4574 490 | 23.0 491 | 492 | 493 | 0.1 494 | 2021-08-27T07:42:24Z 495 | 3020 496 | -3.83009 497 | 498 | 499 | 7.0 500 | http://datos.santander.es/api/datos/sensores_smart_mobile/3020.xml 501 | 502 | 503 | 116.0 504 | AirQualityObserved 505 | 40.3721 506 | 40.2 507 | 508 | 509 | 0.1 510 | 2021-08-27T07:42:00Z 511 | 3107 512 | -3.7522 513 | 514 | 515 | 70.0 516 | http://datos.santander.es/api/datos/sensores_smart_mobile/3107.xml 517 | 518 | 519 | 82.0 520 | AirQualityObserved 521 | 41.4353 522 | 33.0 523 | 524 | 525 | 0.2 526 | 2021-08-27T07:42:00Z 527 | 3122 528 | 2.22745 529 | 530 | 531 | 3.0 532 | http://datos.santander.es/api/datos/sensores_smart_mobile/3122.xml 533 | 534 | 535 | 73.0 536 | AirQualityObserved 537 | 43.4491 538 | 35.2 539 | 540 | 541 | 0.2 542 | 2021-08-27T07:42:00Z 543 | 3102 544 | -3.87777 545 | 546 | 547 | 60.0 548 | http://datos.santander.es/api/datos/sensores_smart_mobile/3102.xml 549 | 550 | 551 | 52.0 552 | AirQualityObserved 553 | 43.4479 554 | 22.3 555 | 556 | 557 | 0.1 558 | 2021-08-27T07:41:57Z 559 | 3027 560 | -3.8685 561 | 562 | 563 | 6.0 564 | http://datos.santander.es/api/datos/sensores_smart_mobile/3027.xml 565 | 566 | 567 | 115.0 568 | AirQualityObserved 569 | 38.719 570 | 35.1 571 | 572 | 573 | 0.1 574 | 2021-08-16T12:18:00Z 575 | 3123 576 | -6.70898 577 | 578 | 579 | 119.0 580 | http://datos.santander.es/api/datos/sensores_smart_mobile/3123.xml 581 | 582 | 583 | 115.0 584 | AirQualityObserved 585 | 39.7201 586 | 37.0 587 | 588 | 589 | 30.6 590 | 2021-06-25T16:53:00Z 591 | 3109 592 | -3.29876 593 | 594 | 595 | 8.0 596 | http://datos.santander.es/api/datos/sensores_smart_mobile/3109.xml 597 | 598 | 599 | 115.0 600 | AirQualityObserved 601 | 43.4618 602 | 19.2 603 | 604 | 605 | 0.1 606 | 2021-05-06T16:00:53Z 607 | 3048 608 | -3.81288 609 | 610 | 611 | 51.0 612 | http://datos.santander.es/api/datos/sensores_smart_mobile/3048.xml 613 | 614 | 615 | 116.0 616 | AirQualityObserved 617 | 43.4484 618 | 14.3 619 | 620 | 621 | 0.2 622 | 2021-04-28T04:39:04Z 623 | 3057 624 | -3.86856 625 | 626 | 627 | 99.0 628 | http://datos.santander.es/api/datos/sensores_smart_mobile/3057.xml 629 | 630 | 631 | 116.0 632 | AirQualityObserved 633 | 43.47 634 | 19.8 635 | 636 | 637 | 0.1 638 | 2021-02-17T12:22:54Z 639 | 3052 640 | -3.82429 641 | 642 | 643 | 119.0 644 | http://datos.santander.es/api/datos/sensores_smart_mobile/3052.xml 645 | 646 | 647 | 301.0 648 | AirQualityObserved 649 | 43.4482 650 | 16.9 651 | 652 | 653 | 15.2 654 | 2021-02-08T04:30:24Z 655 | 3042 656 | -3.86801 657 | 658 | 659 | 110.0 660 | http://datos.santander.es/api/datos/sensores_smart_mobile/3042.xml 661 | 662 | 663 | 153.0 664 | AirQualityObserved 665 | 43.4588 666 | 14.9 667 | 668 | 669 | 96.0 670 | 2021-01-21T07:00:35Z 671 | 3010 672 | -3.82552 673 | 674 | 675 | 10.0 676 | http://datos.santander.es/api/datos/sensores_smart_mobile/3010.xml 677 | 678 | 679 | 115.0 680 | AirQualityObserved 681 | 43.4518 682 | 21.2 683 | 684 | 685 | 0.1 686 | 2020-10-28T07:33:45Z 687 | 3066 688 | -3.83215 689 | 690 | 691 | 120.0 692 | http://datos.santander.es/api/datos/sensores_smart_mobile/3066.xml 693 | 694 | 695 | 115.0 696 | AirQualityObserved 697 | 43.4485 698 | 15.4 699 | 700 | 701 | 0.2 702 | 2020-10-17T19:00:55Z 703 | 3045 704 | -3.86784 705 | 706 | 707 | 121.0 708 | http://datos.santander.es/api/datos/sensores_smart_mobile/3045.xml 709 | 710 | 711 | 0.0 712 | AirQualityObserved 713 | 43.42 714 | 32.3 715 | 716 | 717 | 0.0 718 | 2020-10-06T09:18:00Z 719 | 3155 720 | -3.84797 721 | 722 | 723 | 0.0 724 | http://datos.santander.es/api/datos/sensores_smart_mobile/3155.xml 725 | 726 | 727 | 114.0 728 | AirQualityObserved 729 | 43.4482 730 | 16.8 731 | 732 | 733 | 0.1 734 | 2020-09-24T04:54:58Z 735 | 3014 736 | -3.86758 737 | 738 | 739 | 120.0 740 | http://datos.santander.es/api/datos/sensores_smart_mobile/3014.xml 741 | 742 | 743 | 114.0 744 | AirQualityObserved 745 | 43.4483 746 | 25.6 747 | 748 | 749 | 0.1 750 | 2020-08-19T05:13:40Z 751 | 3017 752 | -3.8685 753 | 754 | 755 | 99.0 756 | http://datos.santander.es/api/datos/sensores_smart_mobile/3017.xml 757 | 758 | 759 | 83.0 760 | AirQualityObserved 761 | 43.0224 762 | 22.0 763 | 764 | 765 | 2.5 766 | 2020-08-09T01:43:00Z 767 | 3152 768 | -4.51277 769 | 770 | 771 | 120.0 772 | http://datos.santander.es/api/datos/sensores_smart_mobile/3152.xml 773 | 774 | 775 | 115.0 776 | AirQualityObserved 777 | 43.4481 778 | 23.8 779 | 780 | 781 | 0.1 782 | 2020-08-07T08:41:28Z 783 | 3035 784 | -3.86819 785 | 786 | 787 | 109.0 788 | http://datos.santander.es/api/datos/sensores_smart_mobile/3035.xml 789 | 790 | 791 | 70.0 792 | AirQualityObserved 793 | 43.4648 794 | 19.1 795 | 796 | 797 | 0.3 798 | 2020-06-09T05:05:00Z 799 | 3161 800 | -3.82435 801 | 802 | 803 | 38.0 804 | http://datos.santander.es/api/datos/sensores_smart_mobile/3161.xml 805 | 806 | 807 | 115.0 808 | AirQualityObserved 809 | 43.4552 810 | 23.4 811 | 812 | 813 | 0.3 814 | 2020-02-06T11:12:27Z 815 | 3038 816 | -3.83439 817 | 818 | 819 | 5.0 820 | http://datos.santander.es/api/datos/sensores_smart_mobile/3038.xml 821 | 822 | 823 | 115.0 824 | AirQualityObserved 825 | 43.4622 826 | 35.6 827 | 828 | 829 | 0.1 830 | 2019-10-31T20:37:43Z 831 | 3173 832 | -3.8008 833 | 834 | 835 | 46.0 836 | http://datos.santander.es/api/datos/sensores_smart_mobile/3173.xml 837 | 838 | 839 | 115.0 840 | AirQualityObserved 841 | 43.4517 842 | 22.6 843 | 844 | 845 | 0.1 846 | 2019-10-31T20:36:22Z 847 | 3067 848 | -3.83224 849 | 850 | 851 | 120.0 852 | http://datos.santander.es/api/datos/sensores_smart_mobile/3067.xml 853 | 854 | 855 | 83.0 856 | AirQualityObserved 857 | 39.2154 858 | 10.5 859 | 860 | 861 | 0.3 862 | 2019-10-27T05:49:20Z 863 | 3105 864 | -4.7882 865 | 866 | 867 | 19.0 868 | http://datos.santander.es/api/datos/sensores_smart_mobile/3105.xml 869 | 870 | 871 | 115.0 872 | AirQualityObserved 873 | 43.4554 874 | 28.0 875 | 876 | 877 | 0.1 878 | 2019-08-27T07:16:06Z 879 | 3062 880 | -3.83428 881 | 882 | 883 | 109.0 884 | http://datos.santander.es/api/datos/sensores_smart_mobile/3062.xml 885 | 886 | 887 | 116.0 888 | AirQualityObserved 889 | 43.4615 890 | 14.6 891 | 892 | 893 | 0.1 894 | 2019-03-22T19:11:54Z 895 | 3007 896 | -3.80975 897 | 898 | 899 | 12.0 900 | http://datos.santander.es/api/datos/sensores_smart_mobile/3007.xml 901 | 902 | 903 | 82.0 904 | AirQualityObserved 905 | 43.4621 906 | 32.5 907 | 908 | 909 | 0.4 910 | 2019-02-28T09:33:15Z 911 | 3169 912 | -3.83911 913 | 914 | 915 | 10.0 916 | http://datos.santander.es/api/datos/sensores_smart_mobile/3169.xml 917 | 918 | 919 | 116.0 920 | AirQualityObserved 921 | 43.4554 922 | 11.0 923 | 924 | 925 | 0.1 926 | 2019-02-07T07:56:38Z 927 | 3060 928 | -3.83431 929 | 930 | 931 | 67.0 932 | http://datos.santander.es/api/datos/sensores_smart_mobile/3060.xml 933 | 934 | 935 | 116.0 936 | AirQualityObserved 937 | 43.452 938 | 19.2 939 | 940 | 941 | 0.1 942 | 2019-02-05T09:57:31Z 943 | 3072 944 | -3.83223 945 | 946 | 947 | 120.0 948 | http://datos.santander.es/api/datos/sensores_smart_mobile/3072.xml 949 | 950 | 951 | 114.0 952 | AirQualityObserved 953 | 43.4643 954 | 5.7 955 | 956 | 957 | 18.8 958 | 2019-01-28T05:41:06Z 959 | 3120 960 | -3.83531 961 | 962 | 963 | 16.0 964 | http://datos.santander.es/api/datos/sensores_smart_mobile/3120.xml 965 | 966 | 967 | 113.0 968 | AirQualityObserved 969 | 43.4554 970 | 6.3 971 | 972 | 973 | 0.2 974 | 2019-01-23T22:32:13Z 975 | 3049 976 | -3.83363 977 | 978 | 979 | 104.0 980 | http://datos.santander.es/api/datos/sensores_smart_mobile/3049.xml 981 | 982 | 983 | 79.0 984 | AirQualityObserved 985 | 43.4646 986 | 18.7 987 | 988 | 989 | 0.4 990 | 2018-10-21T08:29:45Z 991 | 3108 992 | -3.8356 993 | 994 | 995 | 3.0 996 | http://datos.santander.es/api/datos/sensores_smart_mobile/3108.xml 997 | 998 | 999 | 212.0 1000 | AirQualityObserved 1001 | 43.4673 1002 | 23.5 1003 | 1004 | 1005 | 12.7 1006 | 2018-09-12T18:26:33Z 1007 | 3081 1008 | -3.80611 1009 | 1010 | 1011 | 592.0 1012 | http://datos.santander.es/api/datos/sensores_smart_mobile/3081.xml 1013 | 1014 | 1015 | 84.0 1016 | AirQualityObserved 1017 | 43.4319 1018 | 22.6 1019 | 1020 | 1021 | 0.1 1022 | 2018-09-06T17:58:54Z 1023 | 3177 1024 | -3.83113 1025 | 1026 | 1027 | 62.0 1028 | http://datos.santander.es/api/datos/sensores_smart_mobile/3177.xml 1029 | 1030 | 1031 | 32.0 1032 | AirQualityObserved 1033 | 43.454 1034 | 23.7 1035 | 1036 | 1037 | 0.1 1038 | 2018-07-28T08:54:38Z 1039 | 3166 1040 | -3.86473 1041 | 1042 | 1043 | 8.0 1044 | http://datos.santander.es/api/datos/sensores_smart_mobile/3166.xml 1045 | 1046 | 1047 | 42.0 1048 | AirQualityObserved 1049 | 43.4649 1050 | 17.7 1051 | 1052 | 1053 | 0.1 1054 | 2018-07-16T06:35:55Z 1055 | 3167 1056 | -3.82449 1057 | 1058 | 1059 | 32.0 1060 | http://datos.santander.es/api/datos/sensores_smart_mobile/3167.xml 1061 | 1062 | 1063 | 85.0 1064 | AirQualityObserved 1065 | 43.4555 1066 | 9.0 1067 | 1068 | 1069 | 0.3 1070 | 2018-02-03T06:36:14Z 1071 | 3080 1072 | -3.83413 1073 | 1074 | 1075 | 53.0 1076 | http://datos.santander.es/api/datos/sensores_smart_mobile/3080.xml 1077 | 1078 | 1079 | 60.0 1080 | AirQualityObserved 1081 | 43.4411 1082 | 12.2 1083 | 1084 | 1085 | 0.1 1086 | 2018-01-18T13:08:03Z 1087 | 3028 1088 | -3.8878 1089 | 1090 | 1091 | 105.0 1092 | http://datos.santander.es/api/datos/sensores_smart_mobile/3028.xml 1093 | 1094 | 1095 | 27.0 1096 | AirQualityObserved 1097 | 43.4409 1098 | 5.9 1099 | 1100 | 1101 | 0.5 1102 | 2018-01-18T11:34:58Z 1103 | 3033 1104 | -3.88782 1105 | 1106 | 1107 | 12.0 1108 | http://datos.santander.es/api/datos/sensores_smart_mobile/3033.xml 1109 | 1110 | 1111 | 115.0 1112 | AirQualityObserved 1113 | 43.4619 1114 | 30.2 1115 | 1116 | 1117 | 0.1 1118 | 2017-10-30T07:30:07Z 1119 | 3170 1120 | -3.83923 1121 | 1122 | 1123 | 42.0 1124 | http://datos.santander.es/api/datos/sensores_smart_mobile/3170.xml 1125 | 1126 | 1127 | 800.0 1128 | AirQualityObserved 1129 | 43.4681 1130 | 0.0 1131 | 1132 | 1133 | 99.9 1134 | 2017-10-19T11:21:28Z 1135 | 3003 1136 | -3.7877 1137 | 1138 | 1139 | 999.0 1140 | http://datos.santander.es/api/datos/sensores_smart_mobile/3003.xml 1141 | 1142 | 1143 | 999.0 1144 | AirQualityObserved 1145 | 43.4785 1146 | 0.0 1147 | 1148 | 1149 | 99.9 1150 | 2017-10-19T11:21:28Z 1151 | 3070 1152 | -3.80134 1153 | 1154 | 1155 | 999.0 1156 | http://datos.santander.es/api/datos/sensores_smart_mobile/3070.xml 1157 | 1158 | 1159 | 999.0 1160 | AirQualityObserved 1161 | 43.4555 1162 | 0.0 1163 | 1164 | 1165 | 99.9 1166 | 2017-10-19T11:21:28Z 1167 | 3004 1168 | -3.83401 1169 | 1170 | 1171 | 999.0 1172 | http://datos.santander.es/api/datos/sensores_smart_mobile/3004.xml 1173 | 1174 | 1175 | 999.0 1176 | AirQualityObserved 1177 | 43.4554 1178 | 0.0 1179 | 1180 | 1181 | 99.9 1182 | 2017-10-19T11:21:12Z 1183 | 3029 1184 | -3.83427 1185 | 1186 | 1187 | 999.0 1188 | http://datos.santander.es/api/datos/sensores_smart_mobile/3029.xml 1189 | 1190 | 1191 | 999.0 1192 | AirQualityObserved 1193 | 43.4562 1194 | 0.0 1195 | 1196 | 1197 | 99.9 1198 | 2017-10-19T11:21:12Z 1199 | 3041 1200 | -3.83317 1201 | 1202 | 1203 | 999.0 1204 | http://datos.santander.es/api/datos/sensores_smart_mobile/3041.xml 1205 | 1206 | 1207 | 999.0 1208 | AirQualityObserved 1209 | 43.4556 1210 | 0.0 1211 | 1212 | 1213 | 99.9 1214 | 2017-10-19T11:20:31Z 1215 | 3013 1216 | -3.83373 1217 | 1218 | 1219 | 999.0 1220 | http://datos.santander.es/api/datos/sensores_smart_mobile/3013.xml 1221 | 1222 | 1223 | 999.0 1224 | AirQualityObserved 1225 | 43.4627 1226 | 0.0 1227 | 1228 | 1229 | 99.9 1230 | 2017-10-19T11:20:01Z 1231 | 3075 1232 | -3.82352 1233 | 1234 | 1235 | 999.0 1236 | http://datos.santander.es/api/datos/sensores_smart_mobile/3075.xml 1237 | 1238 | 1239 | 999.0 1240 | AirQualityObserved 1241 | 43.4556 1242 | 0.0 1243 | 1244 | 1245 | 99.9 1246 | 2017-10-19T11:20:01Z 1247 | 3071 1248 | -3.83416 1249 | 1250 | 1251 | 999.0 1252 | http://datos.santander.es/api/datos/sensores_smart_mobile/3071.xml 1253 | 1254 | 1255 | 999.0 1256 | AirQualityObserved 1257 | 43.4556 1258 | 0.0 1259 | 1260 | 1261 | 99.9 1262 | 2017-10-19T11:19:51Z 1263 | 3040 1264 | -3.83366 1265 | 1266 | 1267 | 999.0 1268 | http://datos.santander.es/api/datos/sensores_smart_mobile/3040.xml 1269 | 1270 | 1271 | 999.0 1272 | AirQualityObserved 1273 | 43.4685 1274 | 0.0 1275 | 1276 | 1277 | 99.9 1278 | 2017-10-19T11:19:45Z 1279 | 3092 1280 | -3.79757 1281 | 1282 | 1283 | 999.0 1284 | http://datos.santander.es/api/datos/sensores_smart_mobile/3092.xml 1285 | 1286 | 1287 | 999.0 1288 | AirQualityObserved 1289 | 43.4605 1290 | 0.0 1291 | 1292 | 1293 | 99.9 1294 | 2017-10-19T11:18:55Z 1295 | 3012 1296 | -3.82585 1297 | 1298 | 1299 | 999.0 1300 | http://datos.santander.es/api/datos/sensores_smart_mobile/3012.xml 1301 | 1302 | 1303 | 999.0 1304 | AirQualityObserved 1305 | 43.4586 1306 | 0.0 1307 | 1308 | 1309 | 99.9 1310 | 2017-10-19T11:18:14Z 1311 | 3043 1312 | -3.85141 1313 | 1314 | 1315 | 999.0 1316 | http://datos.santander.es/api/datos/sensores_smart_mobile/3043.xml 1317 | 1318 | 1319 | 999.0 1320 | AirQualityObserved 1321 | 43.4238 1322 | 200.0 1323 | 1324 | 1325 | 99.9 1326 | 2017-10-19T10:21:50Z 1327 | 3172 1328 | -3.85676 1329 | 1330 | 1331 | 999.0 1332 | http://datos.santander.es/api/datos/sensores_smart_mobile/3172.xml 1333 | 1334 | 1335 | 999.0 1336 | AirQualityObserved 1337 | 43.4677 1338 | 200.0 1339 | 1340 | 1341 | 99.9 1342 | 2017-10-16T01:46:09Z 1343 | 3117 1344 | -3.83619 1345 | 1346 | 1347 | 999.0 1348 | http://datos.santander.es/api/datos/sensores_smart_mobile/3117.xml 1349 | 1350 | 1351 | -------------------------------------------------------------------------------- /src/main/resources/data/data03.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 116.0 8 | AirQualityObserved 9 | 43.449 10 | 22.9 11 | 12 | 13 | 0.1 14 | 2021-08-27T07:47:39Z 15 | 3047 16 | -3.8677 17 | 18 | 19 | 120.0 20 | http://datos.santander.es/api/datos/sensores_smart_mobile/3047.xml 21 | 22 | 23 | 115.0 24 | AirQualityObserved 25 | 43.4618 26 | 24.1 27 | 28 | 29 | 0.1 30 | 2021-08-27T07:47:34Z 31 | 3006 32 | -3.8126 33 | 34 | 35 | 3.0 36 | http://datos.santander.es/api/datos/sensores_smart_mobile/3006.xml 37 | 38 | 39 | 115.0 40 | AirQualityObserved 41 | 43.4602 42 | 27.0 43 | 44 | 45 | 0.1 46 | 2021-08-27T07:47:14Z 47 | 3011 48 | -3.85356 49 | 50 | 51 | 5.0 52 | http://datos.santander.es/api/datos/sensores_smart_mobile/3011.xml 53 | 54 | 55 | 54.0 56 | AirQualityObserved 57 | 43.448 58 | 24.9 59 | 60 | 61 | 0.2 62 | 2021-08-27T07:47:12Z 63 | 3058 64 | -3.86846 65 | 66 | 67 | 121.0 68 | http://datos.santander.es/api/datos/sensores_smart_mobile/3058.xml 69 | 70 | 71 | 110.0 72 | AirQualityObserved 73 | 43.4678 74 | 33.4 75 | 76 | 77 | 0.1 78 | 2021-08-27T07:47:00Z 79 | 3114 80 | -3.83473 81 | 82 | 83 | 118.0 84 | http://datos.santander.es/api/datos/sensores_smart_mobile/3114.xml 85 | 86 | 87 | 115.0 88 | AirQualityObserved 89 | 43.4655 90 | 23.9 91 | 92 | 93 | 0.1 94 | 2021-08-27T07:46:47Z 95 | 3078 96 | -3.79677 97 | 98 | 99 | 120.0 100 | http://datos.santander.es/api/datos/sensores_smart_mobile/3078.xml 101 | 102 | 103 | 114.0 104 | AirQualityObserved 105 | 43.4629 106 | 23.2 107 | 108 | 109 | 0.1 110 | 2021-08-27T07:46:41Z 111 | 3005 112 | -3.79301 113 | 114 | 115 | 11.0 116 | http://datos.santander.es/api/datos/sensores_smart_mobile/3005.xml 117 | 118 | 119 | 84.0 120 | AirQualityObserved 121 | 43.4482 122 | 24.2 123 | 124 | 125 | 0.3 126 | 2021-08-27T07:46:33Z 127 | 3001 128 | -3.86826 129 | 130 | 131 | 3.0 132 | http://datos.santander.es/api/datos/sensores_smart_mobile/3001.xml 133 | 134 | 135 | 115.0 136 | AirQualityObserved 137 | 43.461 138 | 26.8 139 | 140 | 141 | 0.1 142 | 2021-08-27T07:46:29Z 143 | 3018 144 | -3.84883 145 | 146 | 147 | 34.0 148 | http://datos.santander.es/api/datos/sensores_smart_mobile/3018.xml 149 | 150 | 151 | 110.0 152 | AirQualityObserved 153 | 43.4393 154 | 23.6 155 | 156 | 157 | 0.1 158 | 2021-08-27T07:46:27Z 159 | 3015 160 | -3.84471 161 | 162 | 163 | 120.0 164 | http://datos.santander.es/api/datos/sensores_smart_mobile/3015.xml 165 | 166 | 167 | 165.0 168 | AirQualityObserved 169 | 43.4582 170 | 31.9 171 | 172 | 173 | 0.0 174 | 2021-08-27T07:46:07Z 175 | 3196 176 | -3.84073 177 | 178 | 179 | 0.0 180 | http://datos.santander.es/api/datos/sensores_smart_mobile/3196.xml 181 | 182 | 183 | 107.0 184 | AirQualityObserved 185 | 43.1379 186 | 31.5 187 | 188 | 189 | 0.1 190 | 2021-08-27T07:46:00Z 191 | 3119 192 | -2.07384 193 | 194 | 195 | 5.0 196 | http://datos.santander.es/api/datos/sensores_smart_mobile/3119.xml 197 | 198 | 199 | 114.0 200 | AirQualityObserved 201 | 43.4615 202 | 24.8 203 | 204 | 205 | 0.1 206 | 2021-08-27T07:45:55Z 207 | 3077 208 | -3.80977 209 | 210 | 211 | 120.0 212 | http://datos.santander.es/api/datos/sensores_smart_mobile/3077.xml 213 | 214 | 215 | 91.0 216 | AirQualityObserved 217 | 43.469 218 | 21.9 219 | 220 | 221 | 0.1 222 | 2021-08-27T07:45:41Z 223 | 3008 224 | -3.77699 225 | 226 | 227 | 10.0 228 | http://datos.santander.es/api/datos/sensores_smart_mobile/3008.xml 229 | 230 | 231 | 115.0 232 | AirQualityObserved 233 | 43.4594 234 | 23.7 235 | 236 | 237 | 0.1 238 | 2021-08-27T07:45:38Z 239 | 3059 240 | -3.8109 241 | 242 | 243 | 119.0 244 | http://datos.santander.es/api/datos/sensores_smart_mobile/3059.xml 245 | 246 | 247 | 116.0 248 | AirQualityObserved 249 | 43.4631 250 | 24.3 251 | 252 | 253 | 0.1 254 | 2021-08-27T07:45:36Z 255 | 3044 256 | -3.79629 257 | 258 | 259 | 120.0 260 | http://datos.santander.es/api/datos/sensores_smart_mobile/3044.xml 261 | 262 | 263 | 115.0 264 | AirQualityObserved 265 | 43.4635 266 | 24.1 267 | 268 | 269 | 0.1 270 | 2021-08-27T07:45:23Z 271 | 3021 272 | -3.78825 273 | 274 | 275 | 118.0 276 | http://datos.santander.es/api/datos/sensores_smart_mobile/3021.xml 277 | 278 | 279 | 115.0 280 | AirQualityObserved 281 | 43.4739 282 | 24.1 283 | 284 | 285 | 0.1 286 | 2021-08-27T07:45:19Z 287 | 3022 288 | -3.78579 289 | 290 | 291 | 9.0 292 | http://datos.santander.es/api/datos/sensores_smart_mobile/3022.xml 293 | 294 | 295 | 108.0 296 | AirQualityObserved 297 | 43.4818 298 | 24.4 299 | 300 | 301 | 0.1 302 | 2021-08-27T07:45:01Z 303 | 3019 304 | -3.78823 305 | 306 | 307 | 111.0 308 | http://datos.santander.es/api/datos/sensores_smart_mobile/3019.xml 309 | 310 | 311 | 116.0 312 | AirQualityObserved 313 | 43.4731 314 | 24.6 315 | 316 | 317 | 1.6 318 | 2021-08-27T07:45:00Z 319 | 3103 320 | -3.80707 321 | 322 | 323 | 9.0 324 | http://datos.santander.es/api/datos/sensores_smart_mobile/3103.xml 325 | 326 | 327 | 115.0 328 | AirQualityObserved 329 | 43.4705 330 | 24.3 331 | 332 | 333 | 0.6 334 | 2021-08-27T07:45:00Z 335 | 3111 336 | -3.80025 337 | 338 | 339 | 3.0 340 | http://datos.santander.es/api/datos/sensores_smart_mobile/3111.xml 341 | 342 | 343 | 25.0 344 | AirQualityObserved 345 | 43.4488 346 | 25.1 347 | 348 | 349 | 0.1 350 | 2021-08-27T07:44:57Z 351 | 3032 352 | -3.86758 353 | 354 | 355 | 11.0 356 | http://datos.santander.es/api/datos/sensores_smart_mobile/3032.xml 357 | 358 | 359 | 115.0 360 | AirQualityObserved 361 | 43.458 362 | 23.7 363 | 364 | 365 | 0.1 366 | 2021-08-27T07:44:37Z 367 | 3055 368 | -3.85411 369 | 370 | 371 | 23.0 372 | http://datos.santander.es/api/datos/sensores_smart_mobile/3055.xml 373 | 374 | 375 | 115.0 376 | AirQualityObserved 377 | 43.4778 378 | 21.1 379 | 380 | 381 | 0.1 382 | 2021-08-27T07:44:27Z 383 | 3025 384 | -3.79128 385 | 386 | 387 | 13.0 388 | http://datos.santander.es/api/datos/sensores_smart_mobile/3025.xml 389 | 390 | 391 | 86.0 392 | AirQualityObserved 393 | 43.4682 394 | 26.5 395 | 396 | 397 | 0.1 398 | 2021-08-27T07:44:00Z 399 | 3115 400 | -3.80962 401 | 402 | 403 | 53.0 404 | http://datos.santander.es/api/datos/sensores_smart_mobile/3115.xml 405 | 406 | 407 | 115.0 408 | AirQualityObserved 409 | 43.4486 410 | 24.3 411 | 412 | 413 | 0.1 414 | 2021-08-27T07:43:36Z 415 | 3026 416 | -3.86787 417 | 418 | 419 | 8.0 420 | http://datos.santander.es/api/datos/sensores_smart_mobile/3026.xml 421 | 422 | 423 | 115.0 424 | AirQualityObserved 425 | 43.4614 426 | 24.9 427 | 428 | 429 | 0.1 430 | 2021-08-27T07:43:03Z 431 | 3054 432 | -3.80708 433 | 434 | 435 | 92.0 436 | http://datos.santander.es/api/datos/sensores_smart_mobile/3054.xml 437 | 438 | 439 | 60.0 440 | AirQualityObserved 441 | 43.4452 442 | 31.5 443 | 444 | 445 | 10.8 446 | 2021-08-27T07:43:00Z 447 | 3068 448 | -3.85358 449 | 450 | 451 | 57.0 452 | http://datos.santander.es/api/datos/sensores_smart_mobile/3068.xml 453 | 454 | 455 | 116.0 456 | AirQualityObserved 457 | 43.4399 458 | 21.2 459 | 460 | 461 | 0.3 462 | 2021-08-27T07:43:00Z 463 | 3125 464 | -3.89176 465 | 466 | 467 | 120.0 468 | http://datos.santander.es/api/datos/sensores_smart_mobile/3125.xml 469 | 470 | 471 | 114.0 472 | AirQualityObserved 473 | 43.457 474 | 24.5 475 | 476 | 477 | 0.1 478 | 2021-08-27T07:42:32Z 479 | 3056 480 | -3.83142 481 | 482 | 483 | 120.0 484 | http://datos.santander.es/api/datos/sensores_smart_mobile/3056.xml 485 | 486 | 487 | 81.0 488 | AirQualityObserved 489 | 43.4574 490 | 23.0 491 | 492 | 493 | 0.1 494 | 2021-08-27T07:42:24Z 495 | 3020 496 | -3.83009 497 | 498 | 499 | 7.0 500 | http://datos.santander.es/api/datos/sensores_smart_mobile/3020.xml 501 | 502 | 503 | 116.0 504 | AirQualityObserved 505 | 40.3721 506 | 40.2 507 | 508 | 509 | 0.1 510 | 2021-08-27T07:42:00Z 511 | 3107 512 | -3.7522 513 | 514 | 515 | 70.0 516 | http://datos.santander.es/api/datos/sensores_smart_mobile/3107.xml 517 | 518 | 519 | 82.0 520 | AirQualityObserved 521 | 41.4353 522 | 33.0 523 | 524 | 525 | 0.2 526 | 2021-08-27T07:42:00Z 527 | 3122 528 | 2.22745 529 | 530 | 531 | 3.0 532 | http://datos.santander.es/api/datos/sensores_smart_mobile/3122.xml 533 | 534 | 535 | 73.0 536 | AirQualityObserved 537 | 43.4491 538 | 35.2 539 | 540 | 541 | 0.2 542 | 2021-08-27T07:42:00Z 543 | 3102 544 | -3.87777 545 | 546 | 547 | 60.0 548 | http://datos.santander.es/api/datos/sensores_smart_mobile/3102.xml 549 | 550 | 551 | 52.0 552 | AirQualityObserved 553 | 43.4479 554 | 22.3 555 | 556 | 557 | 0.1 558 | 2021-08-27T07:41:57Z 559 | 3027 560 | -3.8685 561 | 562 | 563 | 6.0 564 | http://datos.santander.es/api/datos/sensores_smart_mobile/3027.xml 565 | 566 | 567 | 115.0 568 | AirQualityObserved 569 | 38.719 570 | 35.1 571 | 572 | 573 | 0.1 574 | 2021-08-16T12:18:00Z 575 | 3123 576 | -6.70898 577 | 578 | 579 | 119.0 580 | http://datos.santander.es/api/datos/sensores_smart_mobile/3123.xml 581 | 582 | 583 | 115.0 584 | AirQualityObserved 585 | 39.7201 586 | 37.0 587 | 588 | 589 | 30.6 590 | 2021-06-25T16:53:00Z 591 | 3109 592 | -3.29876 593 | 594 | 595 | 8.0 596 | http://datos.santander.es/api/datos/sensores_smart_mobile/3109.xml 597 | 598 | 599 | 115.0 600 | AirQualityObserved 601 | 43.4618 602 | 19.2 603 | 604 | 605 | 0.1 606 | 2021-05-06T16:00:53Z 607 | 3048 608 | -3.81288 609 | 610 | 611 | 51.0 612 | http://datos.santander.es/api/datos/sensores_smart_mobile/3048.xml 613 | 614 | 615 | 116.0 616 | AirQualityObserved 617 | 43.4484 618 | 14.3 619 | 620 | 621 | 0.2 622 | 2021-04-28T04:39:04Z 623 | 3057 624 | -3.86856 625 | 626 | 627 | 99.0 628 | http://datos.santander.es/api/datos/sensores_smart_mobile/3057.xml 629 | 630 | 631 | 116.0 632 | AirQualityObserved 633 | 43.47 634 | 19.8 635 | 636 | 637 | 0.1 638 | 2021-02-17T12:22:54Z 639 | 3052 640 | -3.82429 641 | 642 | 643 | 119.0 644 | http://datos.santander.es/api/datos/sensores_smart_mobile/3052.xml 645 | 646 | 647 | 301.0 648 | AirQualityObserved 649 | 43.4482 650 | 16.9 651 | 652 | 653 | 15.2 654 | 2021-02-08T04:30:24Z 655 | 3042 656 | -3.86801 657 | 658 | 659 | 110.0 660 | http://datos.santander.es/api/datos/sensores_smart_mobile/3042.xml 661 | 662 | 663 | 153.0 664 | AirQualityObserved 665 | 43.4588 666 | 14.9 667 | 668 | 669 | 96.0 670 | 2021-01-21T07:00:35Z 671 | 3010 672 | -3.82552 673 | 674 | 675 | 10.0 676 | http://datos.santander.es/api/datos/sensores_smart_mobile/3010.xml 677 | 678 | 679 | 115.0 680 | AirQualityObserved 681 | 43.4518 682 | 21.2 683 | 684 | 685 | 0.1 686 | 2020-10-28T07:33:45Z 687 | 3066 688 | -3.83215 689 | 690 | 691 | 120.0 692 | http://datos.santander.es/api/datos/sensores_smart_mobile/3066.xml 693 | 694 | 695 | 115.0 696 | AirQualityObserved 697 | 43.4485 698 | 15.4 699 | 700 | 701 | 0.2 702 | 2020-10-17T19:00:55Z 703 | 3045 704 | -3.86784 705 | 706 | 707 | 121.0 708 | http://datos.santander.es/api/datos/sensores_smart_mobile/3045.xml 709 | 710 | 711 | 0.0 712 | AirQualityObserved 713 | 43.42 714 | 32.3 715 | 716 | 717 | 0.0 718 | 2020-10-06T09:18:00Z 719 | 3155 720 | -3.84797 721 | 722 | 723 | 0.0 724 | http://datos.santander.es/api/datos/sensores_smart_mobile/3155.xml 725 | 726 | 727 | 114.0 728 | AirQualityObserved 729 | 43.4482 730 | 16.8 731 | 732 | 733 | 0.1 734 | 2020-09-24T04:54:58Z 735 | 3014 736 | -3.86758 737 | 738 | 739 | 120.0 740 | http://datos.santander.es/api/datos/sensores_smart_mobile/3014.xml 741 | 742 | 743 | 114.0 744 | AirQualityObserved 745 | 43.4483 746 | 25.6 747 | 748 | 749 | 0.1 750 | 2020-08-19T05:13:40Z 751 | 3017 752 | -3.8685 753 | 754 | 755 | 99.0 756 | http://datos.santander.es/api/datos/sensores_smart_mobile/3017.xml 757 | 758 | 759 | 83.0 760 | AirQualityObserved 761 | 43.0224 762 | 22.0 763 | 764 | 765 | 2.5 766 | 2020-08-09T01:43:00Z 767 | 3152 768 | -4.51277 769 | 770 | 771 | 120.0 772 | http://datos.santander.es/api/datos/sensores_smart_mobile/3152.xml 773 | 774 | 775 | 115.0 776 | AirQualityObserved 777 | 43.4481 778 | 23.8 779 | 780 | 781 | 0.1 782 | 2020-08-07T08:41:28Z 783 | 3035 784 | -3.86819 785 | 786 | 787 | 109.0 788 | http://datos.santander.es/api/datos/sensores_smart_mobile/3035.xml 789 | 790 | 791 | 70.0 792 | AirQualityObserved 793 | 43.4648 794 | 19.1 795 | 796 | 797 | 0.3 798 | 2020-06-09T05:05:00Z 799 | 3161 800 | -3.82435 801 | 802 | 803 | 38.0 804 | http://datos.santander.es/api/datos/sensores_smart_mobile/3161.xml 805 | 806 | 807 | 115.0 808 | AirQualityObserved 809 | 43.4552 810 | 23.4 811 | 812 | 813 | 0.3 814 | 2020-02-06T11:12:27Z 815 | 3038 816 | -3.83439 817 | 818 | 819 | 5.0 820 | http://datos.santander.es/api/datos/sensores_smart_mobile/3038.xml 821 | 822 | 823 | 115.0 824 | AirQualityObserved 825 | 43.4622 826 | 35.6 827 | 828 | 829 | 0.1 830 | 2019-10-31T20:37:43Z 831 | 3173 832 | -3.8008 833 | 834 | 835 | 46.0 836 | http://datos.santander.es/api/datos/sensores_smart_mobile/3173.xml 837 | 838 | 839 | 115.0 840 | AirQualityObserved 841 | 43.4517 842 | 22.6 843 | 844 | 845 | 0.1 846 | 2019-10-31T20:36:22Z 847 | 3067 848 | -3.83224 849 | 850 | 851 | 120.0 852 | http://datos.santander.es/api/datos/sensores_smart_mobile/3067.xml 853 | 854 | 855 | 83.0 856 | AirQualityObserved 857 | 39.2154 858 | 10.5 859 | 860 | 861 | 0.3 862 | 2019-10-27T05:49:20Z 863 | 3105 864 | -4.7882 865 | 866 | 867 | 19.0 868 | http://datos.santander.es/api/datos/sensores_smart_mobile/3105.xml 869 | 870 | 871 | 115.0 872 | AirQualityObserved 873 | 43.4554 874 | 28.0 875 | 876 | 877 | 0.1 878 | 2019-08-27T07:16:06Z 879 | 3062 880 | -3.83428 881 | 882 | 883 | 109.0 884 | http://datos.santander.es/api/datos/sensores_smart_mobile/3062.xml 885 | 886 | 887 | 116.0 888 | AirQualityObserved 889 | 43.4615 890 | 14.6 891 | 892 | 893 | 0.1 894 | 2019-03-22T19:11:54Z 895 | 3007 896 | -3.80975 897 | 898 | 899 | 12.0 900 | http://datos.santander.es/api/datos/sensores_smart_mobile/3007.xml 901 | 902 | 903 | 82.0 904 | AirQualityObserved 905 | 43.4621 906 | 32.5 907 | 908 | 909 | 0.4 910 | 2019-02-28T09:33:15Z 911 | 3169 912 | -3.83911 913 | 914 | 915 | 10.0 916 | http://datos.santander.es/api/datos/sensores_smart_mobile/3169.xml 917 | 918 | 919 | 116.0 920 | AirQualityObserved 921 | 43.4554 922 | 11.0 923 | 924 | 925 | 0.1 926 | 2019-02-07T07:56:38Z 927 | 3060 928 | -3.83431 929 | 930 | 931 | 67.0 932 | http://datos.santander.es/api/datos/sensores_smart_mobile/3060.xml 933 | 934 | 935 | 116.0 936 | AirQualityObserved 937 | 43.452 938 | 19.2 939 | 940 | 941 | 0.1 942 | 2019-02-05T09:57:31Z 943 | 3072 944 | -3.83223 945 | 946 | 947 | 120.0 948 | http://datos.santander.es/api/datos/sensores_smart_mobile/3072.xml 949 | 950 | 951 | 114.0 952 | AirQualityObserved 953 | 43.4643 954 | 5.7 955 | 956 | 957 | 18.8 958 | 2019-01-28T05:41:06Z 959 | 3120 960 | -3.83531 961 | 962 | 963 | 16.0 964 | http://datos.santander.es/api/datos/sensores_smart_mobile/3120.xml 965 | 966 | 967 | 113.0 968 | AirQualityObserved 969 | 43.4554 970 | 6.3 971 | 972 | 973 | 0.2 974 | 2019-01-23T22:32:13Z 975 | 3049 976 | -3.83363 977 | 978 | 979 | 104.0 980 | http://datos.santander.es/api/datos/sensores_smart_mobile/3049.xml 981 | 982 | 983 | 79.0 984 | AirQualityObserved 985 | 43.4646 986 | 18.7 987 | 988 | 989 | 0.4 990 | 2018-10-21T08:29:45Z 991 | 3108 992 | -3.8356 993 | 994 | 995 | 3.0 996 | http://datos.santander.es/api/datos/sensores_smart_mobile/3108.xml 997 | 998 | 999 | 212.0 1000 | AirQualityObserved 1001 | 43.4673 1002 | 23.5 1003 | 1004 | 1005 | 12.7 1006 | 2018-09-12T18:26:33Z 1007 | 3081 1008 | -3.80611 1009 | 1010 | 1011 | 592.0 1012 | http://datos.santander.es/api/datos/sensores_smart_mobile/3081.xml 1013 | 1014 | 1015 | 84.0 1016 | AirQualityObserved 1017 | 43.4319 1018 | 22.6 1019 | 1020 | 1021 | 0.1 1022 | 2018-09-06T17:58:54Z 1023 | 3177 1024 | -3.83113 1025 | 1026 | 1027 | 62.0 1028 | http://datos.santander.es/api/datos/sensores_smart_mobile/3177.xml 1029 | 1030 | 1031 | 32.0 1032 | AirQualityObserved 1033 | 43.454 1034 | 23.7 1035 | 1036 | 1037 | 0.1 1038 | 2018-07-28T08:54:38Z 1039 | 3166 1040 | -3.86473 1041 | 1042 | 1043 | 8.0 1044 | http://datos.santander.es/api/datos/sensores_smart_mobile/3166.xml 1045 | 1046 | 1047 | 42.0 1048 | AirQualityObserved 1049 | 43.4649 1050 | 17.7 1051 | 1052 | 1053 | 0.1 1054 | 2018-07-16T06:35:55Z 1055 | 3167 1056 | -3.82449 1057 | 1058 | 1059 | 32.0 1060 | http://datos.santander.es/api/datos/sensores_smart_mobile/3167.xml 1061 | 1062 | 1063 | 85.0 1064 | AirQualityObserved 1065 | 43.4555 1066 | 9.0 1067 | 1068 | 1069 | 0.3 1070 | 2018-02-03T06:36:14Z 1071 | 3080 1072 | -3.83413 1073 | 1074 | 1075 | 53.0 1076 | http://datos.santander.es/api/datos/sensores_smart_mobile/3080.xml 1077 | 1078 | 1079 | 60.0 1080 | AirQualityObserved 1081 | 43.4411 1082 | 12.2 1083 | 1084 | 1085 | 0.1 1086 | 2018-01-18T13:08:03Z 1087 | 3028 1088 | -3.8878 1089 | 1090 | 1091 | 105.0 1092 | http://datos.santander.es/api/datos/sensores_smart_mobile/3028.xml 1093 | 1094 | 1095 | 27.0 1096 | AirQualityObserved 1097 | 43.4409 1098 | 5.9 1099 | 1100 | 1101 | 0.5 1102 | 2018-01-18T11:34:58Z 1103 | 3033 1104 | -3.88782 1105 | 1106 | 1107 | 12.0 1108 | http://datos.santander.es/api/datos/sensores_smart_mobile/3033.xml 1109 | 1110 | 1111 | 115.0 1112 | AirQualityObserved 1113 | 43.4619 1114 | 30.2 1115 | 1116 | 1117 | 0.1 1118 | 2017-10-30T07:30:07Z 1119 | 3170 1120 | -3.83923 1121 | 1122 | 1123 | 42.0 1124 | http://datos.santander.es/api/datos/sensores_smart_mobile/3170.xml 1125 | 1126 | 1127 | 800.0 1128 | AirQualityObserved 1129 | 43.4681 1130 | 0.0 1131 | 1132 | 1133 | 99.9 1134 | 2017-10-19T11:21:28Z 1135 | 3003 1136 | -3.7877 1137 | 1138 | 1139 | 999.0 1140 | http://datos.santander.es/api/datos/sensores_smart_mobile/3003.xml 1141 | 1142 | 1143 | 999.0 1144 | AirQualityObserved 1145 | 43.4785 1146 | 0.0 1147 | 1148 | 1149 | 99.9 1150 | 2017-10-19T11:21:28Z 1151 | 3070 1152 | -3.80134 1153 | 1154 | 1155 | 999.0 1156 | http://datos.santander.es/api/datos/sensores_smart_mobile/3070.xml 1157 | 1158 | 1159 | 999.0 1160 | AirQualityObserved 1161 | 43.4555 1162 | 0.0 1163 | 1164 | 1165 | 99.9 1166 | 2017-10-19T11:21:28Z 1167 | 3004 1168 | -3.83401 1169 | 1170 | 1171 | 999.0 1172 | http://datos.santander.es/api/datos/sensores_smart_mobile/3004.xml 1173 | 1174 | 1175 | 999.0 1176 | AirQualityObserved 1177 | 43.4554 1178 | 0.0 1179 | 1180 | 1181 | 99.9 1182 | 2017-10-19T11:21:12Z 1183 | 3029 1184 | -3.83427 1185 | 1186 | 1187 | 999.0 1188 | http://datos.santander.es/api/datos/sensores_smart_mobile/3029.xml 1189 | 1190 | 1191 | 999.0 1192 | AirQualityObserved 1193 | 43.4562 1194 | 0.0 1195 | 1196 | 1197 | 99.9 1198 | 2017-10-19T11:21:12Z 1199 | 3041 1200 | -3.83317 1201 | 1202 | 1203 | 999.0 1204 | http://datos.santander.es/api/datos/sensores_smart_mobile/3041.xml 1205 | 1206 | 1207 | 999.0 1208 | AirQualityObserved 1209 | 43.4556 1210 | 0.0 1211 | 1212 | 1213 | 99.9 1214 | 2017-10-19T11:20:31Z 1215 | 3013 1216 | -3.83373 1217 | 1218 | 1219 | 999.0 1220 | http://datos.santander.es/api/datos/sensores_smart_mobile/3013.xml 1221 | 1222 | 1223 | 999.0 1224 | AirQualityObserved 1225 | 43.4627 1226 | 0.0 1227 | 1228 | 1229 | 99.9 1230 | 2017-10-19T11:20:01Z 1231 | 3075 1232 | -3.82352 1233 | 1234 | 1235 | 999.0 1236 | http://datos.santander.es/api/datos/sensores_smart_mobile/3075.xml 1237 | 1238 | 1239 | 999.0 1240 | AirQualityObserved 1241 | 43.4556 1242 | 0.0 1243 | 1244 | 1245 | 99.9 1246 | 2017-10-19T11:20:01Z 1247 | 3071 1248 | -3.83416 1249 | 1250 | 1251 | 999.0 1252 | http://datos.santander.es/api/datos/sensores_smart_mobile/3071.xml 1253 | 1254 | 1255 | 999.0 1256 | AirQualityObserved 1257 | 43.4556 1258 | 0.0 1259 | 1260 | 1261 | 99.9 1262 | 2017-10-19T11:19:51Z 1263 | 3040 1264 | -3.83366 1265 | 1266 | 1267 | 999.0 1268 | http://datos.santander.es/api/datos/sensores_smart_mobile/3040.xml 1269 | 1270 | 1271 | 999.0 1272 | AirQualityObserved 1273 | 43.4685 1274 | 0.0 1275 | 1276 | 1277 | 99.9 1278 | 2017-10-19T11:19:45Z 1279 | 3092 1280 | -3.79757 1281 | 1282 | 1283 | 999.0 1284 | http://datos.santander.es/api/datos/sensores_smart_mobile/3092.xml 1285 | 1286 | 1287 | 999.0 1288 | AirQualityObserved 1289 | 43.4605 1290 | 0.0 1291 | 1292 | 1293 | 99.9 1294 | 2017-10-19T11:18:55Z 1295 | 3012 1296 | -3.82585 1297 | 1298 | 1299 | 999.0 1300 | http://datos.santander.es/api/datos/sensores_smart_mobile/3012.xml 1301 | 1302 | 1303 | 999.0 1304 | AirQualityObserved 1305 | 43.4586 1306 | 0.0 1307 | 1308 | 1309 | 99.9 1310 | 2017-10-19T11:18:14Z 1311 | 3043 1312 | -3.85141 1313 | 1314 | 1315 | 999.0 1316 | http://datos.santander.es/api/datos/sensores_smart_mobile/3043.xml 1317 | 1318 | 1319 | 999.0 1320 | AirQualityObserved 1321 | 43.4238 1322 | 200.0 1323 | 1324 | 1325 | 99.9 1326 | 2017-10-19T10:21:50Z 1327 | 3172 1328 | -3.85676 1329 | 1330 | 1331 | 999.0 1332 | http://datos.santander.es/api/datos/sensores_smart_mobile/3172.xml 1333 | 1334 | 1335 | 999.0 1336 | AirQualityObserved 1337 | 43.4677 1338 | 200.0 1339 | 1340 | 1341 | 99.9 1342 | 2017-10-16T01:46:09Z 1343 | 3117 1344 | -3.83619 1345 | 1346 | 1347 | 999.0 1348 | http://datos.santander.es/api/datos/sensores_smart_mobile/3117.xml 1349 | 1350 | 1351 | --------------------------------------------------------------------------------