r372 - in trunk: sammoa-application sammoa-application/src/main/java/fr/ulr/sammoa/application/map sammoa-application/src/main/resources/i18n sammoa-application/src/test/java/fr/ulr/sammoa/application sammoa-application/src/test/java/fr/ulr/sammoa/application/map sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util
Author: fdesbois Date: 2012-08-08 20:26:09 +0200 (Wed, 08 Aug 2012) New Revision: 372 Url: http://forge.codelutin.com/repositories/revision/sammoa/372 Log: refs #1203 : implement Shp export for Flight GeoPoints Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfColumnModel.java trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfImport.java trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfTableModelBuilder.java trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfTimestampConverter.java trunk/sammoa-application/src/test/java/fr/ulr/sammoa/application/map/ trunk/sammoa-application/src/test/java/fr/ulr/sammoa/application/map/DbfTimestampConverterTest.java trunk/sammoa-application/src/test/java/fr/ulr/sammoa/application/map/ExportMapServiceTest.java Removed: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/DbfImport.java Modified: trunk/sammoa-application/pom.xml trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/ExportMapService.java trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/ShpImporter.java Modified: trunk/sammoa-application/pom.xml =================================================================== --- trunk/sammoa-application/pom.xml 2012-08-08 16:50:09 UTC (rev 371) +++ trunk/sammoa-application/pom.xml 2012-08-08 18:26:09 UTC (rev 372) @@ -88,6 +88,11 @@ <artifactId>nuiton-csv</artifactId> </dependency> + <dependency> + <groupId>com.bbn</groupId> + <artifactId>openmap</artifactId> + </dependency> + <!-- test dependencies --> <dependency> <groupId>junit</groupId> Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfColumnModel.java =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfColumnModel.java (rev 0) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfColumnModel.java 2012-08-08 18:26:09 UTC (rev 372) @@ -0,0 +1,62 @@ +package fr.ulr.sammoa.application.map; + +import com.bbn.openmap.dataAccess.shape.DbfTableModel; + +/** + * Note: there is an existing {@link com.bbn.openmap.dataAccess.shape.DbfTableModelFactory.Column} + * class. + * <p/> + * Created: 07/08/12 + * + * @author fdesbois <florian.desbois@codelutin.com> + */ +public class DbfColumnModel { + + protected String name; + + protected byte type; + + protected int length; + + protected byte decimalCount; + + protected int index; + + public DbfColumnModel(String name, byte type) { + this.name = name; + this.type = type; + this.index = -1; + } + + public String getName() { + return name; + } + + public byte getType() { + return type; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getDecimalCount() { + return decimalCount; + } + + public void setDecimalCount(int decimalCount) { + this.decimalCount = (byte) decimalCount; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } +} Property changes on: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfColumnModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfImport.java (from rev 371, trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/DbfImport.java) =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfImport.java (rev 0) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfImport.java 2012-08-08 18:26:09 UTC (rev 372) @@ -0,0 +1,129 @@ +package fr.ulr.sammoa.application.map; +/* + * #%L + * SAMMOA :: UI Swing + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 UMS 3462, Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.bbn.openmap.dataAccess.shape.DbfTableModel; +import com.google.common.base.Throwables; +import com.google.common.collect.Lists; +import org.nuiton.util.csv.Import; +import org.nuiton.util.csv.ImportModel; +import org.nuiton.util.csv.ImportRuntimeException; +import org.nuiton.util.csv.ImportableColumn; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.Reader; +import java.net.URL; +import java.util.Iterator; +import java.util.List; + +import static org.nuiton.i18n.I18n._; + +/** + * Created: 25/07/12 + * + * @author fdesbois <desbois@codelutin.com> + */ +public class DbfImport<E> extends Import<E> { + + private static final Logger logger = LoggerFactory.getLogger(DbfImport.class); + + protected DbfTableModel source; + + protected Iterator<List<Object>> records; + + protected List<Object> record; + + public DbfImport(ImportModel<E> model, URL fileUrl) { + // Use dummy reader for superclass Import that manage by default csv files + super(model, new Reader() { + + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + return -1; + } + + @Override + public void close() throws IOException { + } + }); + + try { + // FIXME-fdesbois-2012-07-26 : there is an issue with encoding, don't know how to customize it + this.source = DbfTableModel.read(fileUrl); + + } catch (Exception e) { + throw Throwables.propagate(e); + } + this.records = source.getRecords(); + } + + @Override + protected <T> String readValue(ImportableColumn<E, T> field, int lineNumber) { + try { + + int columnNumber = source.getColumnIndexForName(field.getHeaderName()); + + String value = String.valueOf(record.get(columnNumber)); + + return value; + + } catch (Exception e) { + throw new ImportRuntimeException( + _("csv.import.error.unableToReadField", + field.getHeaderName(), lineNumber), e); + } + } + + @Override + public void close() { + // nothing to do + } + + @Override + protected boolean readRow() throws ImportRuntimeException { + boolean result; + if (records.hasNext()) { + record = records.next(); + if (logger.isTraceEnabled()) { + logger.trace("Read record {}", record); + } + result = true; + + } else { + result = false; + } + return result; + } + + @Override + protected String[] getHeaders() throws ImportRuntimeException { + List<String> list = Lists.newArrayList(); + for (int index = 0; index < source.getColumnCount(); index++) { + list.add(source.getColumnName(index)); + } + return list.toArray(new String[list.size()]); + } +} Property changes on: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfImport.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfTableModelBuilder.java =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfTableModelBuilder.java (rev 0) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfTableModelBuilder.java 2012-08-08 18:26:09 UTC (rev 372) @@ -0,0 +1,178 @@ +package fr.ulr.sammoa.application.map; + +import com.bbn.openmap.dataAccess.shape.DbfTableModel; +import com.google.common.base.Function; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * Created: 07/08/12 + * + * @author fdesbois <florian.desbois@codelutin.com> + */ +public class DbfTableModelBuilder { + + public static final int DEFAULT_STRING_LENGTH = 64; + + public static final int DEFAULT_INTEGER_LENGTH = 8; + + public static final String DATE_FORMAT_PATTERN = "yyyyMMdd"; + + public static final DateFormat DATE_FORMAT = new SimpleDateFormat(DATE_FORMAT_PATTERN); + + protected List<DbfColumnModel> columns; + + protected Map<String, DbfColumnModel> columnMap; + + protected DbfTableModel model; + + public DbfTableModelBuilder() { + columns = Lists.newArrayList(); + } + + public DbfTableModelBuilder dbfColumn(DbfColumnModel column) { + if (column.getIndex() != -1) { + columns.add(column.getIndex(), column); + } else { + column.setIndex(columns.size()); + columns.add(column); + } + return this; + } + + public DbfColumnModel newStringColumn(String name) { + DbfColumnModel result = new DbfColumnModel(name, DbfTableModel.TYPE_CHARACTER); + result.setLength(DEFAULT_STRING_LENGTH); + return result; + } + + public DbfColumnModel newIntegerColumn(String name) { + DbfColumnModel result = new DbfColumnModel(name, DbfTableModel.TYPE_NUMERIC); + result.setLength(DEFAULT_INTEGER_LENGTH); + return result; + } + + public DbfColumnModel newDoubleColumn(String name, int length, int decimalCount) { + DbfColumnModel result = new DbfColumnModel(name, DbfTableModel.TYPE_NUMERIC); + result.setLength(length); + result.setDecimalCount(decimalCount); + return result; + } + + public DbfColumnModel newTimestampColumn(String name) { + DbfColumnModel result = new DbfColumnModel(name, DbfTableModel.TYPE_TIMESTAMP); + return result; + } + + public DbfColumnModel newDateColumn(String name) { + DbfColumnModel result = new DbfColumnModel(name, DbfTableModel.TYPE_DATE); + result.setLength(DATE_FORMAT_PATTERN.length()); + return result; + } + + public DbfTableModelBuilder stringColumn(String name) { + return dbfColumn(newStringColumn(name)); + } + + public DbfTableModelBuilder integerColumn(String name) { + return dbfColumn(newIntegerColumn(name)); + } + + public DbfTableModelBuilder doubleColumn(String name, int length, int decimalCount) { + return dbfColumn(newDoubleColumn(name, length, decimalCount)); + } + + public DbfTableModelBuilder timestampColumn(String name) { + return dbfColumn(newTimestampColumn(name)); + } + + public DbfTableModelBuilder dateColumn(String name) { + return dbfColumn(newDateColumn(name)); + } + + public DbfTableModelBuilder build() { + model = new DbfTableModel(columns.size()); + model.setWritable(true); + + for (int i = 0; i < columns.size(); i++) { + DbfColumnModel columnModel = columns.get(i); + model.setColumnName(i, columnModel.getName()); + model.setType(i, columnModel.getType()); + model.setLength(i, columnModel.getLength()); + model.setDecimalCount(i, (byte) columnModel.getDecimalCount()); + } + columnMap = Maps.uniqueIndex(columns, + new Function<DbfColumnModel, String>() { + + @Override + public String apply(DbfColumnModel input) { + return input.getName(); + } + }); + return this; + } + + public DbfTableModel getModel() { + return model; + } + + public void setValue(int rowIndex, String columnName, Object value) { + Preconditions.checkState(model != null, "Model must be built before setting values"); + + DbfColumnModel column = columnMap.get(columnName); + + int columnIndex = column.getIndex(); + value = cleanValue(value, column.getType()); + model.setValueAt(value, rowIndex, columnIndex); + } + + public int addValues(Map<String, Object> values) { + Preconditions.checkState(model != null, "Model must be built before adding values"); + + model.addBlankRecord(); + int rowIndex = model.getRowCount() - 1; + for (Map.Entry<String, Object> entry : values.entrySet()) { + setValue(rowIndex, entry.getKey(), entry.getValue()); + } + return rowIndex; + } + + protected Object cleanValue(Object value, byte type) { + + Object result = value; + if (DbfTableModel.isNumericalType(type)) { + + // FIX for Integer Format error in DbfTableModel#getStringForType + if (value instanceof Integer) { + result = Double.valueOf(String.valueOf(value)); + } + } + else if (DbfTableModel.TYPE_TIMESTAMP == type) { + + // FIX for Date : no format is done + if (value instanceof Date) { + Date date = (Date) value; + + result = DbfTimestampConverter.toString(date); + } + } + else if (DbfTableModel.TYPE_DATE == type) { + + // FIX for Date : no format is done + if (value instanceof Date) { + Date date = (Date) value; + + result = DATE_FORMAT.format(date); + } + } + return result; + } + +} Property changes on: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfTableModelBuilder.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfTimestampConverter.java =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfTimestampConverter.java (rev 0) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfTimestampConverter.java 2012-08-08 18:26:09 UTC (rev 372) @@ -0,0 +1,92 @@ +package fr.ulr.sammoa.application.map; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import org.nuiton.util.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +/** + * Created: 08/08/12 + * + * @author fdesbois <florian.desbois@codelutin.com> + */ +public final class DbfTimestampConverter { + + protected static final Long HOUR_MULT = 3600000L; + protected static final Long MINUTE_MULT = 60000L; + protected static final Long SECOND_MULT = 1000L; + + + private static final Logger logger = LoggerFactory.getLogger(DbfTimestampConverter.class); + + private DbfTimestampConverter() { + // static class + } + + public static String toString(Date date) { + + Calendar calendar = new GregorianCalendar(); + calendar.setTime(date); + + Calendar refCalendar = getReferenceCalendar(); + + long dateValue = DateUtil.getDifferenceInDays(refCalendar.getTime(), date); + long timeValue = calendar.get(Calendar.HOUR_OF_DAY) * HOUR_MULT + + calendar.get(Calendar.MINUTE) * MINUTE_MULT + + calendar.get(Calendar.SECOND) * SECOND_MULT; + + String result = dateValue + " " + timeValue; + return result; + } + + public static Date toDate(String timestamp) { + Preconditions.checkArgument(Strings.nullToEmpty(timestamp).trim().contains(" "), + "A space is missing between the date and time values"); + + String[] values = timestamp.split(" "); + + Long dateValue = Long.parseLong(values[0]); + Long timeValue = Long.parseLong(values[1]); + + Calendar refCalendar = getReferenceCalendar(); + + Calendar resultCalendar = new GregorianCalendar(); + resultCalendar.setTime(refCalendar.getTime()); + + resultCalendar.add(Calendar.DATE, dateValue.intValue()); + + Long hours = timeValue / HOUR_MULT; + Long timeWithoutHours = timeValue - hours * HOUR_MULT; + Long minutes = timeWithoutHours / MINUTE_MULT; + Long seconds = (timeWithoutHours - minutes * MINUTE_MULT) / SECOND_MULT; + + resultCalendar.set(Calendar.HOUR_OF_DAY, hours.intValue()); + resultCalendar.set(Calendar.MINUTE, minutes.intValue()); + resultCalendar.set(Calendar.SECOND, seconds.intValue()); + + if (logger.isDebugEnabled()) { + logger.debug(String.format("DateValue=%d, TimeValue=%d, Hours=%d, Minutes=%d, Seconds=%d, Result=%s", + dateValue, + timeValue, + hours, + minutes, + seconds, + resultCalendar) + ); + } + + return resultCalendar.getTime(); + } + + private static Calendar getReferenceCalendar() { + Calendar result = new GregorianCalendar(4713, 0, 1); + result.set(Calendar.ERA, GregorianCalendar.BC); + return result; + } + +} Property changes on: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/DbfTimestampConverter.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/ExportMapService.java =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/ExportMapService.java 2012-08-08 16:50:09 UTC (rev 371) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/map/ExportMapService.java 2012-08-08 18:26:09 UTC (rev 372) @@ -23,12 +23,34 @@ * #L% */ +import com.bbn.openmap.dataAccess.shape.DbfTableModel; +import com.bbn.openmap.dataAccess.shape.EsriGraphicList; +import com.bbn.openmap.dataAccess.shape.EsriPointList; +import com.bbn.openmap.dataAccess.shape.EsriShapeExport; +import com.bbn.openmap.omGraphics.OMGraphic; +import com.bbn.openmap.omGraphics.OMPoint; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; import fr.ulr.sammoa.application.SammoaConfig; import fr.ulr.sammoa.application.SammoaContext; +import fr.ulr.sammoa.persistence.Campaign; +import fr.ulr.sammoa.persistence.Flight; +import fr.ulr.sammoa.persistence.GeoPoint; +import fr.ulr.sammoa.persistence.Region; import fr.ulr.sammoa.persistence.SammoaPersistence; +import org.nuiton.util.PeriodDates; +import org.nuiton.util.TimeLog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; + /** * Export map service * @@ -40,16 +62,21 @@ private static final Logger logger = LoggerFactory.getLogger(ExportMapService.class); + private static final TimeLog timeLog = new TimeLog(ExportMapService.class); + protected SammoaContext context; protected SammoaConfig config; protected SammoaPersistence persistence; + protected DateFormat timeFormat; + public ExportMapService(SammoaContext context) { this.context = context; this.persistence = context.getPersistence(); this.config = context.getConfig(); + this.timeFormat = new SimpleDateFormat("HHmmss"); } public void exportEffortsMap(ExportMapModel dataModel) { @@ -84,10 +111,90 @@ dataModel.getExportDirectory() + "::" + dataModel.getExportFilename()); } - try { - Thread.sleep(1000); - } catch (InterruptedException e) { + long startTime = TimeLog.getTime(); + + Campaign campaign = dataModel.getCampaign(); + Region region = campaign.getRegion(); + + DbfTableModelBuilder builder = new DbfTableModelBuilder() + .stringColumn("REGION") + .stringColumn("CAMPAIGN") + .integerColumn("FLIGHT") + .stringColumn("COMPUTER") + .dateColumn("DATE") + .stringColumn("HHMMSS") + .doubleColumn("LAT", 19, 11) + .doubleColumn("LON", 19, 11) + .doubleColumn("SPEED", 19, 11) + .doubleColumn("ALTITUDE", 19, 11) + .build(); + + EsriGraphicList graphicList = new EsriPointList(); + List<Flight> campaignFlights = context.getFlightService().getFlights(dataModel.getCampaign()); + + // Filter on period + Date beginDate = dataModel.getBeginDate() == null ? campaign.getBeginDate() : dataModel.getBeginDate(); + Date endDate = dataModel.getEndDate() == null ? campaign.getEndDate() : dataModel.getEndDate(); + final PeriodDates period = new PeriodDates(beginDate, endDate); + Iterable<Flight> flights = Iterables.filter(campaignFlights, new Predicate<Flight>() { + + @Override + public boolean apply(Flight input) { + return period.between(input.getBeginDate()); + } + }); + + // Export for each flight + Map<String, Object> record = Maps.newHashMap(); + for (Flight flight : flights) { + + if (logger.isInfoEnabled()) { + logger.info(String.format("Export GeoPoints from flight %d - %s - %s - %s", + flight.getFlightNumber(), + flight.getSystemId(), + campaign.getCode(), + region.getCode()) + ); + } + + List<GeoPoint> geoPoints = context.getFlightService().getFlightGeoPoints(flight); + + // One record by GeoPoint + for (GeoPoint geoPoint : geoPoints) { + + record.clear(); + + record.put("REGION", region.getCode()); + record.put("CAMPAIGN", campaign.getCode()); + record.put("FLIGHT", flight.getFlightNumber()); + record.put("COMPUTER", flight.getSystemId()); + record.put("DATE", geoPoint.getRecordTime()); + record.put("HHMMSS", timeFormat.format(geoPoint.getRecordTime())); + record.put("LAT", geoPoint.getLatitude()); + record.put("LON", geoPoint.getLongitude()); + record.put("SPEED", geoPoint.getSpeed()); + record.put("ALTITUDE", geoPoint.getAltitude()); + + builder.addValues(record); + + if (logger.isTraceEnabled()) { + logger.trace("Record={}", record); + } + + OMGraphic graphic = new OMPoint(geoPoint.getLatitude(), geoPoint.getLongitude()); + graphicList.add(graphic); + } } + + startTime = timeLog.log(startTime, "exportGeoPointsMap", "after building EsriGraphicList and DbfTableModel"); + + // Execute export with EsriShapeExport + DbfTableModel tableModel = builder.getModel(); + String pathFile = new File(dataModel.getExportDirectory(), dataModel.getExportFilename()).getAbsolutePath(); + EsriShapeExport shapeExport = new EsriShapeExport(graphicList, tableModel, pathFile); + shapeExport.export(); + + timeLog.log(startTime, "exportGeoPointsMap", "after EsriShapeExport execution"); } } Modified: trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties =================================================================== --- trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties 2012-08-08 16:50:09 UTC (rev 371) +++ trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties 2012-08-08 18:26:09 UTC (rev 372) @@ -1,3 +1,4 @@ +csv.import.error.unableToReadField= sammoa.config.admin.email=Administrator's email sammoa.config.application.site.url=Website URL of the application sammoa.config.application.version=Version of the application Added: trunk/sammoa-application/src/test/java/fr/ulr/sammoa/application/map/DbfTimestampConverterTest.java =================================================================== --- trunk/sammoa-application/src/test/java/fr/ulr/sammoa/application/map/DbfTimestampConverterTest.java (rev 0) +++ trunk/sammoa-application/src/test/java/fr/ulr/sammoa/application/map/DbfTimestampConverterTest.java 2012-08-08 18:26:09 UTC (rev 372) @@ -0,0 +1,32 @@ +package fr.ulr.sammoa.application.map; + +import junit.framework.Assert; +import org.junit.Test; +import org.nuiton.util.DateUtil; + +import java.util.Date; + +/** + * Created: 08/08/12 + * + * @author fdesbois <florian.desbois@codelutin.com> + */ +public class DbfTimestampConverterTest { + + @Test + public void testToString() throws Exception { + + Date date = DateUtil.createDate(52, 2, 19, 5, 3, 2007); + String result = DbfTimestampConverter.toString(date); +// Assert.assertEquals(result, "2454488 68572000"); + Assert.assertEquals(result, "2454165 68572000"); + } + + @Test + public void testToDate() throws Exception { + + Date expected = DateUtil.createDate(52, 2, 19, 5, 3, 2007); + Date result = DbfTimestampConverter.toDate("2454165 68572000"); + Assert.assertEquals(expected, result); + } +} Property changes on: trunk/sammoa-application/src/test/java/fr/ulr/sammoa/application/map/DbfTimestampConverterTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/sammoa-application/src/test/java/fr/ulr/sammoa/application/map/ExportMapServiceTest.java =================================================================== --- trunk/sammoa-application/src/test/java/fr/ulr/sammoa/application/map/ExportMapServiceTest.java (rev 0) +++ trunk/sammoa-application/src/test/java/fr/ulr/sammoa/application/map/ExportMapServiceTest.java 2012-08-08 18:26:09 UTC (rev 372) @@ -0,0 +1,222 @@ +package fr.ulr.sammoa.application.map; + +import com.google.common.collect.Lists; +import fr.ulr.sammoa.application.FlightService; +import fr.ulr.sammoa.application.SammoaConfig; +import fr.ulr.sammoa.application.SammoaContext; +import fr.ulr.sammoa.application.csv.DoubleToIntegerValueParser; +import fr.ulr.sammoa.persistence.Campaign; +import fr.ulr.sammoa.persistence.CampaignImpl; +import fr.ulr.sammoa.persistence.Flight; +import fr.ulr.sammoa.persistence.FlightImpl; +import fr.ulr.sammoa.persistence.GeoPoint; +import fr.ulr.sammoa.persistence.GeoPointDAO; +import fr.ulr.sammoa.persistence.GeoPointImpl; +import fr.ulr.sammoa.persistence.Region; +import fr.ulr.sammoa.persistence.RegionImpl; +import fr.ulr.sammoa.persistence.SammoaDAOHelper; +import fr.ulr.sammoa.persistence.SammoaDatabase; +import junit.framework.Assert; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.TopiaException; +import org.nuiton.util.DateUtil; +import org.nuiton.util.csv.Common; +import org.nuiton.util.csv.ImportModel; +import org.nuiton.util.csv.ImportableColumn; +import org.nuiton.util.csv.ModelBuilder; +import org.nuiton.util.csv.ValueSetter; + +import java.io.File; +import java.net.URL; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * Created: 08/08/12 + * + * @author fdesbois <florian.desbois@codelutin.com> + */ +public class ExportMapServiceTest { + + public SammoaConfig config = + new SammoaConfig("sammoa-test.properties"); + + @Rule + public SammoaDatabase database = new SammoaDatabase("/" + + config.getApplicationConfig().getConfigFileName(), config.getAutoCommitDelay()); + + protected TopiaContext transaction; + + @Before + public void setUp() throws TopiaException { + transaction = database.beginTransaction(); + } + + @After + public void tearDown() throws TopiaException { + database.endTransaction(transaction); + } + + @Test + public void testExportGeoPointsMap() throws Exception { + + SammoaContext context = new SammoaContext(config, database.getPersistence()); + + Campaign campaign = database.createCampaign("PACOMM", "FRANCE"); + campaign.setBeginDate(DateUtil.createDate(1, 1, 2012)); + campaign.setEndDate(DateUtil.createDate(31, 12, 2012)); + + FlightService flightService = new FlightService(context); + Flight flight = flightService.createFlight(campaign); + + flight.setBeginDate(DateUtil.createDate(18, 0, 12, 18, 7, 2012)); + + createGeoPoint(DateUtil.createDate(30, 15, 12, 18, 7, 2012), 1, 2, flight); + createGeoPoint(DateUtil.createDate(39, 18, 12, 18, 7, 2012), 3, 4, flight); + + transaction.commitTransaction(); + + ExportMapService exportMapService = new ExportMapService(context); + + File exportDirectory = database.getTestBasedir(); + + ExportMapModel exportMapModel = ExportMapModel.newModel( + exportDirectory, + "export-geoPoints.shp", + campaign, + null, + null, + null, + null, + null + ); + + exportMapService.exportGeoPointsMap(exportMapModel); + + Assert.assertTrue(new File(exportDirectory, "export-geoPoints.shp").exists()); + Assert.assertTrue(new File(exportDirectory, "export-geoPoints.dbf").exists()); + Assert.assertTrue(new File(exportDirectory, "export-geoPoints.shx").exists()); + + URL fileUrl = new File(exportDirectory, "export-geoPoints.dbf").toURI().toURL(); + DbfImport<GeoPoint> dbfImport = new DbfImport<GeoPoint>(new GeoPointImportModel(), fileUrl); + + List<GeoPoint> results = Lists.newArrayList(dbfImport); + + Assert.assertEquals(2, results.size()); + { + GeoPoint result = results.get(0); + Flight resultFlight = result.getFlight(); + Campaign resultCampaign = resultFlight.getCampaign(); + Region resultRegion = resultCampaign.getRegion(); + Assert.assertEquals("FRANCE", resultRegion.getCode()); + Assert.assertEquals("PACOMM", resultCampaign.getCode()); + Assert.assertEquals(1, resultFlight.getFlightNumber()); + Assert.assertEquals("A", resultFlight.getSystemId()); + Assert.assertEquals(DateUtil.createDate(30, 15, 12, 18, 7, 2012), result.getRecordTime()); + Assert.assertEquals(1., result.getLatitude()); + Assert.assertEquals(2., result.getLongitude()); + Assert.assertEquals(0., result.getAltitude()); + Assert.assertEquals(0., result.getSpeed()); + } + { + GeoPoint result = results.get(1); + Flight resultFlight = result.getFlight(); + Campaign resultCampaign = resultFlight.getCampaign(); + Region resultRegion = resultCampaign.getRegion(); + Assert.assertEquals("FRANCE", resultRegion.getCode()); + Assert.assertEquals("PACOMM", resultCampaign.getCode()); + Assert.assertEquals(1, resultFlight.getFlightNumber()); + Assert.assertEquals("A", resultFlight.getSystemId()); + Assert.assertEquals(DateUtil.createDate(39, 18, 12, 18, 7, 2012), result.getRecordTime()); + Assert.assertEquals(3., result.getLatitude()); + Assert.assertEquals(4., result.getLongitude()); + Assert.assertEquals(0., result.getAltitude()); + Assert.assertEquals(0., result.getSpeed()); + } + } + + protected GeoPoint createGeoPoint(Date date, + double latitude, + double longitude, + Flight flight) + throws TopiaException { + + GeoPointDAO transectDAO = SammoaDAOHelper.getGeoPointDAO(transaction); + GeoPoint result = transectDAO.create(); + result.setRecordTime(date); + result.setLatitude(latitude); + result.setLongitude(longitude); + result.setFlight(flight); + + return result; + } + + protected class GeoPointImportModel implements ImportModel<GeoPoint> { + + @Override + public char getSeparator() { + return ' '; + } + + @Override + public void pushCsvHeaderNames(List<String> headerNames) { + } + + @Override + public GeoPoint newEmptyInstance() { + Region region = new RegionImpl(); + Campaign campaign = new CampaignImpl(); + campaign.setRegion(region); + Flight flight = new FlightImpl(); + flight.setCampaign(campaign); + GeoPoint result = new GeoPointImpl(); + result.setFlight(flight); + return result; + } + + @Override + public Iterable<ImportableColumn<GeoPoint, Object>> getColumnsForImport() { + ModelBuilder builder = new ModelBuilder(); + builder.newMandatoryColumn("REGION", "flight.campaign.region.code"); + builder.newMandatoryColumn("CAMPAIGN", "flight.campaign.code"); + builder.newMandatoryColumn("FLIGHT", "flight.flightNumber", new DoubleToIntegerValueParser()); + builder.newMandatoryColumn("COMPUTER", "flight.systemId"); + builder.newMandatoryColumn("DATE", "recordTime", new Common.DateValue(DbfTableModelBuilder.DATE_FORMAT_PATTERN)); + builder.newMandatoryColumn("HHMMSS", new Common.DateValue("HHmmss"), new GeoPointTimeValueSetter()); + builder.newMandatoryColumn("LAT", "latitude", Common.DOUBLE_PRIMITIVE); + builder.newMandatoryColumn("LON", "longitude", Common.DOUBLE_PRIMITIVE); + builder.newMandatoryColumn("SPEED", "speed", Common.DOUBLE_PRIMITIVE); + builder.newMandatoryColumn("ALTITUDE", "altitude", Common.DOUBLE_PRIMITIVE); + return builder.getColumnsForImport(); + } + } + + protected class GeoPointTimeValueSetter implements ValueSetter<GeoPoint, Date> { + + @Override + public void set(GeoPoint object, Date value) throws Exception { + Date recordTime = object.getRecordTime(); +// if (recordTime != null) { + Calendar resultCalendar = Calendar.getInstance(); + resultCalendar.setTime(recordTime); + + Calendar valueCalendar = Calendar.getInstance(); + valueCalendar.setTime(value); + resultCalendar.set(Calendar.HOUR_OF_DAY, valueCalendar.get(Calendar.HOUR_OF_DAY)); + resultCalendar.set(Calendar.MINUTE, valueCalendar.get(Calendar.MINUTE)); + resultCalendar.set(Calendar.SECOND, valueCalendar.get(Calendar.SECOND)); + + object.setRecordTime(resultCalendar.getTime()); + +// } else { +// object.setRecordTime(value); +// } + } + + } +} Property changes on: trunk/sammoa-application/src/test/java/fr/ulr/sammoa/application/map/ExportMapServiceTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java 2012-08-08 16:50:09 UTC (rev 371) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java 2012-08-08 18:26:09 UTC (rev 372) @@ -208,9 +208,9 @@ List<Route> routes = getFlightService().getRoutes(flight); List<GeoPoint> geoPoints = getFlightService().getFlightGeoPoints(flight); - if (logger.isDebugEnabled()) { + if (logger.isTraceEnabled()) { for (GeoPoint geoPoint : geoPoints) { - logger.debug(String.format("GeoPoint={%1$tH:%1$tM:%1$tS,%2$f,%3$f}", + logger.trace(String.format("GeoPoint={%1$tH:%1$tM:%1$tS,%2$f,%3$f}", geoPoint.getRecordTime(), geoPoint.getLatitude(), geoPoint.getLongitude()) Deleted: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/DbfImport.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/DbfImport.java 2012-08-08 16:50:09 UTC (rev 371) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/DbfImport.java 2012-08-08 18:26:09 UTC (rev 372) @@ -1,129 +0,0 @@ -package fr.ulr.sammoa.ui.swing.util; -/* - * #%L - * SAMMOA :: UI Swing - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2012 UMS 3462, Code Lutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import com.bbn.openmap.dataAccess.shape.DbfTableModel; -import com.google.common.base.Throwables; -import com.google.common.collect.Lists; -import org.nuiton.util.csv.Import; -import org.nuiton.util.csv.ImportModel; -import org.nuiton.util.csv.ImportRuntimeException; -import org.nuiton.util.csv.ImportableColumn; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.io.Reader; -import java.net.URL; -import java.util.Iterator; -import java.util.List; - -import static org.nuiton.i18n.I18n._; - -/** - * Created: 25/07/12 - * - * @author fdesbois <desbois@codelutin.com> - */ -public class DbfImport<E> extends Import<E> { - - private static final Logger logger = LoggerFactory.getLogger(DbfImport.class); - - protected DbfTableModel source; - - protected Iterator<List<Object>> records; - - protected List<Object> record; - - public DbfImport(ImportModel<E> model, URL fileUrl) { - // Use dummy reader for superclass Import that manage by default csv files - super(model, new Reader() { - - @Override - public int read(char[] cbuf, int off, int len) throws IOException { - return -1; - } - - @Override - public void close() throws IOException { - } - }); - - try { - // FIXME-fdesbois-2012-07-26 : there is an issue with encoding, don't know how to customize it - this.source = DbfTableModel.read(fileUrl); - - } catch (Exception e) { - throw Throwables.propagate(e); - } - this.records = source.getRecords(); - } - - @Override - protected <T> String readValue(ImportableColumn<E, T> field, int lineNumber) { - try { - - int columnNumber = source.getColumnIndexForName(field.getHeaderName()); - - String value = String.valueOf(record.get(columnNumber)); - - return value; - - } catch (Exception e) { - throw new ImportRuntimeException( - _("csv.import.error.unableToReadField", - field.getHeaderName(), lineNumber), e); - } - } - - @Override - public void close() { - // nothing to do - } - - @Override - protected boolean readRow() throws ImportRuntimeException { - boolean result; - if (records.hasNext()) { - record = records.next(); - if (logger.isTraceEnabled()) { - logger.trace("Read record {}", record); - } - result = true; - - } else { - result = false; - } - return result; - } - - @Override - protected String[] getHeaders() throws ImportRuntimeException { - List<String> list = Lists.newArrayList(); - for (int index = 0; index < source.getColumnCount(); index++) { - list.add(source.getColumnName(index)); - } - return list.toArray(new String[list.size()]); - } -} Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/ShpImporter.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/ShpImporter.java 2012-08-08 16:50:09 UTC (rev 371) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/util/ShpImporter.java 2012-08-08 18:26:09 UTC (rev 372) @@ -24,6 +24,7 @@ */ import com.google.common.io.Files; +import fr.ulr.sammoa.application.map.DbfImport; import org.apache.commons.io.FileUtils; import org.nuiton.util.csv.ImportModel; import org.slf4j.Logger;
participants (1)
-
fdesbois@users.forge.codelutin.com