Commit 60725168 authored by Alexander Prendetskiy's avatar Alexander Prendetskiy Committed by Matija Obreza
Browse files

add new TileController

parent e9f1b92d
package org.genesys2.server.api.v1;
import org.genesys.catalog.service.ShortFilterService;
import org.genesys2.server.service.MappingService;
import org.genesys2.server.service.filter.AccessionFilter;
import org.genesys2.spring.ResourceNotFoundException;
import org.genesys2.util.ColorUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//@RestController("tileApi1")
@Controller
//@Api(tags = {"tile"})
public class TileController {
@Autowired
private MappingService mappingService;
@Autowired
private ShortFilterService shortFilterService;
private static final Logger LOG = LoggerFactory.getLogger(TileController.class);
@RequestMapping(value = "/explore/tile/{zoom}/{x}/{y}/{filterCode}", produces = MediaType.IMAGE_PNG_VALUE)
public void tile(@PathVariable(value = "filterCode", required = true) String filterCode,
@RequestParam(value = "color", required = false) String color,
@PathVariable("x") int x, @PathVariable("y") int y, @PathVariable("zoom") int zoom,
HttpServletResponse response) {
try {
AccessionFilter appliedFilters = shortFilterService.filterByCode(filterCode, AccessionFilter.class);
byte[] image = mappingService.getTile(appliedFilters, zoom, x, y);
image = ColorUtil.changeColor(color, image);
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=3600, s-maxage=3600, public, no-transform");
response.getOutputStream().write(image, 0, image.length);
} catch (final IOException e) {
LOG.warn(e.getMessage());
throw new RuntimeException("Could not render image", e);
} catch (final Throwable e) {
LOG.error(e.getMessage(), e);
throw new ResourceNotFoundException(e.getMessage());
}
}
}
......@@ -74,6 +74,7 @@ import org.genesys2.server.service.impl.GenesysFilterServiceImpl.LabelValue;
import org.genesys2.server.service.impl.SearchException;
import org.genesys2.server.servlet.model.ErrorResponse;
import org.genesys2.spring.ResourceNotFoundException;
import org.genesys2.util.ColorUtil;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
......@@ -795,7 +796,7 @@ public class ExplorerController extends BaseController implements InitializingBe
AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
byte[] image = mappingService.getTile(appliedFilters, zoom, x, y);
image = changeColor(color, image);
image = ColorUtil.changeColor(color, image);
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=3600, s-maxage=3600, public, no-transform");
response.getOutputStream().write(image, 0, image.length);
......@@ -816,44 +817,6 @@ public class ExplorerController extends BaseController implements InitializingBe
return geoService.getBoundingBox(appliedFilters);
}
private byte[] changeColor(String color, byte[] imageBytes) {
if (StringUtils.isBlank(color)) {
return imageBytes;
}
if (!color.startsWith("#"))
color = "#" + color;
if (LOG.isDebugEnabled())
LOG.debug("Changing color to {}", color);
try {
final Color newColor = Color.decode(color);
if (newColor.equals(MappingService.DEFAULT_TILE_COLOR)) {
return imageBytes;
}
final int originalColor = MappingService.DEFAULT_TILE_COLOR.getRGB();
final int updatedColor = newColor.getRGB();
final MapColorsFilter mcf = new MapColorsFilter(originalColor, updatedColor);
final ByteArrayInputStream bios = new ByteArrayInputStream(imageBytes);
final BufferedImage image = mcf.filter(ImageIO.read(bios), null);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "PNG", baos);
return baos.toByteArray();
} catch (final NumberFormatException e) {
LOG.warn("Cannot get color for {}", color);
return imageBytes;
} catch (final IOException e) {
LOG.warn(e.getMessage());
return imageBytes;
}
}
private void overviewInstitutes(ModelMap model, AppliedFilters appliedFilters) throws SearchException {
model.addAttribute("statsInstCode", elasticService.termStatisticsAuto(Accession.class, AccessionFilter.convert(appliedFilters), 20, AppliedFiltersConverter.convertTerm(FilterConstants.INSTCODE)));
model.addAttribute("statsInstCountry", elasticService.termStatisticsAuto(Accession.class, AccessionFilter.convert(appliedFilters), 20, AppliedFiltersConverter.convertTerm(FilterConstants.INSTITUTE_COUNTRY_ISO3)));
......
......@@ -18,6 +18,7 @@ package org.genesys2.server.service;
import java.util.List;
import org.genesys.blocks.model.filters.BasicModelFilter;
import org.genesys2.server.model.elastic.AccessionDetails;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
......@@ -41,5 +42,7 @@ public interface GenesysFilterService {
void listGeoTile(boolean distinct, AppliedFilters filters, Integer limit, int zoom, int xtile, int ytile, RowCallbackHandler rowHandler);
List<Object[]> listGeoTile(BasicModelFilter filters, Integer limit, int zoom, int xtile, int ytile);
AppliedFilters transformFiltersIfNeed(AppliedFilters appliedFilters);
}
......@@ -20,6 +20,7 @@ import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import org.genesys.blocks.model.filters.BasicModelFilter;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
public interface MappingService {
......@@ -68,6 +69,8 @@ public interface MappingService {
*/
byte[] getTile(AppliedFilters filters, int zoom, int xtile, int ytile);
byte[] getTile(BasicModelFilter filters, int zoom, int xtile, int ytile);
/**
* Coordinate utilities
*/
......
......@@ -23,30 +23,28 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import com.querydsl.core.QueryResults;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.JPQLQuery;
import com.querydsl.jpa.impl.JPAQuery;
import org.genesys.blocks.model.filters.BasicModelFilter;
import org.genesys2.server.exception.MaxPageLimitException;
import org.genesys2.server.model.elastic.AccessionDetails;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.Method;
import org.genesys2.server.model.genesys.*;
import org.genesys2.server.model.impl.Country;
import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.model.impl.GeoRegion;
import org.genesys2.server.persistence.AccessionRepository;
import org.genesys2.server.persistence.MethodRepository;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.ElasticsearchService;
import org.genesys2.server.service.*;
import org.genesys2.server.service.ElasticsearchService.Term;
import org.genesys2.server.service.ElasticsearchService.TermResult;
import org.genesys2.server.service.FilterConstants;
import org.genesys2.server.service.GenesysFilterService;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.GeoRegionService;
import org.genesys2.server.service.GeoService;
import org.genesys2.server.service.InstituteService;
import org.genesys2.server.service.TaxonomyService;
import org.genesys2.server.service.filter.AccessionFilter;
import org.genesys2.server.service.filter.AppliedFiltersConverter;
import org.genesys2.server.service.impl.DirectMysqlQuery.MethodResolver;
......@@ -88,8 +86,8 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
@Autowired
private GeoService geoService;
// @PersistenceContext
// private EntityManager entityManager;
@Autowired
private EntityManager entityManager;
private JdbcTemplate jdbcTemplate;
......@@ -431,6 +429,26 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
}, rowHandler);
}
@Override
// TODO check query - should be something like in the method above
public List<Object[]> listGeoTile(BasicModelFilter filters, Integer limit, int zoom, int xtile, int ytile) {
QAccession accession = QAccession.accession;
// migrate functionality from DirectMysqlQuery.filterTile
JPQLQuery<Tuple> query = new JPAQuery<>(entityManager);
query.select(accession.accessionId.geo.longitude, accession.accessionId.geo.latitude).distinct().from(accession);
query.where(filters.buildQuery());
QueryResults<Tuple> results = query.fetchResults();
return results.getResults().stream()
.map(item -> new Object[]{
item.get(accession.accessionId.geo.longitude),
item.get(accession.accessionId.geo.latitude),
}).collect(Collectors.toList());
}
@Override
public AppliedFilters transformFiltersIfNeed(final AppliedFilters appliedFilters) {
AppliedFilter regionOriginFilter = appliedFilters.stream().filter(filter -> filter.getFilterName().equals("regionOrigin")).findFirst().orElse(null);
......
......@@ -23,9 +23,11 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.imageio.ImageIO;
import org.genesys.blocks.model.filters.BasicModelFilter;
import org.genesys2.server.service.GenesysFilterService;
import org.genesys2.server.service.MappingService;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
......@@ -229,4 +231,38 @@ public class MappingServiceImpl implements MappingService {
throw new RuntimeException("Could not render image", e);
}
}
@Override
public byte[] getTile(BasicModelFilter filters, int zoom, int xtile, int ytile) {
final BufferedImage bufferedImage = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
final int[] pixelSizes = new int[] { 0, 0, 0, 1, 1, 2, 2, 2, 3, 2, 2, 3 };
final int pixelSize = pixelSizes[zoom >= pixelSizes.length ? pixelSizes.length - 1 : zoom];
final int colorWithoutAlpha = MappingService.DEFAULT_TILE_COLOR.getRGB();
List<Object[]> geoTiles = filterService.listGeoTile(filters, null, zoom, xtile, ytile);
geoTiles.forEach(item -> {
final int longitude = MappingService.CoordUtil.lonToImg3(zoom, xtile, (Double) item[0]);
final int latitude = MappingService.CoordUtil.latToImg3(zoom, ytile, (Double) item[1]);
for (int i = -pixelSize / 2; i <= pixelSize / 2; i++) {
for (int j = -pixelSize / 2; j <= pixelSize / 2; j++) {
if (longitude + i >= 0 && latitude + j >= 0 && longitude + i < 256 && latitude + j < 256) {
bufferedImage.setRGB(longitude + i, latitude + j, colorWithoutAlpha);
}
}
}
});
try {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", baos);
return baos.toByteArray();
} catch (final IOException e) {
LOG.warn(e.getMessage(), e);
throw new RuntimeException("Couldn't render image", e);
}
}
}
package org.genesys2.util;
import com.jhlabs.image.MapColorsFilter;
import org.apache.commons.lang3.StringUtils;
import org.genesys2.server.service.MappingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ColorUtil {
private final static Logger LOG = LoggerFactory.getLogger(ColorUtil.class);
public static byte[] changeColor(String color, byte[] imageBytes) {
if (StringUtils.isBlank(color)) {
return imageBytes;
}
if (!color.startsWith("#"))
color = "#" + color;
if (LOG.isDebugEnabled())
LOG.debug("Changing color to {}", color);
try {
final Color newColor = Color.decode(color);
if (newColor.equals(MappingService.DEFAULT_TILE_COLOR)) {
return imageBytes;
}
final int originalColor = MappingService.DEFAULT_TILE_COLOR.getRGB();
final int updatedColor = newColor.getRGB();
final MapColorsFilter mcf = new MapColorsFilter(originalColor, updatedColor);
final ByteArrayInputStream bios = new ByteArrayInputStream(imageBytes);
final BufferedImage image = mcf.filter(ImageIO.read(bios), null);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "PNG", baos);
return baos.toByteArray();
} catch (final NumberFormatException e) {
LOG.warn("Cannot get color for {}", color);
return imageBytes;
} catch (final IOException e) {
LOG.warn(e.getMessage());
return imageBytes;
}
}
}
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