package es.upm.fi.dia.oeg.map4rdf.server.dao.impl; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.vocabulary.RDFS; import es.upm.fi.dia.oeg.map4rdf.server.dao.DaoException; import es.upm.fi.dia.oeg.map4rdf.server.dao.Map4rdfDao; import es.upm.fi.dia.oeg.map4rdf.server.vocabulary.Geo; import es.upm.fi.dia.oeg.map4rdf.share.BoundingBox; import es.upm.fi.dia.oeg.map4rdf.share.Facet; import es.upm.fi.dia.oeg.map4rdf.share.FacetConstraint; import es.upm.fi.dia.oeg.map4rdf.share.GeoResource; import es.upm.fi.dia.oeg.map4rdf.share.GeoResourceOverlay; import es.upm.fi.dia.oeg.map4rdf.share.Point; import es.upm.fi.dia.oeg.map4rdf.share.PointBean; import es.upm.fi.dia.oeg.map4rdf.share.PolyLine; import es.upm.fi.dia.oeg.map4rdf.share.PolyLineBean; import es.upm.fi.dia.oeg.map4rdf.share.Resource; import es.upm.fi.dia.oeg.map4rdf.share.StatisticDefinition; import es.upm.fi.dia.oeg.map4rdf.share.Year; import es.upm.fi.dia.oeg.map4rdf.share.aemet.AemetResource; import es.upm.fi.dia.oeg.map4rdf.share.viajero.ViajeroResourceContainer; public class ViajeroImpl extends CommonDaoImpl implements Map4rdfDao { private static final Logger LOG = Logger.getLogger(ViajeroImpl.class); public ViajeroImpl(String endpointUri,String defaultProjection) { super(endpointUri,defaultProjection); } @Override public GeoResource getGeoResource(String uri) throws DaoException { QueryExecution execution = QueryExecutionFactory.sparqlService( endpointUri, createGetResourceQuery(uri)); try { ResultSet queryResult = execution.execSelect(); GeoResource resource = null; while (queryResult.hasNext()) { QuerySolution solution = queryResult.next(); try { double lat = solution.getLiteral("lat").getDouble(); double lng = solution.getLiteral("lng").getDouble(); if (resource == null) { resource = new AemetResource(uri, new PointBean( uri, lng, lat,defaultProjection)); } if (solution.contains("label")) { Literal labelLiteral = solution.getLiteral("label"); resource.addLabel(labelLiteral.getLanguage(), labelLiteral.getString()); } } catch (NumberFormatException e) { LOG.warn("Invalid Latitud or Longitud value: " + e.getMessage()); } } return resource; } catch (Exception e) { throw new DaoException("Unable to execute SPARQL query", e); } finally { execution.close(); } } @Override public List<GeoResource> getGeoResources(BoundingBox boundingBox, Set<FacetConstraint> constraints) throws DaoException { return getGeoResources(boundingBox, constraints, null); } @Override public List<GeoResource> getGeoResources(BoundingBox boundingBox, Set<FacetConstraint> constraints, int max) throws DaoException { return getGeoResources(boundingBox, constraints, new Integer(max)); } @Override public List<GeoResourceOverlay> getGeoResourceOverlays( StatisticDefinition statisticDefinition, BoundingBox boundingBox, Set<FacetConstraint> constraints) throws DaoException { // TODO Not statistics in Viajero return Collections.emptyList(); } @Override public List<Facet> getFacets(String predicateUri, BoundingBox boundingBox) throws DaoException { Map<String, Facet> result = new HashMap<String, Facet>(); StringBuilder queryBuffer = new StringBuilder(); queryBuffer.append("select distinct ?class ?label where { "); queryBuffer.append("?x <" + Geo.lat + "> _:lat. "); queryBuffer.append("?x <" + Geo.lng + "> _:lng. "); queryBuffer.append("?x <" + predicateUri + "> ?class . "); queryBuffer.append("optional {?class <" + RDFS.label + "> ?label . }}"); QueryExecution execution = QueryExecutionFactory.sparqlService( endpointUri, queryBuffer.toString()); try { ResultSet queryResult = execution.execSelect(); while (queryResult.hasNext()) { QuerySolution solution = queryResult.next(); String uri = solution.getResource("class").getURI(); Facet value = null; if (result.containsKey(uri)) { value = result.get(uri); } else { value = new Facet(uri); result.put(uri, value); } if (solution.contains("label")) { Literal label = solution.getLiteral("label"); value.addLabel(label.getLanguage(), label.getString()); } } return new ArrayList<Facet>(result.values()); } catch (Exception e) { throw new DaoException("Unable to execute SPARQL query", e); } finally { execution.close(); } } @Override public List<Year> getYears(String datasetUri) throws DaoException { // TODO Not statistics in Viajero return Collections.emptyList(); } @Override public List<Resource> getStatisticDatasets() throws DaoException { // TODO Not statistics in Viajero return Collections.emptyList(); } @Override public List<GeoResource> getNextPoints(BoundingBox boundingBox, int max) throws DaoException { HashMap<String, GeoResource> result = new HashMap<String, GeoResource>(); QueryExecution execution = QueryExecutionFactory.sparqlService( endpointUri, createGetNextPoints(boundingBox, max)); try { ResultSet queryResult = execution.execSelect(); while (queryResult.hasNext()) { QuerySolution solution = queryResult.next(); try { String uri = solution.getResource("r").getURI(); double lat = solution.getLiteral("lat").getDouble(); double lng = solution.getLiteral("lng").getDouble(); GeoResource resource = result.get(uri); if (resource == null) { resource = new ViajeroResourceContainer(uri, new PointBean(uri, lng, lat,defaultProjection)); result.put(uri, resource); } if (solution.contains("label")) { Literal labelLiteral = solution.getLiteral("label"); resource.addLabel(labelLiteral.getLanguage(), labelLiteral.getString()); } } catch (NumberFormatException e) { LOG.warn("Invalid Latitud or Longitud value: " + e.getMessage()); } } return new ArrayList<GeoResource>(result.values()); } catch (Exception e) { throw new DaoException("Unable to execute SPARQL query", e); } finally { execution.close(); } } private List<GeoResource> getGeoResources(BoundingBox boundingBox, Set<FacetConstraint> constraints, Integer max) throws DaoException { HashMap<String, ViajeroResourceContainer> result = new HashMap<String, ViajeroResourceContainer>(); QueryExecution execution = QueryExecutionFactory.sparqlService( endpointUri, createGetResourcesQueryAdaptedViajero(boundingBox, constraints, max)); if(constraints!=null && constraints.isEmpty()){ return new ArrayList<GeoResource>(); } try { ResultSet queryResult = execution.execSelect(); while (queryResult.hasNext()) { QuerySolution solution = queryResult.next(); try { String uri = solution.getResource("r").getURI(); double lat = solution.getLiteral("lat").getDouble(); double lng = solution.getLiteral("lng").getDouble(); ViajeroResourceContainer resource = null; resource = result.get(uri); if (resource == null) { if(solution.contains("facetValueID") && solution.getResource("facetValueID").getURI().contains("Trip")){ resource = new ViajeroResourceContainer(uri, getItinerary(uri)); result.put(uri, resource); }else{ resource = new ViajeroResourceContainer(uri, new PointBean(uri, lng, lat,defaultProjection)); result.put(uri, resource); } } if (solution.contains("label")) { Literal labelLiteral = solution.getLiteral("label"); resource.addLabel(labelLiteral.getLanguage(), labelLiteral.getString()); } if(solution.contains("facetID") && solution.contains("facetValueID")){ String facetID=solution.getResource("facetID").getURI(); String facetValueID=solution.getResource("facetValueID").getURI(); resource.setFacetConstraint(new FacetConstraint(facetID, facetValueID)); } } catch (NumberFormatException e) { LOG.warn("Invalid Latitud or Longitud value: " + e.getMessage()); } } return new ArrayList<GeoResource>(result.values()); } catch (Exception e) { throw new DaoException("Unable to execute SPARQL query", e); } finally { execution.close(); } } private String createGetResourcesQueryAdaptedViajero( BoundingBox boundingBox, Set<FacetConstraint> constraints, Integer limit) { StringBuilder query = new StringBuilder( "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT distinct ?r ?lat ?lng ?label ?facetID ?facetValueID "); query.append("WHERE { "); if (constraints != null && !constraints.isEmpty()) { for (FacetConstraint constraint : constraints) { if (constraint.getFacetValueId().contains("Trip")) { query.append("{?t ?facetID ?facetValueID. "); query.append("FILTER("); query.append("?facetID IN("); query.append("<"+constraint.getFacetId()+">)"); query.append(" && ?facetValueID IN("); query.append("<"+constraint.getFacetValueId()+">)). "); query.append("?t <http://webenemasuno.linkeddata.es/ontology/OPMO/hasItinerary> ?r."); query.append("OPTIONAL { ?r <" + RDFS.label + "> ?label } ."); query.append("?r <http://webenemasuno.linkeddata.es/ontology/OPMO/hasPart> ?part."); query.append("?part <http://webenemasuno.linkeddata.es/ontology/OPMO/hasPoint> ?point. "); query.append("?point <"+Geo.lat+"> ?lat."); query.append("?point <"+Geo.lng+"> ?lng."); query.append("} UNION"); } else if (constraint.getFacetValueId().contains("Point")) { //Tratamiento especial si es un punto query.append("{?r ?facetID ?facetValueID. "); query.append("FILTER("); query.append("?facetID IN("); query.append("<"+constraint.getFacetId()+">)"); query.append(" && ?facetValueID IN("); query.append("<"+constraint.getFacetValueId()+">)). "); query.append("?r <" + Geo.lat + "> ?lat. "); query.append("?r <" + Geo.lng + "> ?lng . "); query.append("OPTIONAL { ?r <" + RDFS.label + "> ?label } ."); query.append("} UNION"); } else { // cualquier cosa con localizacion (guias, aristas) query.append("{?g ?facetID ?facetValueID. "); query.append("FILTER("); query.append("?facetID IN("); query.append("<"+constraint.getFacetId()+">)"); query.append(" && ?facetValueID IN("); query.append("<"+constraint.getFacetValueId()+">)). "); query.append("?g <"+Geo.location+"> ?r."); query.append("?r <" + Geo.lat + "> ?lat. "); query.append("?r <" + Geo.lng + "> ?lng . "); query.append("OPTIONAL { ?r <" + RDFS.label + "> ?label } ."); query.append(" } UNION"); } } query.delete(query.length() - 5, query.length()); } // filters if (boundingBox != null) { query = addBoundingBoxFilter(query, boundingBox); } query.append("}"); if (limit != null) { query.append(" LIMIT " + limit); } return query.toString(); } private PolyLine getItinerary(String uriItinerario) throws DaoException { // query 1. The path & order of the itinerary. QueryExecution exec2 = QueryExecutionFactory.sparqlService(endpointUri, createGetItineraryQuery(1000, uriItinerario));// como mucho un // itinerario de // 1000 puntos ResultSet queryResult2 = exec2.execSelect(); String point = ""; double lat, longitude; ArrayList<Point> puntosOrdenados = new ArrayList<Point>(); while (queryResult2.hasNext()) { QuerySolution solution2 = queryResult2.next(); point = solution2.getResource("point").getURI(); lat = solution2.getLiteral("lat").getDouble(); longitude = solution2.getLiteral("long").getDouble(); PointBean p1 = new PointBean(point, longitude, lat,defaultProjection); puntosOrdenados.add(p1); } // Los puntos vienen ordenados ya por ?order (en la consulta) PolyLineBean p = new PolyLineBean(uriItinerario, puntosOrdenados,defaultProjection); return p; } private String createGetItineraryQuery(Integer limit, String uri) { StringBuilder query = new StringBuilder( "SELECT distinct ?order ?point ?lat ?long "); query.append("WHERE{ "); query.append("<" + uri + "> <http://webenemasuno.linkeddata.es/ontology/OPMO/hasPart> ?path."); query.append("?path <http://webenemasuno.linkeddata.es/ontology/OPMO/hasOrder> ?order."); query.append("?path <http://webenemasuno.linkeddata.es/ontology/OPMO/hasPoint> ?point."); query.append("?point <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat."); query.append("?point <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?long."); query.append("}"); query.append("ORDER BY ?order"); if (limit != null) { query.append(" LIMIT " + limit); } return query.toString(); } private String createGetResourceQuery(String uri) { StringBuilder query = new StringBuilder( "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT distinct ?position ?lat ?lng ?label "); query.append("WHERE { "); query.append("<" + "uri" + "> <" + Geo.lat + "> ?lat. "); query.append("<" + "uri" + "> <" + Geo.lng + "> ?lng . "); query.append("OPTIONAL { <" + uri + "> <" + RDFS.label + "> ?label } ."); query.append("}"); return query.toString(); } private String createGetNextPoints(BoundingBox boundingBox, int limit){ StringBuilder query = new StringBuilder("PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT distinct ?r ?lat ?lng ?label "); query.append("WHERE { "); query.append("?r <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2003/01/geo/wgs84_pos#Point>."); query.append("?r <" + Geo.lat + "> ?lat. "); query.append("?r <" + Geo.lng + "> ?lng . "); query.append("OPTIONAL { ?r <" + RDFS.label + "> ?label } ."); //filters if (boundingBox!=null) { query = addBoundingBoxFilter(query, boundingBox); } query.append("}"); if (limit >0) { query.append(" LIMIT " + limit); } return query.toString(); } }