Java tutorial
/*---------------- FILE HEADER KALYPSO ------------------------------------------ * * This file is part of kalypso. * Copyright (C) 2004 by: * * Technical University Hamburg-Harburg (TUHH) * Institute of River and coastal engineering * Denickestrae 22 * 21073 Hamburg, Germany * http://www.tuhh.de/wb * * and * * Bjoernsen Consulting Engineers (BCE) * Maria Trost 3 * 56070 Koblenz, Germany * http://www.bjoernsen.de * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact: * * E-Mail: * belger@bjoernsen.de * schlienger@bjoernsen.de * v.doemming@tuhh.de * * ---------------------------------------------------------------------------*/ package org.kalypso.model.wspm.pdb.internal.gaf; import java.math.BigDecimal; import java.util.Date; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.eclipse.core.runtime.IProgressMonitor; import org.hibernate.Session; import org.kalypso.model.wspm.pdb.connect.IPdbOperation; import org.kalypso.model.wspm.pdb.connect.PdbConnectException; import org.kalypso.model.wspm.pdb.db.mapping.CrossSection; import org.kalypso.model.wspm.pdb.db.mapping.CrossSectionPart; import org.kalypso.model.wspm.pdb.db.mapping.CrossSectionPartType; import org.kalypso.model.wspm.pdb.db.mapping.Event; import org.kalypso.model.wspm.pdb.db.mapping.Point; import org.kalypso.model.wspm.pdb.db.mapping.Roughness; import org.kalypso.model.wspm.pdb.db.mapping.State; import org.kalypso.model.wspm.pdb.db.mapping.Vegetation; import org.kalypso.model.wspm.pdb.db.mapping.WaterBody; import org.kalypso.model.wspm.pdb.db.mapping.WaterlevelFixation; import org.kalypso.model.wspm.pdb.gaf.GafCode; import org.kalypso.model.wspm.pdb.gaf.GafKind; import org.kalypso.model.wspm.pdb.gaf.GafProfile; import org.kalypso.model.wspm.pdb.gaf.GafProfiles; import org.kalypso.model.wspm.pdb.internal.i18n.Messages; import org.kalypso.model.wspm.pdb.internal.utils.PDBNameGenerator; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.linearref.LinearLocation; import com.vividsolutions.jts.linearref.LocationIndexedLine; /** * Writes a gaf profile into the database. * * @author Gernot Belger */ public class Gaf2Db implements IPdbOperation { private final WaterBody m_waterBody; private final State m_state; private final GafProfiles m_profiles; private final IProgressMonitor m_monitor; private final String m_dbType; private final PDBNameGenerator m_sectionNameGenerator = new PDBNameGenerator(); private final Event m_waterlevelEvent; private final List<CrossSectionPartType> m_knownTypes; public Gaf2Db(final String dbType, final WaterBody waterBody, final State state, final GafProfiles profiles, final Event waterlevelEvent, final List<CrossSectionPartType> knownTypes, final IProgressMonitor monitor) { m_dbType = dbType; m_waterBody = waterBody; m_state = state; m_profiles = profiles; m_waterlevelEvent = waterlevelEvent; m_knownTypes = knownTypes; m_monitor = monitor; } @Override public String getLabel() { return Messages.getString("Gaf2Db.0"); //$NON-NLS-1$ } @Override public void execute(final Session session) throws PdbConnectException { try { final GafProfile[] profiles = m_profiles.getProfiles(); m_monitor.beginTask(Messages.getString("Gaf2Db.1"), profiles.length); //$NON-NLS-1$ if (m_waterlevelEvent != null) m_state.getEvents().add(m_waterlevelEvent); addState(session, m_state); commitWaterLevel(session); for (final GafProfile profile : profiles) { m_monitor.subTask(String.format(Messages.getString("Gaf2Db.2"), profile.getStation())); //$NON-NLS-1$ commitProfile(session, m_dbType, profile); m_monitor.worked(1); } m_monitor.subTask(Messages.getString("Gaf2Db.3")); //$NON-NLS-1$ } catch (final Exception e) { e.printStackTrace(); throw new PdbConnectException(Messages.getString("Gaf2Db.4"), e); //$NON-NLS-1$ } } public static void addState(final Session session, final State state) { final Date now = new Date(); state.setCreationDate(now); state.setEditingDate(now); if (session != null) session.save(state); } private void commitProfile(final Session session, final String dbType, final GafProfile profile) throws Exception { final CrossSection crossSection = commitCrossSection(session, dbType, profile); /* Get PP part */ final GafPart[] parts = profile.getParts(); final GafPart ppPart = profile.findPart(GafKind.P); /* add parts */ for (final GafPart gafPart : parts) { final PDBNameGenerator partNameGenerator = new PDBNameGenerator(); final CrossSectionPart csPart = commitPart(session, dbType, crossSection, gafPart, partNameGenerator); if (csPart == null) continue; final GafPoint[] points = gafPart.getPoints(); for (int j = 0; j < points.length; j++) { final PDBNameGenerator pointNameGenerator = new PDBNameGenerator(); final GafPoint gafPoint = points[j]; commitPoint(gafPart, session, csPart, gafPoint, j, pointNameGenerator, ppPart); } addWaterlevels(session, profile, gafPart); } } private CrossSection commitCrossSection(final Session session, final String dbType, final GafProfile profile) throws Exception { final CrossSection crossSection = new CrossSection(); final String protoName = String.format("%s", profile.getStation()); //$NON-NLS-1$ final String name = m_sectionNameGenerator.createUniqueName(protoName); crossSection.setName(name); crossSection.setState(m_state); crossSection.setWaterBody(m_waterBody); crossSection.setDescription(StringUtils.EMPTY); crossSection.setStation(profile.getStation()); /* Copy initial dates from state */ crossSection.setCreationDate(m_state.getCreationDate()); crossSection.setEditingDate(m_state.getEditingDate()); crossSection.setEditingUser(m_state.getEditingUser()); crossSection.setMeasurementDate(m_state.getMeasurementDate()); final Geometry line = profile.createLine(dbType); crossSection.setLine(line); session.save(crossSection); return crossSection; } private CrossSectionPart commitPart(final Session session, final String dbType, final CrossSection crossSection, final GafPart part, final PDBNameGenerator nameGenerator) throws Exception { final CrossSectionPart csPart = new CrossSectionPart(); final GafKind partKind = part.getKind(); final String name = nameGenerator.createUniqueName(partKind.toString()); csPart.setName(name); if (part.getKind() == GafKind.W) { final String gafFileName = m_profiles.getGafFilename(); csPart.setDescription(String.format(Messages.getString("Gaf2Db.5"), gafFileName)); //$NON-NLS-1$ } else csPart.setDescription(StringUtils.EMPTY); final CrossSectionPartType partType = findPartType(partKind); csPart.setCrossSectionPartType(partType); final Geometry line = part.getLine(dbType); csPart.setLine(line); csPart.setCrossSection(crossSection); session.save(csPart); return csPart; } private CrossSectionPartType findPartType(final GafKind partKind) { for (final CrossSectionPartType type : m_knownTypes) { if (type.getCategory().equals(partKind.toString())) return type; } throw new IllegalArgumentException(String.format("Unknown part category: %s", partKind)); //$NON-NLS-1$ } private void commitPoint(final GafPart gafPart, final Session session, final CrossSectionPart csPart, final GafPoint gafPoint, final int index, final PDBNameGenerator nameGenerator, final GafPart projectionPart) { final Point point = new Point(); point.setCrossSectionPart(csPart); final GafCode code = gafPoint.getCode(); final GafCode hyk = gafPoint.getHyk(); /* Using pointID from gaf, but force it to be unique within each part */ final String name = nameGenerator.createUniqueName(gafPoint.getPointId()); final com.vividsolutions.jts.geom.Point location = gafPoint.getPoint(); final BigDecimal width = getOrCalculatePoint(gafPart, gafPoint, projectionPart); /* Write data into db point */ point.setName(name); point.setDescription(StringUtils.EMPTY); point.setConsecutiveNum(index); point.setHeight(gafPoint.getHeight()); point.setWidth(width); point.setHyk(hyk.getHyk()); point.setCode(code.getCode()); point.setLocation(location); final Roughness roughness = gafPoint.getRoughnessClass(); point.setRoughness(roughness); // REMARK: we do not resolve the values here, because a set values means 'overwritten' // point.setRoughnessKstValue( roughness.getKstValue() ); // point.setRoughnessKValue( roughness.getKValue() ); final Vegetation vegetation = gafPoint.getVegetationClass(); if (vegetation == null) { System.out.println(); } point.setVegetation(vegetation); // REMARK: we do not resolve the values here, because a set values means 'overwritten' // point.setVegetationAx( vegetation.getAx() ); // point.setVegetationAy( vegetation.getAy() ); // point.setVegetationDp( vegetation.getDp() ); session.save(point); } /** * Calculates the width of a point if it is not set in the gaf file.<br/> * For PP points, it is just the distance to the first point.<br/> * For non-pp points, it is the station of the point projected to the pp-line. */ private BigDecimal getOrCalculatePoint(final GafPart gafPart, final GafPoint gafPoint, final GafPart projectionPart) { final BigDecimal width = gafPoint.getWidth(); if (width != null) return width; final com.vividsolutions.jts.geom.Point location = gafPoint.getPoint(); if (GafKind.P.equals(gafPart.getKind()) || projectionPart == null) { return calculateWidthFromDistance(gafPart, location); } else { final Geometry line = projectionPart.getLine(m_dbType); if (!(line instanceof LineString) || line.getNumPoints() < 2) return calculateWidthFromDistance(gafPart, location); final LineString ls = (LineString) line; final LocationIndexedLine lineRef = new LocationIndexedLine(line); final LinearLocation loc = lineRef.project(location.getCoordinate()); final Coordinate closestPt = loc.getCoordinate(line); final double distance = ls.getCoordinateN(0).distance(closestPt); return new BigDecimal(distance).setScale(3, BigDecimal.ROUND_HALF_UP); } } private BigDecimal calculateWidthFromDistance(final GafPart gafPart, final com.vividsolutions.jts.geom.Point location) { final GafPoint startPoint = gafPart.getPoints()[0]; final com.vividsolutions.jts.geom.Point startLocation = startPoint.getPoint(); if (location == null || startLocation == null) return null; final double distance = location.distance(startLocation); return new BigDecimal(distance).setScale(3, BigDecimal.ROUND_HALF_UP); } private void addWaterlevels(final Session session, final GafProfile profile, final GafPart part) { if (m_waterlevelEvent == null) return; final GafKind kind = part.getKind(); if (!GafKind.W.equals(kind)) return; final GafPoint[] points = part.getPoints(); for (final GafPoint point : points) { final WaterlevelFixation fixation = new WaterlevelFixation(); fixation.setEvent(m_waterlevelEvent); fixation.setDescription(StringUtils.EMPTY); fixation.setCreationDate(m_waterlevelEvent.getCreationDate()); fixation.setEditingDate(m_waterlevelEvent.getEditingDate()); fixation.setEditingUser(m_waterlevelEvent.getEditingUser()); fixation.setMeasurementDate(m_waterlevelEvent.getMeasurementDate()); fixation.setLocation(point.getPoint()); fixation.setStation(profile.getStation()); fixation.setWaterlevel(point.getHeight()); m_waterlevelEvent.getWaterlevelFixations().add(fixation); session.save(fixation); } } private void commitWaterLevel(final Session session) { if (m_waterlevelEvent != null) { m_waterlevelEvent.setCreationDate(m_state.getCreationDate()); m_waterlevelEvent.setEditingDate(m_state.getEditingDate()); m_waterlevelEvent.setEditingUser(m_state.getEditingUser()); m_waterlevelEvent.setMeasurementDate(m_state.getMeasurementDate()); m_waterlevelEvent.setWaterBody(m_waterBody); m_waterlevelEvent.setState(m_state); session.save(m_waterlevelEvent); } } }