GeometryConverter.java

  1. /*
  2.  * Copyright (C) 2016 - 2017 B3Partners B.V.
  3.  *
  4.  * This program is free software: you can redistribute it and/or modify
  5.  * it under the terms of the GNU Affero General Public License as published by
  6.  * the Free Software Foundation, either version 3 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU Affero General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU Affero General Public License
  15.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16.  */
  17. package nl.b3p.topnl.converters;

  18. import java.io.IOException;
  19. import java.io.InvalidClassException;
  20. import java.io.StringReader;
  21. import javax.xml.parsers.ParserConfigurationException;
  22. import javax.xml.transform.TransformerException;
  23. import org.apache.commons.logging.Log;
  24. import org.apache.commons.logging.LogFactory;
  25. import org.geotools.gml3.ArcParameters;
  26. import org.geotools.gml3.CircleRadiusTolerance;
  27. import org.geotools.xsd.Parser;
  28. import org.jdom2.input.DOMBuilder;
  29. import org.jdom2.output.XMLOutputter;
  30. import org.locationtech.jts.geom.Geometry;
  31. import org.locationtech.jts.geom.GeometryFactory;
  32. import org.locationtech.jts.geom.PrecisionModel;
  33. import org.locationtech.jts.simplify.DouglasPeuckerSimplifier;
  34. import org.w3c.dom.Element;
  35. import org.xml.sax.SAXException;

  36. /**
  37.  * @author Meine Toonen meinetoonen@b3partners.nl
  38.  */
  39. public class GeometryConverter {

  40.   protected static final Log log = LogFactory.getLog(GeometryConverter.class);

  41.   private static final double DISTANCE_TOLERANCE = 0.001;
  42.   protected static final double LINEARIZATION_TOLERANCE_MULTIPLIER = 0.01; // 0.001;

  43.   private Parser parser;
  44.   private GeometryFactory geometryFactory;

  45.   protected static final int SRID = 28992;

  46.   public GeometryConverter() {
  47.     GeometryFactory gf = new GeometryFactory(new PrecisionModel(), SRID);

  48.     /*  GMLConfiguration gml3Config = new GMLConfiguration(true);
  49.     gml3Config.setGeometryFactory(gf);
  50.     gml3Config.setExtendedArcSurfaceSupport(true);*/

  51.     ArcParameters arcParameters =
  52.         new ArcParameters(new CircleRadiusTolerance(LINEARIZATION_TOLERANCE_MULTIPLIER)); // new
  53.     // AbsoluteTolerance(LINEARIZATION_TOLERANCE));

  54.     org.geotools.gml3.GMLConfiguration gml3Config = new org.geotools.gml3.GMLConfiguration();
  55.     gml3Config.setExtendedArcSurfaceSupport(true);
  56.     gml3Config.getContext().registerComponentInstance(gf);
  57.     gml3Config.getContext().registerComponentInstance(arcParameters);
  58.     parser = new Parser(gml3Config);
  59.     this.geometryFactory = gf;
  60.   }

  61.   public Geometry convertGeometry(Element el)
  62.       throws IOException, SAXException, ParserConfigurationException, TransformerException {
  63.     if (!(el instanceof org.w3c.dom.Element)) {
  64.       throw new IllegalArgumentException("gml org.w3c.node is not an org.w3c.Element");
  65.     }
  66.     // TODO: maybe convert node directly to a source / inputsource / reader / stream for parser.
  67.     // instead of JDOM detour.
  68.     org.jdom2.Element elem = new DOMBuilder().build((org.w3c.dom.Element) el);
  69.     String gmlString = new XMLOutputter().outputString(elem);
  70.     gmlString = gmlString.replaceAll("gml:", "");
  71.     // tySstem.out.println("gmlString:" + gmlString);
  72.     //   parser.getNamespaces().declarePrefix("gml", "http://www.opengis.net/gml/3.2");
  73.     Object parsedObject = parser.parse(new StringReader(gmlString));
  74.     if (parsedObject instanceof Geometry) {
  75.       Geometry geom = (Geometry) parsedObject;
  76.       if (!geom.isValid()) {
  77.         geom = geom.buffer(0.0);
  78.         log.debug("Geometry is invalid. Made valid by buffering with 0");
  79.       }
  80.       // arcs can have nodes that are on the same point (28992; 3 digit precision): simplify
  81.       Geometry simplGeom = DouglasPeuckerSimplifier.simplify(geom, DISTANCE_TOLERANCE);
  82.       return simplGeom;
  83.     } else {
  84.       throw new InvalidClassException(
  85.           parsedObject.getClass().getCanonicalName(), "Parsed object not of class Geometry.");
  86.     }
  87.   }
  88. }