Commit d24c9752 authored by Matija Obreza's avatar Matija Obreza
Browse files

Refactored code for TileController

- Moved internal class CoordUtil to org.genesys2.utils
parent 60725168
...@@ -151,7 +151,7 @@ public class ShortFilterServiceImpl implements ShortFilterService { ...@@ -151,7 +151,7 @@ public class ShortFilterServiceImpl implements ShortFilterService {
@Override @Override
public <T> T filterByCode(String code, Class<T> clazz) throws IOException { public <T> T filterByCode(String code, Class<T> clazz) throws IOException {
ShortFilter shortFilter = shortFilterRepository.findByCode(code); ShortFilter shortFilter = shortFilterRepository.findByCode(code == null ? "" : code);
return mapper.readValue(shortFilter.getJson(), clazz); return mapper.readValue(shortFilter.getJson(), clazz);
} }
......
/*
* Copyright 2018 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.server.api.v1; package org.genesys2.server.api.v1;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.genesys.catalog.service.ShortFilterService; import org.genesys.catalog.service.ShortFilterService;
import org.genesys2.server.service.MappingService; import org.genesys2.server.service.MappingService;
import org.genesys2.server.service.filter.AccessionFilter; import org.genesys2.server.service.filter.AccessionFilter;
import org.genesys2.spring.ResourceNotFoundException;
import org.genesys2.util.ColorUtil; import org.genesys2.util.ColorUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
...@@ -14,12 +30,11 @@ import org.springframework.stereotype.Controller; ...@@ -14,12 +30,11 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//@RestController("tileApi1") /**
* This is not an API controller, it's accessible to anonymous users.
*/
@Controller @Controller
//@Api(tags = {"tile"})
public class TileController { public class TileController {
@Autowired @Autowired
...@@ -28,29 +43,20 @@ public class TileController { ...@@ -28,29 +43,20 @@ public class TileController {
@Autowired @Autowired
private ShortFilterService shortFilterService; private ShortFilterService shortFilterService;
private static final Logger LOG = LoggerFactory.getLogger(TileController.class); @RequestMapping(value = "/acn/tile/{zoom:\\d+}/{x:\\d+}/{y:\\d+}", produces = MediaType.IMAGE_PNG_VALUE)
public void tile(@RequestParam(value = "f", required = false, defaultValue="") String filterCode,
@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, @RequestParam(value = "color", required = false) String color,
@PathVariable("x") int x, @PathVariable("y") int y, @PathVariable("zoom") int zoom, @PathVariable("x") int x, @PathVariable("y") int y, @PathVariable("zoom") int zoom,
HttpServletResponse response) { HttpServletResponse response) throws IOException {
try {
AccessionFilter appliedFilters = shortFilterService.filterByCode(filterCode, AccessionFilter.class);
byte[] image = mappingService.getTile(appliedFilters, zoom, x, y); AccessionFilter appliedFilters = shortFilterService.filterByCode(filterCode, AccessionFilter.class);
image = ColorUtil.changeColor(color, image);
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=3600, s-maxage=3600, public, no-transform"); byte[] image = mappingService.getTile(appliedFilters, zoom, x, y);
response.getOutputStream().write(image, 0, image.length); image = ColorUtil.changeColor(color, image);
} 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());
}
response.setContentType(MediaType.IMAGE_PNG_VALUE);
response.setContentLength(image.length);
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=3600, s-maxage=3600, public, no-transform");
response.getOutputStream().write(image, 0, image.length);
} }
} }
...@@ -16,10 +16,6 @@ ...@@ -16,10 +16,6 @@
package org.genesys2.server.mvc; package org.genesys2.server.mvc;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
...@@ -34,7 +30,6 @@ import java.util.Map; ...@@ -34,7 +30,6 @@ import java.util.Map;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.TreeMap; import java.util.TreeMap;
import javax.imageio.ImageIO;
import javax.servlet.http.Cookie; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
...@@ -98,7 +93,6 @@ import org.springframework.web.bind.annotation.ResponseBody; ...@@ -98,7 +93,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.support.RequestContextUtils; import org.springframework.web.servlet.support.RequestContextUtils;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.jhlabs.image.MapColorsFilter;
@Controller @Controller
public class ExplorerController extends BaseController implements InitializingBean { public class ExplorerController extends BaseController implements InitializingBean {
...@@ -795,9 +789,11 @@ public class ExplorerController extends BaseController implements InitializingBe ...@@ -795,9 +789,11 @@ public class ExplorerController extends BaseController implements InitializingBe
try { try {
AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class); AppliedFilters appliedFilters = mapper.readValue(jsonFilter, AppliedFilters.class);
byte[] image = mappingService.getTile(appliedFilters, zoom, x, y); byte[] image = mappingService.getTile(AccessionFilter.convert(appliedFilters), zoom, x, y);
image = ColorUtil.changeColor(color, image); image = ColorUtil.changeColor(color, image);
response.setContentType(MediaType.IMAGE_PNG_VALUE);
response.setContentLength(image.length);
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=3600, s-maxage=3600, public, no-transform"); response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=3600, s-maxage=3600, public, no-transform");
response.getOutputStream().write(image, 0, image.length); response.getOutputStream().write(image, 0, image.length);
......
...@@ -18,15 +18,16 @@ package org.genesys2.server.service; ...@@ -18,15 +18,16 @@ package org.genesys2.server.service;
import java.util.List; import java.util.List;
import org.genesys.blocks.model.filters.BasicModelFilter;
import org.genesys2.server.model.elastic.AccessionDetails; import org.genesys2.server.model.elastic.AccessionDetails;
import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.service.filter.AccessionFilter;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters; import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
import org.genesys2.server.service.impl.GenesysFilterServiceImpl.LabelValue; import org.genesys2.server.service.impl.GenesysFilterServiceImpl.LabelValue;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.jdbc.core.RowCallbackHandler;
// TODO Deprecate
public interface GenesysFilterService { public interface GenesysFilterService {
Page<Accession> listAccessions(AppliedFilters filters, Pageable pageable); Page<Accession> listAccessions(AppliedFilters filters, Pageable pageable);
...@@ -42,7 +43,7 @@ public interface GenesysFilterService { ...@@ -42,7 +43,7 @@ public interface GenesysFilterService {
void listGeoTile(boolean distinct, AppliedFilters filters, Integer limit, int zoom, int xtile, int ytile, RowCallbackHandler rowHandler); 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); List<Double[]> listGeoTile(AccessionFilter filter, Integer limit, int zoom, int xtile, int ytile);
AppliedFilters transformFiltersIfNeed(AppliedFilters appliedFilters); AppliedFilters transformFiltersIfNeed(AppliedFilters appliedFilters);
} }
...@@ -20,7 +20,7 @@ import java.awt.Color; ...@@ -20,7 +20,7 @@ import java.awt.Color;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import org.genesys.blocks.model.filters.BasicModelFilter; import org.genesys2.server.service.filter.AccessionFilter;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters; import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
public interface MappingService { public interface MappingService {
...@@ -67,156 +67,5 @@ public interface MappingService { ...@@ -67,156 +67,5 @@ public interface MappingService {
* the ytile * the ytile
* @return the tile * @return the tile
*/ */
byte[] getTile(AppliedFilters filters, int zoom, int xtile, int ytile); byte[] getTile(AccessionFilter filter, int zoom, int xtile, int ytile);
byte[] getTile(BasicModelFilter filters, int zoom, int xtile, int ytile);
/**
* Coordinate utilities
*/
public static class CoordUtil {
/**
* Convert tile index at zoom level to longitude.
*
* @param zoom
* zoom level
* @param xtile
* tile index
* @return longitude of left side of tile
*/
public static double tileToLon(final int zoom, final int xtile) {
return 360.0 * xtile / (1 << zoom) - 180.0;
}
/**
* Convert tile index at zoom level to latitude
*
* @param zoom
* zoom level
* @param ytile
* tile index
* @return latitude of the top side of the tile
*/
public static double tileToLat(final int zoom, final int ytile) {
final double n = Math.PI - 2.0 * Math.PI * ytile / (1 << zoom);
return Math.toDegrees(Math.atan(Math.sinh(n)));
}
/**
* Lon to tile.
*
* @param zoom
* the zoom
* @param lon
* the lon
* @return the int
*/
public static int lonToTile(final int zoom, final double lon) {
return (int) Math.floor((lon + 180.0) / 360.0 * (1 << zoom));
}
/**
* Lat to tile.
*
* @param zoom
* the zoom
* @param lat
* the lat
* @return the int
*/
public static int latToTile(final int zoom, final double lat) {
final double latr = Math.toRadians(lat);
return (int) Math.floor((1 - Math.log(Math.tan(latr) + 1 / Math.cos(latr)) / Math.PI) / 2 * (1 << zoom));
}
/**
* Lon to img.
*
* @param zoom
* the zoom
* @param lon
* the lon
* @return the int
*/
public static int lonToImg(final int zoom, double lon) {
// n = 2 ^ zoom
final int xtile = lonToTile(zoom, lon);
final double a = tileToLon(zoom, xtile);
final double b = tileToLon(zoom, xtile + 1);
// System.err.println("a=" + a + " b=" + b);
// Translate to start of tile
lon -= a;
// Scale by (ba)*256;
// System.err.println("b-a="+(b-a));
lon = 256.0 * lon / (b - a);
return (int) Math.floor(lon);
}
/**
* Lat to img.
*
* @param zoom
* the zoom
* @param lat
* the lat
* @return the int
*/
public static int latToImg(final int zoom, double lat) {
// n = 2 ^ zoom
final int ytile = latToTile(zoom, lat);
// System.err.println("ytile=" + ytile);
final double a = tileToLat(zoom, ytile);
final double b = tileToLat(zoom, ytile + 1);
// System.err.println("a=" + a + " b=" + b);
// Translate to start of tile
lat -= a;
// Scale by (ba)*256;
// System.err.println("b-a=" + (b - a));
lat = 256.0 * lat / (b - a);
return (int) Math.floor(lat);
}
/**
* Mercator projection of decimal latitude to a y-pixel on tile at
* specific zoom level.
*
* @param zoom
* Zoom level
* @param tile
* Tile index
* @param lat
* Latitude
* @return the int
*/
public static int latToImg3(final int zoom, final int tile, double lat) {
lat = Math.min(85.0511287, Math.max(lat, -85.0511287));
final double pixAtZoom = (1 << zoom) * 256;
final double latr = Math.toRadians(lat);
final double y1 = Math.floor((1 - Math.log(Math.tan(latr) + 1 / Math.cos(latr)) / Math.PI) / 2 * pixAtZoom);
return (int) y1 - tile * 256;
}
/**
* Convert decimal longitude to an x-pixel on tile at specific zoom
* level.
*
* @param zoom
* Zoom level
* @param tile
* Tile index
* @param lng
* Longitude
* @return the int
*/
public static int lonToImg3(final int zoom, final int tile, final double lng) {
final double totalPixelsAtZoom = (1 << zoom) * 256;
final double longitudePixelAtZoom = Math.floor((180.0 + lng) / 360.0 * totalPixelsAtZoom);
return (int) (longitudePixelAtZoom - tile * 256);
}
}
} }
...@@ -28,7 +28,6 @@ import org.apache.commons.lang.ArrayUtils; ...@@ -28,7 +28,6 @@ import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.genesys2.server.model.genesys.Method; import org.genesys2.server.model.genesys.Method;
import org.genesys2.server.service.FilterConstants; import org.genesys2.server.service.FilterConstants;
import org.genesys2.server.service.MappingService.CoordUtil;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilter; import org.genesys2.server.service.impl.FilterHandler.AppliedFilter;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters; import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
import org.genesys2.server.service.impl.FilterHandler.FilterValue; import org.genesys2.server.service.impl.FilterHandler.FilterValue;
...@@ -37,6 +36,7 @@ import org.genesys2.server.service.impl.FilterHandler.MaxValueFilter; ...@@ -37,6 +36,7 @@ import org.genesys2.server.service.impl.FilterHandler.MaxValueFilter;
import org.genesys2.server.service.impl.FilterHandler.MinValueFilter; import org.genesys2.server.service.impl.FilterHandler.MinValueFilter;
import org.genesys2.server.service.impl.FilterHandler.StartsWithFilter; import org.genesys2.server.service.impl.FilterHandler.StartsWithFilter;
import org.genesys2.server.service.impl.FilterHandler.ValueRangeFilter; import org.genesys2.server.service.impl.FilterHandler.ValueRangeFilter;
import org.genesys2.util.CoordUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
......
...@@ -28,8 +28,10 @@ import java.util.stream.Collectors; ...@@ -28,8 +28,10 @@ import java.util.stream.Collectors;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.sql.DataSource; import javax.sql.DataSource;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.QueryResults; import com.querydsl.core.QueryResults;
import com.querydsl.core.Tuple; import com.querydsl.core.Tuple;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.JPQLQuery; import com.querydsl.jpa.JPQLQuery;
import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQuery;
import org.genesys.blocks.model.filters.BasicModelFilter; import org.genesys.blocks.model.filters.BasicModelFilter;
...@@ -52,6 +54,7 @@ import org.genesys2.server.service.impl.FilterHandler.AppliedFilter; ...@@ -52,6 +54,7 @@ import org.genesys2.server.service.impl.FilterHandler.AppliedFilter;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters; import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
import org.genesys2.server.service.impl.FilterHandler.FilterValue; import org.genesys2.server.service.impl.FilterHandler.FilterValue;
import org.genesys2.server.service.impl.FilterHandler.LiteralValueFilter; import org.genesys2.server.service.impl.FilterHandler.LiteralValueFilter;
import org.genesys2.util.CoordUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -387,6 +390,9 @@ public class GenesysFilterServiceImpl implements GenesysFilterService { ...@@ -387,6 +390,9 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
listGeoTile(false, filters, limit, -1, 0, 0, rowHandler); listGeoTile(false, filters, limit, -1, 0, 0, rowHandler);
} }
/**
* @deprecated Use {@link #listGeoTile(AccessionFilter, Integer, int, int, int)}
*/
@Override @Override
public void listGeoTile(final boolean distinct, AppliedFilters filters, Integer limit, int zoom, int xtile, int ytile, RowCallbackHandler rowHandler) { public void listGeoTile(final boolean distinct, AppliedFilters filters, Integer limit, int zoom, int xtile, int ytile, RowCallbackHandler rowHandler) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
...@@ -430,22 +436,43 @@ public class GenesysFilterServiceImpl implements GenesysFilterService { ...@@ -430,22 +436,43 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
} }
@Override @Override
// TODO check query - should be something like in the method above public List<Double[]> listGeoTile(AccessionFilter filter, Integer limit, int zoom, int xtile, int ytile) {
public List<Object[]> listGeoTile(BasicModelFilter filters, Integer limit, int zoom, int xtile, int ytile) {
QAccession accession = QAccession.accession; QAccession accession = QAccession.accession;
QAccessionGeo accessionGeo = accession.accessionId.geo;
// migrate functionality from DirectMysqlQuery.filterTile
JPQLQuery<Tuple> query = new JPAQuery<>(entityManager); JPQLQuery<Tuple> query = new JPAQuery<>(entityManager);
query.select(accession.accessionId.geo.longitude, accession.accessionId.geo.latitude).distinct().from(accession); query.select(accessionGeo.longitude, accessionGeo.latitude).distinct().from(accession);
query.where(filters.buildQuery());
BooleanBuilder filt = new BooleanBuilder();
if (filter != null) {
filt.and(filter.buildQuery());
}
// The tile query
{
final double lonW = CoordUtil.tileToLon(zoom, xtile);
final double lonE = CoordUtil.tileToLon(zoom, xtile + 1);
final double diffLon = lonE - lonW;
final double latN = CoordUtil.tileToLat(zoom, ytile);
final double latS = CoordUtil.tileToLat(zoom, ytile + 1);
final double diffLat = latN - latS;
if (LOG.isDebugEnabled()) {
LOG.debug("{} <= lon <= {} corr={}", lonW, lonE, diffLon * .2);
LOG.debug("{} <= lat <= {} corr={}", latS, latN, diffLat * .2);
}
filt.and(accessionGeo.longitude.between(lonW - zoom * diffLon * .2, lonE + zoom * diffLon * .2));
filt.and(accessionGeo.latitude.between(latS - zoom * diffLat * .2, latN + zoom * diffLat * .2));
}
query.where(filt);
QueryResults<Tuple> results = query.fetchResults(); QueryResults<Tuple> results = query.fetchResults();
return results.getResults().stream() return results.getResults().stream()
.map(item -> new Object[]{ .map(item -> new Double[]{
item.get(accession.accessionId.geo.longitude), item.get(accessionGeo.longitude),
item.get(accession.accessionId.geo.latitude), item.get(accessionGeo.latitude),
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
......
...@@ -30,7 +30,9 @@ import javax.imageio.ImageIO; ...@@ -30,7 +30,9 @@ import javax.imageio.ImageIO;
import org.genesys.blocks.model.filters.BasicModelFilter; import org.genesys.blocks.model.filters.BasicModelFilter;
import org.genesys2.server.service.GenesysFilterService; import org.genesys2.server.service.GenesysFilterService;
import org.genesys2.server.service.MappingService; import org.genesys2.server.service.MappingService;
import org.genesys2.server.service.filter.AccessionFilter;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters; import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
import org.genesys2.util.CoordUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -161,79 +163,7 @@ public class MappingServiceImpl implements MappingService { ...@@ -161,79 +163,7 @@ public class MappingServiceImpl implements MappingService {
@Override @Override
@Cacheable(value = "tileserver", key = "'tile-' + #zoom + '-' + #xtile + '-' + #ytile + '-' + #filters") @Cacheable(value = "tileserver", key = "'tile-' + #zoom + '-' + #xtile + '-' + #ytile + '-' + #filters")
public byte[] getTile(AppliedFilters filters, final int zoom, final int xtile, final int ytile) { public byte[] getTile(AccessionFilter filters, int zoom, int xtile, int ytile) {
filterService.transformFiltersIfNeed(filters);
final BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
// final int pixelSize = (int) Math.round(1.0 + (1 << (zoom / 2))) / 2;
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];
if (LOG.isDebugEnabled()) {
LOG.debug(filters.toString());
LOG.debug("PIXELSIZE={} zoom={}", pixelSize, zoom);
}
// // Border
// for (int i = 0; i < 256; i++) {
// bi.setRGB(0, i, Color.red.getRGB());
// bi.setRGB(i, 0, Color.red.getRGB());
// bi.setRGB(255, i, Color.red.getRGB());
// bi.setRGB(i, 255, Color.red.getRGB());
// }
final int colorWithoutAlpha = MappingService.DEFAULT_TILE_COLOR.getRGB();
filterService.listGeoTile(true, filters, null, zoom, xtile, ytile, new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
try {