[geos-commits] r2460 - in trunk/source: headers/geos/operation/overlay headers/geos/operation/overlay/snap operation/overlay operation/overlay/snap

svn_geos at osgeo.org svn_geos at osgeo.org
Mon May 4 15:55:02 EDT 2009


Author: strk
Date: 2009-05-04 15:54:57 -0400 (Mon, 04 May 2009)
New Revision: 2460

Added:
   trunk/source/headers/geos/operation/overlay/snap/GeometrySnapper.h
   trunk/source/operation/overlay/snap/GeometrySnapper.cpp
Modified:
   trunk/source/headers/geos/operation/overlay/Makefile.am
   trunk/source/operation/overlay/Makefile.am
Log:
Port overlay.snap.GeometrySnapper


Modified: trunk/source/headers/geos/operation/overlay/Makefile.am
===================================================================
--- trunk/source/headers/geos/operation/overlay/Makefile.am	2009-05-04 19:51:32 UTC (rev 2459)
+++ trunk/source/headers/geos/operation/overlay/Makefile.am	2009-05-04 19:54:57 UTC (rev 2460)
@@ -24,4 +24,5 @@
 	OverlayResultValidator.h \
 	PointBuilder.h		\
 	PolygonBuilder.h	\
+	snap/GeometrySnapper.h	\
 	snap/LineStringSnapper.h

Added: trunk/source/headers/geos/operation/overlay/snap/GeometrySnapper.h
===================================================================
--- trunk/source/headers/geos/operation/overlay/snap/GeometrySnapper.h	                        (rev 0)
+++ trunk/source/headers/geos/operation/overlay/snap/GeometrySnapper.h	2009-05-04 19:54:57 UTC (rev 2460)
@@ -0,0 +1,129 @@
+/**********************************************************************
+ * $Id$
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.refractions.net
+ *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation. 
+ * See the COPYING file for more information.
+ *
+ ***********************************************************************
+ *
+ * Last port: operation/overlay/snap/GeometrySnapper.java rev 1.8 (JTS-1.10)
+ *
+ **********************************************************************/
+
+#ifndef GEOS_OP_OVERLAY_SNAP_GEOMETRYSNAPPER_H
+#define GEOS_OP_OVERLAY_SNAP_GEOMETRYSNAPPER_H
+
+#include <geos/geom/LineSegment.h> // for composition
+#include <geos/geom/LineString.h> // for inlined ctor
+
+//#include <vector>
+#include <memory> // for auto_ptr
+
+// Forward declarations
+namespace geos {
+	namespace geom {
+		class CoordinateSequence;
+	}
+}
+
+namespace geos {
+namespace operation { // geos::operation
+namespace overlay { // geos::operation::overlay
+namespace snap { // geos::operation::overlay::snap
+
+/** \brief
+ * Snaps the vertices and segments of a geom::Geometry to another
+ * Geometry's vertices.
+ * 
+ * Improves robustness for overlay operations, by eliminating
+ * nearly parallel edges (which cause problems during noding and
+ * intersection calculation).
+ *
+ */
+class GeometrySnapper
+{
+
+public:
+
+	/** \brief
+	 * Estimates the snap tolerance for a Geometry, taking into account
+	 * its precision model.
+	 *
+	 * @param g a Geometry
+	 * @return the estimated snap tolerance
+	 */
+	static double computeOverlaySnapTolerance(const geom::Geometry& g);
+
+	static double computeSizeBasedSnapTolerance(const geom::Geometry& g);
+
+	static double computeOverlaySnapTolerance(const geom::Geometry& g0,
+	                                          const geom::Geometry& g1);
+
+
+	typedef std::auto_ptr<geom::Geometry> GeomPtr;
+	typedef std::pair<GeomPtr, GeomPtr> GeomPtrPair;
+
+	/**
+	 * Snaps two geometries together with a given tolerance.
+	 *
+	 * @param g0 a geometry to snap
+	 * @param g1 a geometry to snap
+	 * @param snapTolerance the tolerance to use
+	 * @return the snapped geometries as a pair of auto_ptrs
+	 */
+	static GeomPtrPair snap(const geom::Geometry& g0,
+	                        const geom::Geometry& g1,
+	                        double snapTolerance);
+
+	/**
+	 * Creates a new snapper acting on the given geometry
+	 *
+	 * @param nSrcGeom the geometry to snap
+	 */
+	GeometrySnapper(const geom::Geometry& nSrcGeom)
+		:
+		srcGeom(nSrcGeom)
+	{}
+
+	/**
+	 * Snaps the vertices in the component {@link LineString}s
+	 * of the source geometry
+	 * to the vertices of the given snap geometry.
+	 *
+	 * @param snapGeom a geometry to snap the source to
+	 * @param snapTolerance
+	 *
+	 * @return a new snapped Geometry
+	 */
+	GeomPtr snapTo(const geom::Geometry& snapGeom, double snapTolerance);
+
+	// why is this public ??
+	void extractTargetCoordinates(const geom::Geometry& g,
+	                    std::vector<const geom::Coordinate*>& target);
+ 
+
+private:
+
+	static const double SNAP_PRECISION_FACTOR; // = 10e-10;
+
+	const geom::Geometry& srcGeom;
+};
+
+} // namespace geos::operation::overlay::snap
+} // namespace geos::operation::overlay
+} // namespace geos::operation
+} // namespace geos
+
+#endif // ndef GEOS_OP_OVERLAY_SNAP_GEOMETRYSNAPPER_H
+
+/**********************************************************************
+ * $Log$
+ **********************************************************************/
+

