package com.c2c.controller; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import javax.imageio.ImageIO; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureCollections; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.map.DefaultMapContext; import org.geotools.map.MapContext; import org.geotools.map.MapLayer; import org.geotools.renderer.GTRenderer; import org.geotools.renderer.lite.StreamingRenderer; import org.geotools.styling.BasicPolygonStyle; import org.geotools.styling.Style; import org.geotools.styling.StyleBuilder; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.c2c.geoutils.ReferenceEnvelopeFactory; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.io.WKBReader; /** * The Controller for generating base layer maps, given a list of dimensions (levels). * <p/> * This class is registered as a bean in ws-servlet.xml. * * @author pmauduit */ @Controller @RequestMapping("/getbaselayer") public class GetBaseLayer extends AbstractQueryingController { private Style baseStyle; private String dbServer ; private String dbName ; private String dbUser ; private String dbPassword ; @RequestMapping(method = RequestMethod.GET) public void getbaselayer(HttpServletRequest request, HttpServletResponse response, @RequestParam("BBOX") String bbox, @RequestParam("WIDTH") int width, @RequestParam("HEIGHT") int height, @RequestParam(value = "SRS", required = false) String srs, @RequestParam(value = "FORMAT", required = false) String format) throws Exception { if (format == null) { format = "image/png"; } response.setContentType(format); StyleBuilder sb = new StyleBuilder(); baseStyle = new BasicPolygonStyle(sb.createFill(new Color(0xdedede)), sb.createStroke()); String pgRequest = ""; Class.forName("org.postgresql.Driver"); Connection c = null; c = DriverManager.getConnection("jdbc:postgresql://"+ dbServer + "/" + dbName, dbUser, dbPassword); try { ResultSet rs = null ; pgRequest = "SELECT ST_AsBinary(geom) FROM spatial_dimensions WHERE dimension_name = ?"; PreparedStatement prepStmt = c.prepareStatement(pgRequest); prepStmt.setString(1, "[NUTS].[NUTS LEVEL 0]"); rs = prepStmt.executeQuery(); FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection(); while (rs.next()) { WKBReader wkbr = new WKBReader() ; Geometry geom = wkbr.read(rs.getBytes(1)); SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); builder.add("the_geom", Geometry.class); builder.add("id",String.class); builder.add("data", String.class); builder.add("search", String.class); builder.setName("baselayer"); SimpleFeatureType bld = builder.buildFeatureType(); Object[] values = {geom}; SimpleFeature sf = SimpleFeatureBuilder.build(bld, values, "featureId"); collection.add(sf); // previously executed query should return only one column break; } ReferencedEnvelope bounds = ReferenceEnvelopeFactory.toReferencedEnvelope(bbox, srs == null ? "EPSG:4326" : srs); Rectangle imageSize = new Rectangle(width, height); renderMap(response, collection, bounds, imageSize, parseFormat(format)); } finally { c.close(); } } private String parseFormat(String format) { if (format == null) { return "png"; } String[] parts = format.split("/"); if (parts.length == 1) { return format; } return parts[1]; } private void renderMap(HttpServletResponse response, FeatureCollection feat, ReferencedEnvelope bounds, Rectangle imageSize, String format) throws IOException { MapLayer[] layers = {new MapLayer(feat,baseStyle)}; MapContext map = new DefaultMapContext(layers, bounds .getCoordinateReferenceSystem()); try { GTRenderer renderer = new StreamingRenderer(); renderer.setContext(map); BufferedImage image = new BufferedImage(imageSize.width, imageSize.height, BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = image.createGraphics(); graphics.setBackground(new Color(0xd6e4f1)); graphics.clearRect(0, 0, imageSize.width, imageSize.height); try { if (feat.getSchema().getGeometryDescriptor() == null) { graphics.setColor(Color.BLACK); int y = imageSize.height / 2; Font font = new Font(Font.SERIF, Font.BOLD, 14); graphics.setFont(font); graphics.drawString("Results have no geometries", 10, y - 14); } else { renderer.paint(graphics, imageSize, bounds); } ServletOutputStream output = response.getOutputStream(); try { ImageIO.write(image, format, output); } finally { output.close(); } } finally { graphics.dispose(); } } finally { map.dispose(); } } public void setDbName(String dbName) { this.dbName = dbName; } public void setDbUser(String dbUser) { this.dbUser = dbUser; } public void setDbPassword(String dbPassword) { this.dbPassword = dbPassword; } public void setDbServer(String dbServer) { this.dbServer = dbServer; } }