Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1397 from aaime/dimension_default_range
[GEOS-7372] Allow default value for time and elevation dimensions to be a range
- Loading branch information
Showing
35 changed files
with
1,406 additions
and
834 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
192 changes: 192 additions & 0 deletions
192
src/ows/src/main/java/org/geoserver/ows/kvp/ElevationParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved | ||
* (c) 2001 - 2013 OpenPlans | ||
* This code is licensed under the GPL 2.0 license, available at the root | ||
* application directory. | ||
*/ | ||
package org.geoserver.ows.kvp; | ||
|
||
import java.text.ParseException; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.Comparator; | ||
import java.util.Iterator; | ||
import java.util.Set; | ||
import java.util.TreeSet; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
import org.geoserver.platform.GeoServerExtensions; | ||
import org.geotools.util.DateRange; | ||
import org.geotools.util.NumberRange; | ||
import org.geotools.util.logging.Logging; | ||
|
||
/** | ||
* Parses the {@code elevation} parameter of the request. | ||
* | ||
* @author Ariel Nunez, GeoSolutions S.A.S. | ||
* @author Simone Giannecchini, GeoSolutions S.A.S. | ||
* @version $Id$ | ||
*/ | ||
public class ElevationParser { | ||
|
||
static final Logger LOGGER = Logging.getLogger(ElevationParser.class); | ||
|
||
/** | ||
* Built-in limits | ||
*/ | ||
private final static int MAX_ELEMENTS_ELEVATIONS_KVP; | ||
|
||
private final static int DEFAULT_MAX_ELEMENTS_ELEVATIONS_KVP = 100; | ||
|
||
static { | ||
// initialization of the renderer choice flag | ||
String value = GeoServerExtensions.getProperty("MAX_ELEMENTS_ELEVATIONS_KVP"); | ||
// default to true, but allow switching on | ||
if (value == null) | ||
MAX_ELEMENTS_ELEVATIONS_KVP = DEFAULT_MAX_ELEMENTS_ELEVATIONS_KVP; | ||
else { | ||
int iVal = -1; | ||
try { | ||
iVal = Integer.parseInt(value.trim()); | ||
} catch (Exception e) { | ||
iVal = DEFAULT_MAX_ELEMENTS_ELEVATIONS_KVP; | ||
} | ||
MAX_ELEMENTS_ELEVATIONS_KVP = iVal; | ||
} | ||
} | ||
|
||
/** | ||
* Parses the elevation given in parameter. The string may contains either a single double, or a | ||
* start value, end value and a period. In the first case, this method returns a singleton | ||
* containing only the parsed value. In the second case, this method returns a list including | ||
* all elevations from start value up to the end value with the interval specified in the | ||
* {@code value} string. | ||
* | ||
* @param value | ||
* The elevation item or items to parse. | ||
* @return A list of doubles, or an empty list of the {@code value} string is null or empty. | ||
* @throws ParseException | ||
* if the string can not be parsed. | ||
*/ | ||
@SuppressWarnings( { "unchecked", "rawtypes" }) | ||
public Collection parse(String value) throws ParseException { | ||
if (value == null) { | ||
return Collections.emptyList(); | ||
} | ||
value = value.trim(); | ||
if (value.length() == 0) { | ||
return Collections.emptyList(); | ||
} | ||
final Set values = new TreeSet(new Comparator() { | ||
|
||
public int compare(Object o1, Object o2) { | ||
final boolean o1Double = o1 instanceof Double; | ||
final boolean o2Double = o2 instanceof Double; | ||
|
||
// o1 date | ||
if (o1Double) { | ||
final Double left = (Double) o1; | ||
if (o2Double) { | ||
// o2 date | ||
return left.compareTo((Double) o2); | ||
} | ||
// o2 number range | ||
return left.compareTo(((NumberRange<Double>) o2).getMinValue()); | ||
} | ||
|
||
// o1 number range | ||
final NumberRange left = (NumberRange) o1; | ||
if (o2Double) { | ||
// o2 date | ||
return left.getMinValue().compareTo(((Double) o2)); | ||
} | ||
// o2 daterange | ||
return left.getMinValue().compareTo(((NumberRange) o2).getMinValue()); | ||
} | ||
}); | ||
final String[] listValues = value.split(","); | ||
for (String d : listValues) { | ||
if (d.indexOf("/") <= 0) { | ||
addValue(values, Double.valueOf(d.trim())); | ||
} else { | ||
// period | ||
|
||
String[] period = d.split("/"); | ||
// Only one value given. | ||
if (period.length == 2) { | ||
// Period continuous | ||
final Double begin = Double.valueOf(period[0]); | ||
final Double end = Double.valueOf(period[1]); | ||
addPeriod(values, NumberRange.create(begin, end)); | ||
} else if (period.length == 3) { | ||
// Period discrete | ||
final Double begin = Double.valueOf(period[0]); | ||
final Double end = Double.valueOf(period[1]); | ||
final Double increment = Double.valueOf(period[2]); | ||
|
||
Double step; | ||
int j = 0; | ||
while ((step = j * increment + begin) <= end) { | ||
addValue(values, step); | ||
j++; | ||
|
||
// limiting discrete period elements | ||
if (j >= MAX_ELEMENTS_ELEVATIONS_KVP) { | ||
if (LOGGER.isLoggable(Level.INFO)) | ||
LOGGER.info("Lmiting number of elements in this periodo to " | ||
+ MAX_ELEMENTS_ELEVATIONS_KVP); | ||
break; | ||
|
||
} | ||
} | ||
} else { | ||
throw new ParseException("Invalid elevation parameter: " + period, 0); | ||
} | ||
} | ||
} | ||
|
||
return new ArrayList(values); | ||
} | ||
|
||
private void addValue(Collection result, Double step) { | ||
for (Iterator it = result.iterator(); it.hasNext();) { | ||
final Object element = it.next(); | ||
if (element instanceof Double) { | ||
// convert | ||
final Double local = (Double) element; | ||
if (local.equals(step)) | ||
return; | ||
} else { | ||
// convert | ||
final DateRange local = (DateRange) element; | ||
if (local.contains(step)) | ||
return; | ||
} | ||
} | ||
result.add(step); | ||
|
||
} | ||
|
||
private void addPeriod(Collection result, NumberRange<Double> newRange) { | ||
for (Iterator it = result.iterator(); it.hasNext();) { | ||
final Object element = it.next(); | ||
if (element instanceof Double) { | ||
// convert | ||
if (newRange.contains((Number) element)) { | ||
it.remove(); | ||
} | ||
} else { | ||
// convert | ||
final NumberRange<Double> local = (NumberRange<Double>) element; | ||
if (local.contains(newRange)) | ||
return; | ||
if (newRange.contains(local)) | ||
it.remove(); | ||
} | ||
} | ||
result.add(newRange); | ||
|
||
} | ||
|
||
} |
Oops, something went wrong.