Modified: trunk/source/operation/overlay/Makefile.am
===================================================================
--- trunk/source/operation/overlay/Makefile.am	2009-05-04 19:51:32 UTC (rev 2459)
+++ trunk/source/operation/overlay/Makefile.am	2009-05-04 19:54:57 UTC (rev 2460)
@@ -18,6 +18,7 @@
 	OverlayResultValidator.cpp \
 	PointBuilder.cpp \
 	PolygonBuilder.cpp \
+	snap/GeometrySnapper.cpp \
 	snap/LineStringSnapper.cpp
 
 libopoverlay_la_LIBADD = 

Added: trunk/source/operation/overlay/snap/GeometrySnapper.cpp
===================================================================
--- trunk/source/operation/overlay/snap/GeometrySnapper.cpp	                        (rev 0)
+++ trunk/source/operation/overlay/snap/GeometrySnapper.cpp	2009-05-04 19:54:57 UTC (rev 2460)
@@ -0,0 +1,184 @@
+/**********************************************************************
+ * $Id$
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.refractions.net
+ *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation. 
+ * See the COPYING file for more information.
+ *
+ ***********************************************************************
+ *
+ * Last port: operation/overlay/snap/GeometrySnapper.java rev 1.8 (JTS-1.10)
+ *
+ **********************************************************************/
+
+#include <geos/operation/overlay/snap/GeometrySnapper.h>
+#include <geos/operation/overlay/snap/LineStringSnapper.h>
+#include <geos/geom/PrecisionModel.h> 
+#include <geos/geom/util/GeometryTransformer.h> // SnapTransformer inheritance
+#include <geos/geom/CoordinateSequence.h> 
+#include <geos/util/UniqueCoordinateArrayFilter.h> 
+
+#include <cassert>
+#include <limits> // for numeric_limits
+#include <memory> // for auto_ptr
+
+#include <algorithm> // for std::min
+
+#ifndef GEOS_DEBUG
+#define GEOS_DEBUG 0
+#endif
+
+using namespace std;
+using namespace geos::geom;
+
+namespace geos {
+namespace operation { // geos.operation
+namespace overlay { // geos.operation.overlay
+namespace snap { // geos.operation.overlay.snap
+
+namespace { // anonymous
+
+class SnapTransformer : public geom::util::GeometryTransformer
+{
+public:
+
+	double snapTolerance;
+	const vector<const Coordinate*>& snapPts;
+
+	SnapTransformer(double nSnapTolerance,
+			const vector<const Coordinate*>& nSnapPts)
+		:
+		snapTolerance(nSnapTolerance),
+		snapPts(nSnapPts)
+	{
+	}
+
+protected:
+
+	virtual CoordinateSequence::AutoPtr transformCoordinates(
+		const CoordinateSequence* coords,
+		const Geometry* parent)
+	{
+		return snapLine(*coords, snapPts);
+	}
+
+private:
+
+	auto_ptr< CoordinateSequence >
+	snapLine(const CoordinateSequence& srcPts,
+	         const vector<const Coordinate*>& snapPts)
+	{
+		// TODO: make the LineStringSnapper a private member...
+		LineStringSnapper snapper(srcPts, snapTolerance);
+
+		return snapper.snapTo(snapPts);
+	}
+};
+
+} // anonymous namespace
+
+/* private static */
+const double GeometrySnapper::SNAP_PRECISION_FACTOR = 10e-10;
+
+
+/* public static */
+double
+GeometrySnapper::computeOverlaySnapTolerance(const Geometry& g)
+{
+	double snapTolerance = computeSizeBasedSnapTolerance(g);
+
+	/**
+	 * Overlay is carried out in the precision model
+	 * of the two inputs.
+	 * If this precision model is of type FIXED, then the snap tolerance
+	 * must reflect the precision grid size.
+	 * Specifically, the snap tolerance should be at least
+	 * the distance from a corner of a precision grid cell
+	 * to the centre point of the cell.
+	 */
+	const PrecisionModel& pm = *(g.getPrecisionModel());
+	if (pm.getType() == PrecisionModel::FIXED) {
+		double fixedSnapTol = (1 / pm.getScale()) * 2 / 1.415;
+		if (fixedSnapTol > snapTolerance)
+			snapTolerance = fixedSnapTol;
+	}
+	return snapTolerance;
+}
+
+/* public static */
+double
+GeometrySnapper::computeSizeBasedSnapTolerance(const geom::Geometry& g)
+{
+	const Envelope& env = *(g.getEnvelopeInternal());
+	double minDimension = std::min(env.getHeight(), env.getWidth());
+	double snapTol = minDimension * SNAP_PRECISION_FACTOR;
+	return snapTol;
+}
+
+/* public static */
+double
+GeometrySnapper::computeOverlaySnapTolerance(const geom::Geometry& g0,
+	                                     const geom::Geometry& g1)
+{
+	return std::min(computeOverlaySnapTolerance(g0),
+			computeOverlaySnapTolerance(g1));
+}
+
+/* public static */
+GeometrySnapper::GeomPtrPair
+GeometrySnapper::snap(const geom::Geometry& g0,
+                      const geom::Geometry& g1,
+                      double snapTolerance)
+{
+	GeometrySnapper::GeomPtrPair snapGeom;
+
+	GeometrySnapper snapper0(g0);
+	snapGeom.first = snapper0.snapTo(g1, snapTolerance);
+
+	GeometrySnapper snapper1(g1);
+
+	/**
+	 * Snap the second geometry to the snapped first geometry
+	 * (this strategy minimizes the number of possible different
+	 * points in the result)
+	 */
+	snapGeom.second = snapper1.snapTo(*snapGeom.first, snapTolerance);
+
+//	cout << *snapGeom.first << endl;
+//	cout << *snapGeom.second << endl;
+
+	return snapGeom;
+}
+
+/*public*/
+GeometrySnapper::GeomPtr
+GeometrySnapper::snapTo(const geom::Geometry& snapGeom, double snapTolerance)
+{
+	vector<const Coordinate*> snapPts;
+	extractTargetCoordinates(snapGeom, snapPts);
+
+	SnapTransformer snapTrans(snapTolerance, snapPts);
+	return snapTrans.transform(&srcGeom);
+}
+
+/*public*/
+void
+GeometrySnapper::extractTargetCoordinates(const Geometry& g,
+	  vector<const Coordinate*>& target)
+{
+	util::UniqueCoordinateArrayFilter filter(target);
+	g.apply_ro(&filter);
+}
+
+
+} // namespace geos.operation.snap
+} // namespace geos.operation.overlay
+} // namespace geos.operation
+} // namespace geos
+



More information about the geos-commits mailing list