GeometryConverter.java
/*
* Copyright (C) 2016 - 2017 B3Partners B.V.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.b3p.topnl.converters;
import java.io.IOException;
import java.io.InvalidClassException;
import java.io.StringReader;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.gml3.ArcParameters;
import org.geotools.gml3.CircleRadiusTolerance;
import org.geotools.xsd.Parser;
import org.jdom2.input.DOMBuilder;
import org.jdom2.output.XMLOutputter;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.simplify.DouglasPeuckerSimplifier;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
/**
* @author Meine Toonen meinetoonen@b3partners.nl
*/
public class GeometryConverter {
protected static final Log log = LogFactory.getLog(GeometryConverter.class);
private static final double DISTANCE_TOLERANCE = 0.001;
protected static final double LINEARIZATION_TOLERANCE_MULTIPLIER = 0.01; // 0.001;
private Parser parser;
private GeometryFactory geometryFactory;
protected static final int SRID = 28992;
public GeometryConverter() {
GeometryFactory gf = new GeometryFactory(new PrecisionModel(), SRID);
/* GMLConfiguration gml3Config = new GMLConfiguration(true);
gml3Config.setGeometryFactory(gf);
gml3Config.setExtendedArcSurfaceSupport(true);*/
ArcParameters arcParameters =
new ArcParameters(new CircleRadiusTolerance(LINEARIZATION_TOLERANCE_MULTIPLIER)); // new
// AbsoluteTolerance(LINEARIZATION_TOLERANCE));
org.geotools.gml3.GMLConfiguration gml3Config = new org.geotools.gml3.GMLConfiguration();
gml3Config.setExtendedArcSurfaceSupport(true);
gml3Config.getContext().registerComponentInstance(gf);
gml3Config.getContext().registerComponentInstance(arcParameters);
parser = new Parser(gml3Config);
this.geometryFactory = gf;
}
public Geometry convertGeometry(Element el)
throws IOException, SAXException, ParserConfigurationException, TransformerException {
if (!(el instanceof org.w3c.dom.Element)) {
throw new IllegalArgumentException("gml org.w3c.node is not an org.w3c.Element");
}
// TODO: maybe convert node directly to a source / inputsource / reader / stream for parser.
// instead of JDOM detour.
org.jdom2.Element elem = new DOMBuilder().build((org.w3c.dom.Element) el);
String gmlString = new XMLOutputter().outputString(elem);
gmlString = gmlString.replaceAll("gml:", "");
// tySstem.out.println("gmlString:" + gmlString);
// parser.getNamespaces().declarePrefix("gml", "http://www.opengis.net/gml/3.2");
Object parsedObject = parser.parse(new StringReader(gmlString));
if (parsedObject instanceof Geometry) {
Geometry geom = (Geometry) parsedObject;
if (!geom.isValid()) {
geom = geom.buffer(0.0);
log.debug("Geometry is invalid. Made valid by buffering with 0");
}
// arcs can have nodes that are on the same point (28992; 3 digit precision): simplify
Geometry simplGeom = DouglasPeuckerSimplifier.simplify(geom, DISTANCE_TOLERANCE);
return simplGeom;
} else {
throw new InvalidClassException(
parsedObject.getClass().getCanonicalName(), "Parsed object not of class Geometry.");
}
}
}