[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