/**
* Copyright (c) Codice Foundation
* <p/>
* This 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 3 of the
* License, or any later version.
* <p/>
* 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
* Lesser General Public License for more details. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*/
package ddf.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
/**
* <p>
* WktStandard supports converting WKT into standard representations based on the WKT grammar in the
* OpenGIS Simple Feature Access specification.
* </p>
* <p>
* DDF normalizes MULTIPOINT geometries to the style defined by the WKT grammar. For example,
* <code>MULTIPOINT ((0 0), (10 10))</code> is in the normalized format. Some systems require a
* different format of MULTIPOINT. The previous example would denormalize as
* <code>MULTIPOINT (0 0, 10 10)</code>
* </p>
*
* @author ddf.isgs@lmco.com
*
*/
public class WktStandard {
private static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();
private static final Pattern WKT_MULTIPOINT_PATTERN = Pattern.compile(
"MULTIPOINT\\s*\\(((\\s*\\(\\s*\\-?\\d+(\\.\\d*)?\\s+\\-?\\d+(\\.\\d*)?\\s*\\)\\s*,?\\s*)+)\\)",
Pattern.CASE_INSENSITIVE);
/**
* Hiding class constructor since this is a utility class
*/
private WktStandard() {
}
/**
* Normalize the given WKT to conform to the WKT grammar.
*
*
* @param wkt
* WKT to normalize
* @return normalized WKT
*/
public static String normalize(String wkt) {
if (StringUtils.isBlank(wkt)) {
return wkt;
}
WKTReader wktReader = new WKTReader(GEOMETRY_FACTORY);
try {
// using JTS to normalize WKT into the correct format
return wktReader.read(wkt).toText();
} catch (ParseException e) {
throw new IllegalArgumentException("Cannot parse wkt.", e);
}
}
/**
* Denormalize the given WKT to support backwards compatibility.
*
* @param wkt
* wkt to denormalize
* @return denormalized WKT
*/
public static String denormalize(String wkt) {
if (wkt == null) {
return wkt;
}
Matcher matcher = WKT_MULTIPOINT_PATTERN.matcher(wkt);
if (matcher.find()) {
matcher.reset();
StringBuffer resultWkt = new StringBuffer(wkt.length());
while (matcher.find()) {
String currentMultiPoint = matcher.group(0);
String currentMultiPointText = matcher.group(1);
matcher.appendReplacement(resultWkt, currentMultiPoint
.replace(currentMultiPointText,
currentMultiPointText.replaceAll("[\\(\\)]", "")));
}
matcher.appendTail(resultWkt);
return resultWkt.toString();
} else {
return wkt;
}
}
}