Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/CrossSectionKMService.java @ 3785:a5f65e8983be
Merged revisions 5501-5502,5504-5508,5511-5513,5516-5519 via svnmerge from
file:///home/clients/bsh/bsh-generischer-viewer/Material/SVN/flys-artifacts/trunk
........
r5501 | felix | 2012-09-18 11:49:45 +0200 (Di, 18 Sep 2012) | 1 line
fix issue865 - missing showarea theme prop.
........
r5502 | clins | 2012-09-18 12:18:30 +0200 (Di, 18 Sep 2012) | 1 line
Add robustness checks to prevent NPEs
........
r5504 | felix | 2012-09-18 14:03:15 +0200 (Di, 18 Sep 2012) | 1 line
i18n for area label (fix issue487).
........
r5505 | clins | 2012-09-18 16:19:59 +0200 (Di, 18 Sep 2012) | 1 line
Update themes to show point descriptions
........
r5506 | rrenkert | 2012-09-18 17:00:30 +0200 (Di, 18 Sep 2012) | 3 lines
Removed incorrect characteristic diameter.
........
r5507 | rrenkert | 2012-09-18 17:03:20 +0200 (Di, 18 Sep 2012) | 3 lines
Fixed some stupid bugs in bed quality data factory and calculation.
........
r5508 | teichmann | 2012-09-18 17:45:49 +0200 (Di, 18 Sep 2012) | 1 line
The usual whitespace and import cleanups.
........
r5511 | teichmann | 2012-09-18 18:24:51 +0200 (Di, 18 Sep 2012) | 1 line
Use generics aware Collections.emptyList().
........
r5512 | teichmann | 2012-09-18 20:36:52 +0200 (Di, 18 Sep 2012) | 1 line
Some more little steps towards "Auslagerung extremer Wasserspiegellagen".
........
r5513 | clins | 2012-09-18 23:38:19 +0200 (Di, 18 Sep 2012) | 1 line
A and B facets of fix analyis are now deactivated by default
........
r5516 | bricks | 2012-09-19 10:45:51 +0200 (Mi, 19 Sep 2012) | 2 lines
Add the gauge station to the GaugeOverviewInfoService xml response
........
r5517 | rrenkert | 2012-09-19 10:50:23 +0200 (Mi, 19 Sep 2012) | 3 lines
Added CSV export to bed quality calculation.
........
r5518 | bricks | 2012-09-19 11:04:04 +0200 (Mi, 19 Sep 2012) | 2 lines
Fix date in changelog entry
........
r5519 | teichmann | 2012-09-19 11:17:14 +0200 (Mi, 19 Sep 2012) | 1 line
Removed trailing whitespace.
........
flys-artifacts/tags/2.9.1@5531 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Wed, 19 Sep 2012 14:58:31 +0000 |
parents | f021080cb409 |
children |
line wrap: on
line source
package de.intevation.flys.artifacts.services; import de.intevation.artifacts.CallMeta; import de.intevation.artifacts.GlobalContext; import de.intevation.artifacts.common.utils.XMLUtils; import de.intevation.flys.artifacts.cache.CacheFactory; import de.intevation.flys.backend.SessionHolder; import de.intevation.flys.model.CrossSection; import de.intevation.flys.model.CrossSectionLine; import java.util.AbstractMap; import java.util.ArrayDeque; import java.util.Deque; import java.util.List; import java.util.Map; import java.util.NavigableMap; import java.util.concurrent.ConcurrentSkipListMap; import net.sf.ehcache.Cache; import org.apache.log4j.Logger; import org.hibernate.Query; import org.hibernate.Session; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * Service to find the next/previous km (measurement) of cross sections. * Looking at the query for a single cross-section id at a single km, the * service does the following: * * It returns the km itself if a measurement at that km was found and * the N nearest other measurement points in both directions. * * That means, you can pass N=0 to find out whether a measurement at given km * exists. * * If less than N neighbours exist in one direction, less are delivered * (e.g. given measurements at [0,2,3,4,5,7,8,9] a query for km=8, N=3 will * result in [4,5,7,8,9]). */ public class CrossSectionKMService extends FLYSService { private static Logger logger = Logger.getLogger(CrossSectionKMService.class); public static final String CACHE_NAME = "cross-section-kms"; /** Trivial constructor. */ public CrossSectionKMService() { } /** * @param data */ @Override public Document doProcess( Document data, GlobalContext globalContext, CallMeta callMeta ) { logger.debug("CrossSectionKMService.doProcess"); NodeList crossSectionNodes = data.getElementsByTagName("art:cross-section"); Document document = XMLUtils.newDocument(); Element all = document.createElement("cross-sections"); for (int i = 0, CS = crossSectionNodes.getLength(); i < CS; ++i) { Element crossSectionElement = (Element)crossSectionNodes.item(i); String idString = crossSectionElement.getAttribute("id"); String kmString = crossSectionElement.getAttribute("km"); String neighborsString = crossSectionElement.getAttribute("n"); if (idString.length() == 0 || kmString.length() == 0) { logger.debug("missing attributes in cross-section element"); continue; } double km; Integer crossSectionId; int N = 2; try { km = Double.parseDouble(kmString); crossSectionId = Integer.valueOf(idString); if (neighborsString.length() > 0) { N = Integer.parseInt(neighborsString); } } catch (NumberFormatException nfe) { logger.debug("converting number failed", nfe); continue; } NavigableMap<Double, Integer> map = getKms(crossSectionId); if (map == null) { logger.debug("cannot find cross section " + crossSectionId); continue; } Deque<Map.Entry<Double, Integer>> result = nearestNeighbors(map, km, N); if (!result.isEmpty()) { Element csE = document.createElement("cross-section"); csE.setAttribute("id", idString); for (Map.Entry<Double, Integer> entry: result) { Element lineE = document.createElement("line"); lineE.setAttribute( "line-id", String.valueOf(entry.getValue())); lineE.setAttribute( "km", String.valueOf(entry.getKey())); csE.appendChild(lineE); } all.appendChild(csE); } } document.appendChild(all); return document; } public static NavigableMap<Double, Integer> getKms(int crossSectionId) { Cache cache = CacheFactory.getCache(CACHE_NAME); if (cache == null) { return getUncached(crossSectionId); } NavigableMap<Double, Integer> map; net.sf.ehcache.Element element = cache.get(crossSectionId); if (element == null) { map = getUncached(crossSectionId); if (map != null) { element = new net.sf.ehcache.Element( crossSectionId, map); cache.put(element); } } else { map = (NavigableMap<Double, Integer>)element.getValue(); } return map; } /** * @param km the kilometer from which to start searching for other * measurements * @param N number of neighboring measurements to find. */ public static Deque<Map.Entry<Double, Integer>> nearestNeighbors( NavigableMap<Double, Integer> map, double km, int N ) { Deque<Map.Entry<Double, Integer>> result = new ArrayDeque<Map.Entry<Double, Integer>>(2*N); Integer v = map.get(km); if (v != null) { result.add(new AbstractMap.SimpleEntry<Double, Integer>(km, v)); } int i = 0; for (Map.Entry<Double, Integer> entry: map.headMap(km, false).descendingMap().entrySet()) { if (i++ >= N) { break; } result.addFirst(entry); } i = 0; for (Map.Entry<Double, Integer> entry: map.tailMap(km, false).entrySet()) { if (i++ >= N) { break; } result.addLast(entry); } return result; } /** * @param crossSectionId id of queried cross-section (in db). * @return Mapping from kilometer to db-id. */ public static NavigableMap<Double, Integer> getUncached( Integer crossSectionId ) { NavigableMap<Double, Integer> result = new ConcurrentSkipListMap<Double, Integer>(); Session session = SessionHolder.HOLDER.get(); Query query = session.createQuery( "from CrossSection where id=:id"); query.setParameter("id", crossSectionId); List<CrossSection> crossSections = query.list(); if (crossSections.isEmpty()) { return null; } CrossSection crossSection = crossSections.get(0); List<CrossSectionLine> lines = crossSection.getLines(); for (CrossSectionLine line: lines) { Double km = line.getKm().doubleValue(); Integer id = line.getId(); result.put(km, id); } return result; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :