Commit 24edd59b authored by Alexander Prendetskiy's avatar Alexander Prendetskiy Committed by Matija Obreza

Accession API v1: Geo info

parent 177d6dc1
...@@ -116,12 +116,14 @@ public class AccessionController { ...@@ -116,12 +116,14 @@ public class AccessionController {
@Value("${base.url}") @Value("${base.url}")
private String baseUrl; private String baseUrl;
@Value("${cdn.servers}")
private String[] cdnServers;
private final Set<String> terms = Sets.newHashSet("institute.code", "institute.country.code3", "cropName", "crop.shortName", "taxonomy.genus", "taxonomy.species", private final Set<String> terms = Sets.newHashSet("institute.code", "institute.country.code3", "cropName", "crop.shortName", "taxonomy.genus", "taxonomy.species",
"taxonomy.genusSpecies", "countryOfOrigin.code3", "sampStat", "available", "mlsStatus", "donorCode", "sgsv", "storage", "duplSite", "breederCode"); "taxonomy.genusSpecies", "countryOfOrigin.code3", "sampStat", "available", "mlsStatus", "donorCode", "sgsv", "storage", "duplSite", "breederCode");
private ObjectMapper objectMapper = new ObjectMapper(); private ObjectMapper objectMapper = new ObjectMapper();
/** /**
* Gets the accession * Gets the accession
* *
...@@ -238,6 +240,21 @@ public class AccessionController { ...@@ -238,6 +240,21 @@ public class AccessionController {
return accessionDetails; return accessionDetails;
} }
@PostMapping(value = "/geo", produces = MediaType.APPLICATION_JSON_VALUE)
@JsonView({ JsonViews.Public.class })
public GeoInfoJson getGeoInfo(@PathVariable(value = "f", required = false) String filterCode, @RequestBody(required = false) AccessionFilter filter) throws IOException {
if (filterCode != null) {
filter = shortFilterService.filterByCode(filterCode, AccessionFilter.class);
}
GeoInfoJson geoInfo = new GeoInfoJson();
geoInfo.bounds = accessionService.getBounds(filter);
geoInfo.accessionCount = accessionService.countAccessions(filter);
geoInfo.tileServers = cdnServers;
return geoInfo;
}
/** /**
* Get term overview for filters * Get term overview for filters
* *
...@@ -321,9 +338,9 @@ public class AccessionController { ...@@ -321,9 +338,9 @@ public class AccessionController {
response.setContentType("application/vnd.google-earth.kml+xml"); response.setContentType("application/vnd.google-earth.kml+xml");
response.addHeader("Content-Disposition", String.format("attachment; filename=\"genesys-kml-" + filterCode + ".kml\"")); response.addHeader("Content-Disposition", String.format("attachment; filename=\"genesys-kml-" + filterCode + ".kml\""));
DecimalFormatSymbols dfs=new DecimalFormatSymbols(); DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setDecimalSeparator('.'); dfs.setDecimalSeparator('.');
DecimalFormat decimalFormat=new DecimalFormat("0.#", dfs); DecimalFormat decimalFormat = new DecimalFormat("0.#", dfs);
decimalFormat.setMinimumIntegerDigits(1); decimalFormat.setMinimumIntegerDigits(1);
decimalFormat.setMinimumFractionDigits(6); decimalFormat.setMinimumFractionDigits(6);
decimalFormat.setGroupingUsed(false); decimalFormat.setGroupingUsed(false);
...@@ -374,4 +391,10 @@ public class AccessionController { ...@@ -374,4 +391,10 @@ public class AccessionController {
public List<Subset> subsets; public List<Subset> subsets;
} }
public static class GeoInfoJson {
public List<Object[]> bounds;
public long accessionCount;
public String[] tileServers;
}
} }
...@@ -28,7 +28,8 @@ import org.springframework.data.domain.Pageable; ...@@ -28,7 +28,8 @@ import org.springframework.data.domain.Pageable;
public interface AccessionService { public interface AccessionService {
/** /**
* Count accessions. Uses Elasticsearch, but counts from database when number is small enough. * Count accessions. Uses Elasticsearch, but counts from database when number is
* small enough.
* *
* @param filter the filter * @param filter the filter
* @return the count * @return the count
...@@ -44,6 +45,14 @@ public interface AccessionService { ...@@ -44,6 +45,14 @@ public interface AccessionService {
*/ */
Page<Accession> list(AccessionFilter filter, Pageable page); Page<Accession> list(AccessionFilter filter, Pageable page);
/**
* Gets the bounds.
*
* @param filter the filter
* @return the bounds
*/
List<Object[]> getBounds(AccessionFilter filter);
/** /**
* Gets accession by uuid * Gets accession by uuid
* *
...@@ -62,6 +71,7 @@ public interface AccessionService { ...@@ -62,6 +71,7 @@ public interface AccessionService {
/** /**
* Converts AccessionIdentifiers to UUID * Converts AccessionIdentifiers to UUID
*
* @param identifiers accession identifiers to lookup in DB * @param identifiers accession identifiers to lookup in DB
* @return map with UUIDs and related AccessionIdentifiers * @return map with UUIDs and related AccessionIdentifiers
*/ */
......
...@@ -15,15 +15,19 @@ ...@@ -15,15 +15,19 @@
*/ */
package org.genesys2.server.service.impl; package org.genesys2.server.service.impl;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import javax.persistence.EntityManager;
import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionData; import org.genesys2.server.model.genesys.AccessionData;
import org.genesys2.server.model.genesys.AccessionId; import org.genesys2.server.model.genesys.AccessionId;
import org.genesys2.server.model.genesys.QAccession;
import org.genesys2.server.model.impl.AccessionIdentifier3; import org.genesys2.server.model.impl.AccessionIdentifier3;
import org.genesys2.server.persistence.AccessionRepository; import org.genesys2.server.persistence.AccessionRepository;
import org.genesys2.server.service.AccessionService; import org.genesys2.server.service.AccessionService;
...@@ -37,10 +41,16 @@ import org.springframework.cache.annotation.Cacheable; ...@@ -37,10 +41,16 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.Querydsl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.core.types.dsl.PathBuilderFactory;
import com.querydsl.jpa.JPQLQuery;
/** /**
* Accession services. * Accession services.
*/ */
...@@ -60,6 +70,10 @@ public class AccessionServiceImpl implements AccessionService { ...@@ -60,6 +70,10 @@ public class AccessionServiceImpl implements AccessionService {
@Autowired @Autowired
private AccessionCounter accessionCounter; private AccessionCounter accessionCounter;
@Autowired
private EntityManager entityManager;
private PathBuilder<Accession> accessionPathBuilder = new PathBuilderFactory().create(Accession.class);
private <T extends AccessionData> T lazyLoad(T accession) { private <T extends AccessionData> T lazyLoad(T accession) {
if (accession != null) { if (accession != null) {
...@@ -116,12 +130,9 @@ public class AccessionServiceImpl implements AccessionService { ...@@ -116,12 +130,9 @@ public class AccessionServiceImpl implements AccessionService {
Map<UUID, AccessionIdentifier3> res = new HashMap<>(); Map<UUID, AccessionIdentifier3> res = new HashMap<>();
List<Accession> foundAccessions = accessionRepository.findById(identifiers); List<Accession> foundAccessions = accessionRepository.findById(identifiers);
for(Accession accession: foundAccessions) { for (Accession accession : foundAccessions) {
Optional<? extends AccessionIdentifier3> toPut = identifiers.stream() Optional<? extends AccessionIdentifier3> toPut = identifiers.stream().filter(id -> id.getAccessionNumber().equals(accession.getAccessionNumber()) && id.getGenus()
.filter(id -> id.getAccessionNumber().equals(accession.getAccessionNumber()) .equals(accession.getGenus()) && id.getHoldingInstitute().equals(accession.getInstCode())).findFirst();
&& id.getGenus().equals(accession.getGenus())
&& id.getHoldingInstitute().equals(accession.getInstCode())
).findFirst();
toPut.ifPresent(accessionIdentifier3 -> res.put(accession.getUuid(), accessionIdentifier3)); toPut.ifPresent(accessionIdentifier3 -> res.put(accession.getUuid(), accessionIdentifier3));
} }
...@@ -151,15 +162,32 @@ public class AccessionServiceImpl implements AccessionService { ...@@ -151,15 +162,32 @@ public class AccessionServiceImpl implements AccessionService {
@Cacheable(value = "apiResponses.accessionApi1.list", unless = "#result == null", keyGenerator = "shortFilterKeyGenerator") @Cacheable(value = "apiResponses.accessionApi1.list", unless = "#result == null", keyGenerator = "shortFilterKeyGenerator")
public Page<Accession> list(AccessionFilter filter, Pageable page) { public Page<Accession> list(AccessionFilter filter, Pageable page) {
List<Accession> content = accessionRepository.findAll(filter, page); List<Accession> content = accessionRepository.findAll(filter, page);
long total = elasticsearchService.count(Accession.class, filter);
if (total < 10000) { long total = countAccessions(filter);
// If total is below 10K, use actual count
total = accessionRepository.count(filter.buildQuery());
}
return new PageImpl<>(content, page, total); return new PageImpl<>(content, page, total);
} }
@Override
public List<Object[]> getBounds(AccessionFilter filter) {
QAccession accession = QAccession.accession;
Querydsl querydsl = new Querydsl(entityManager, accessionPathBuilder);
JPQLQuery<Tuple> query = querydsl.createQuery(accession).select(accession.accessionId.geo.latitude.min(), accession.accessionId.geo.longitude.max(),
accession.accessionId.geo.latitude.max(), accession.accessionId.geo.longitude.min()).from(accession).where(filter.buildQuery());
Object[] results = query.fetchOne().toArray();
List<Object[]> latLngBounds = new ArrayList<>();
// corner1
latLngBounds.add(new Object[] { results[0], results[1] });
// corner2
latLngBounds.add(new Object[] { results[2], results[3] });
return latLngBounds;
}
@Override @Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public List<Accession> processAccessions(List<Long> accessionIds, IAccessionAction action) { public List<Accession> processAccessions(List<Long> accessionIds, IAccessionAction action) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment