Mercurial > dive4elements > river
view flys-client/src/main/java/de/intevation/flys/client/server/GFIServiceImpl.java @ 5818:a4ff4167be1e
Request feature info on all layers and show it as html if
the server does not return valid gml.
Non queryable layers produce an error message when the request
fails. This is good enough
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Wed, 24 Apr 2013 17:33:27 +0200 |
parents | af2aa716152f |
children |
line wrap: on
line source
package de.intevation.flys.client.server; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.apache.log4j.Logger; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import de.intevation.artifacts.common.utils.XMLUtils; import de.intevation.flys.client.shared.exceptions.ServerException; import de.intevation.flys.client.shared.model.AttributedTheme; import de.intevation.flys.client.shared.model.FeatureInfo; import de.intevation.flys.client.shared.model.FeatureInfoResponse; import de.intevation.flys.client.shared.model.Theme; import de.intevation.flys.client.client.services.GFIService; /** * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> */ public class GFIServiceImpl extends RemoteServiceServlet implements GFIService { public static final String ERR_NO_VALID_GFI_URL = "error_no_valid_gfi_url"; public static final String ERR_GFI_REQUEST_FAILED = "error_gfi_req_failed"; public static final String ERR_PARSING_RESPONSE_FAILED = "error_gfi_parsing_failed"; private static final Logger logger = Logger.getLogger(GFIServiceImpl.class); /** * @param theme * @param format * @param bbox * @param height * @param width * @param x * @param y * * @return */ public FeatureInfoResponse query( Theme theme, String format, String bbox, String projection, int height, int width, int x, int y ) throws ServerException { logger.info("GFIServiceImpl.query"); String path = createGetFeautureInfoURL( theme, format, bbox, projection, height, width, x, y); logger.debug("URL=" + path); try { URL url = new URL(path); URLConnection conn = url.openConnection(); conn.connect(); InputStream is = conn.getInputStream(); return parseResponse(is); } catch (IOException ioe) { logger.warn(ioe, ioe); } throw new ServerException(ERR_GFI_REQUEST_FAILED); } /** * @param map * @param theme * @param format * @param x * @param y * * @return */ protected String createGetFeautureInfoURL( Theme theme, String infoFormat, String bbox, String projection, int height, int width, int x, int y ) throws ServerException { String url = getUrl(theme); if (url == null || url.length() == 0) { throw new ServerException(ERR_NO_VALID_GFI_URL); } String layers = ((AttributedTheme)theme).getAttr("layers"); StringBuilder sb = new StringBuilder(); sb.append(url); if (url.indexOf("?") < 0) { sb.append("?SERVICE=WMS"); } else { sb.append("&SERVICE=WMS"); } sb.append("&VERSION=1.1.1"); sb.append("&REQUEST=GetFeatureInfo"); sb.append("&LAYERS=" + layers); sb.append("&QUERY_LAYERS=" + layers); sb.append("&BBOX=" + bbox); sb.append("&HEIGHT=" + height); sb.append("&WIDTH=" + width); sb.append("&FORMAT=image/png"); sb.append("&INFO_FORMAT=" + infoFormat); sb.append("&SRS=" + projection); sb.append("&X=" + String.valueOf(x)); sb.append("&Y=" + String.valueOf(y)); return sb.toString(); } protected String getUrl(Theme theme) { AttributedTheme attr = (AttributedTheme) theme; return attr.getAttr("url"); } protected FeatureInfoResponse parseResponse(InputStream is) { logger.debug("GFIServiceImpl.parseResponse"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte [] buf = new byte[1024]; int r = -1; try { while ((r = is.read(buf)) >= 0) { baos.write(buf, 0, r); } } catch (IOException ex) { logger.warn("GetFeatureInfo response could not be read: ", ex); return new FeatureInfoResponse(); } String content; try { content = baos.toString("UTF-8"); } catch (UnsupportedEncodingException uee) { content = baos.toString(); } Document response = XMLUtils.parseDocument(content); if (response != null) { List<FeatureInfo> features = new ArrayList<FeatureInfo>(); parseFeatureInfos(response, features); return new FeatureInfoResponse(features, null); } // Unable to parse just return the response as is return new FeatureInfoResponse(new ArrayList<FeatureInfo>(), content); } protected void parseFeatureInfos(Node node, List<FeatureInfo> features) { logger.debug("GFIServiceImpl.parseFeatureInfos"); String name = node.getNodeName(); if (name.endsWith("_layer")) { features.add(parseFeature(node)); return; } NodeList children = node.getChildNodes(); if (children != null && children.getLength() > 0) { for (int i = 0, n = children.getLength(); i < n; i++) { parseFeatureInfos(children.item(i), features); } } } protected FeatureInfo parseFeature(Node node) { logger.debug("GFIServiceImpl.parseFeature"); String layername = node.getNodeName(); FeatureInfo f = new FeatureInfo(layername); NodeList children = node.getChildNodes(); int numChildren = children != null ? children.getLength() : 0; logger.debug("Feature '" + layername + "' has " + numChildren + " nodes."); for (int i = 0; i < numChildren; i++) { Node tmp = children.item(i); String nodeName = tmp.getNodeName(); logger.debug(" node name: '" + nodeName + "'"); if (nodeName.equals("gml:name")) { logger.debug("NAME node has child: " + tmp.getFirstChild().getNodeValue()); f.setLayername(tmp.getFirstChild().getNodeValue()); } else if (nodeName.endsWith("_feature")) { parseFeatureAttributes(tmp, f); } } return f; } protected void parseFeatureAttributes(Node node, FeatureInfo f) { logger.debug("GFIServiceImpl.parseFeatureAttributes"); NodeList children = node.getChildNodes(); int numChildren = children != null ? children.getLength() : 0; logger.debug("Has " + numChildren + " attributes."); for (int i = 0; i < numChildren; i++) { Node tmp = children.item(i); String name = tmp.getNodeName(); logger.debug(" tmp attribute name: '" + name + "'"); if (name.equals("gml:boundedBy")) { // TODO } else { Node child = tmp.getFirstChild(); if (child != null) { f.addAttr(name, child.getNodeValue()); } } } } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :