/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2005-2008, Open Source Geospatial Foundation (OSGeo) * * 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; * version 2.1 of the License. * * 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. */ package org.geotools.gce.imagemosaic; import java.util.Date; import java.util.Iterator; import org.geotools.util.DateRange; import org.geotools.util.Range; import org.geotools.util.Utilities; import org.opengis.feature.Feature; /** * Generates a list of compact DateRanges from a collection * * @author Daniele Romagnoli, GeoSolutions SAS * */ class DateRangeVisitor extends RangeVisitor { public DateRangeVisitor(String attributeTypeName1, String attributeTypeName2) { super(attributeTypeName1, attributeTypeName2, RangeType.DATE); } public void visit(Feature feature) { final Object firstValue = expr1.evaluate(feature); final Object secondValue = expr2.evaluate(feature); if (firstValue != null && secondValue != null) { final Date beginDate = (Date) firstValue; final Date endDate = (Date) secondValue; set.add(new DateRange(beginDate, endDate)); } } /** * Setup the minimal set of dataRanges (intersecting ranges are merged together) as a Set of ISO8601 String intervals with period. * * @return */ @Override protected void populateRange() { Iterator<? extends Range> iterator = set.iterator(); DateRange second = null; DateRange first; while (iterator.hasNext()) { first = second; second = (DateRange) iterator.next(); if (first != null) { // Compact intervals with intersections if (second.intersects(first)) { second = merge(first, second); if (!iterator.hasNext()) { minimalRanges.add(formatRange(second)); second = null; } } else { minimalRanges.add(formatRange(first)); first = null; } } } if (second != null) { minimalRanges.add(formatRange(second)); } } /** * Format a DateRange into ISO8601 interval strings * * @param range * @return */ private String formatRange(DateRange range) { final StringBuilder builder = new StringBuilder(); final String begin = ConvertersHack.convert(range.getMinValue(), String.class); final String end = ConvertersHack.convert(range.getMaxValue(), String.class); builder.append(begin + "/" + end + "/PT1S"); return builder.toString(); } /** * Merge 2 ranges together. In order to speed up the computations, this method does the assumption that the 2 date ranges are already sorted * (first < second) and they intersect together. * * @param firstDateRange * @param secondDateRange * @return */ private static DateRange merge(DateRange firstDateRange, DateRange secondDateRange) { Utilities.ensureNonNull("firstDateRange", firstDateRange); Utilities.ensureNonNull("secondDateRange", secondDateRange); final long beginFirst = firstDateRange.getMinValue().getTime(); final long endFirst = firstDateRange.getMaxValue().getTime(); final long beginSecond = secondDateRange.getMinValue().getTime(); final long endSecond = secondDateRange.getMaxValue().getTime(); final long max = Math.max(endFirst, endSecond); final long min = Math.min(beginFirst, beginSecond); final Date beginDate = new Date(min); final Date endDate = new Date(max); return new DateRange(beginDate, endDate); } }