[geos-commits] [SCM] GEOS branch master updated. 075eb3cd1f6f267697aaae8ba7ba67c766f83170

git at osgeo.org git at osgeo.org
Sun Jun 16 18:59:06 PDT 2019


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".

The branch, master has been updated
       via  075eb3cd1f6f267697aaae8ba7ba67c766f83170 (commit)
      from  c897e468c7c0856d241928b95c92883794544f73 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 075eb3cd1f6f267697aaae8ba7ba67c766f83170
Author: Daniel Baston <dbaston at gmail.com>
Date:   Wed Jun 12 16:45:14 2019 -0400

    Convert Location into an enum class

diff --git a/include/geos/algorithm/PointLocation.h b/include/geos/algorithm/PointLocation.h
index 5cd0bf9..01647f3 100644
--- a/include/geos/algorithm/PointLocation.h
+++ b/include/geos/algorithm/PointLocation.h
@@ -22,6 +22,7 @@
 #include <geos/export.h>
 #include <geos/geom/Coordinate.h>
 #include <geos/geom/CoordinateSequence.h>
+#include <geos/geom/Location.h>
 
 namespace geos {
 namespace algorithm { // geos::algorithm
@@ -67,19 +68,19 @@ public:
     static bool isInRing(const geom::Coordinate& p, const geom::CoordinateSequence* ring);
 
     /** \brief
-     * Determines whether a point lies in the interior, on the boundary, or in the
-     * exterior of a ring. The ring may be oriented in either direction.
-     *
-     * This method does **not** first check the point against the envelope of
-     * the ring.
-     *
-     * @param p point to check for ring inclusion
-     * @param ring an array of coordinates representing the ring (which must have
-     *             first point identical to last point)
+    * Determines whether a point lies in the interior, on the boundary, or in the
+    * exterior of a ring. The ring may be oriented in either direction.
+    *
+    * This method does *not* first check the point against the envelope of
+    * the ring.
+    *
+    * @param p point to check for ring inclusion
+    * @param ring an array of coordinates representing the ring (which must have
+    *             first point identical to last point)
      * @return the [Location](@ref geom::Location) of p relative to the ring
-     */
-    static int locateInRing(const geom::Coordinate& p, const std::vector<const geom::Coordinate*>& ring);
-    static int locateInRing(const geom::Coordinate& p, const geom::CoordinateSequence& ring);
+    */
+    static geom::Location locateInRing(const geom::Coordinate& p, const std::vector<const geom::Coordinate*>& ring);
+    static geom::Location locateInRing(const geom::Coordinate& p, const geom::CoordinateSequence& ring);
 
 };
 
diff --git a/include/geos/algorithm/PointLocator.h b/include/geos/algorithm/PointLocator.h
index 644b6dd..da66f84 100644
--- a/include/geos/algorithm/PointLocator.h
+++ b/include/geos/algorithm/PointLocator.h
@@ -67,7 +67,7 @@ public:
      *
      * @return the Location of the point relative to the input Geometry
      */
-    int locate(const geom::Coordinate& p, const geom::Geometry* geom);
+    geom::Location locate(const geom::Coordinate& p, const geom::Geometry* geom);
 
     /**
      * Convenience method to test a point for intersection with
@@ -91,15 +91,15 @@ private:
 
     void computeLocation(const geom::Coordinate& p, const geom::Geometry* geom);
 
-    void updateLocationInfo(int loc);
+    void updateLocationInfo(geom::Location loc);
 
-    int locate(const geom::Coordinate& p, const geom::Point* pt);
+    geom::Location locate(const geom::Coordinate& p, const geom::Point* pt);
 
-    int locate(const geom::Coordinate& p, const geom::LineString* l);
+    geom::Location locate(const geom::Coordinate& p, const geom::LineString* l);
 
-    int locateInPolygonRing(const geom::Coordinate& p, const geom::LinearRing* ring);
+    geom::Location locateInPolygonRing(const geom::Coordinate& p, const geom::LinearRing* ring);
 
-    int locate(const geom::Coordinate& p, const geom::Polygon* poly);
+    geom::Location locate(const geom::Coordinate& p, const geom::Polygon* poly);
 
 };
 
diff --git a/include/geos/algorithm/RayCrossingCounter.h b/include/geos/algorithm/RayCrossingCounter.h
index d0aef85..1181013 100644
--- a/include/geos/algorithm/RayCrossingCounter.h
+++ b/include/geos/algorithm/RayCrossingCounter.h
@@ -21,6 +21,7 @@
 #define GEOS_ALGORITHM_RAYCROSSINGCOUNTER_H
 
 #include <geos/export.h>
+#include <geos/geom/Location.h>
 
 #include <vector>
 
@@ -87,11 +88,11 @@ public:
      * @param ring an array of Coordinates forming a ring
      * @return the location of the point in the ring
      */
-    static int locatePointInRing(const geom::Coordinate& p,
+    static geom::Location locatePointInRing(const geom::Coordinate& p,
                                  const geom::CoordinateSequence& ring);
 
     /// Semantically equal to the above, just different args encoding
-    static int locatePointInRing(const geom::Coordinate& p,
+    static geom::Location locatePointInRing(const geom::Coordinate& p,
                                  const std::vector<const geom::Coordinate*>& ring);
 
     RayCrossingCounter(const geom::Coordinate& p_point)
@@ -134,7 +135,7 @@ public:
      *
      * @return the Location of the point
      */
-    int getLocation();
+    geom::Location getLocation();
 
     /** \brief
      * Tests whether the point lies in or on the ring, polygon or
diff --git a/include/geos/algorithm/RayCrossingCounterDD.h b/include/geos/algorithm/RayCrossingCounterDD.h
index 95d7de5..2cb4f84 100644
--- a/include/geos/algorithm/RayCrossingCounterDD.h
+++ b/include/geos/algorithm/RayCrossingCounterDD.h
@@ -21,6 +21,7 @@
 #define GEOS_ALGORITHM_RAYCROSSINGCOUNTERDD_H
 
 #include <geos/export.h>
+#include <geos/geom/Location.h>
 #include <geos/algorithm/ttmath/ttmath.h>
 
 #include <vector>
@@ -84,11 +85,11 @@ public:
      * @param ring an array of Coordinates forming a ring
      * @return the location of the point in the ring
      */
-    static int locatePointInRing(const geom::Coordinate& p,
+    static geom::Location locatePointInRing(const geom::Coordinate& p,
                                  const geom::CoordinateSequence& ring);
 
     /// Semantically equal to the above, just different args encoding
-    static int locatePointInRing(const geom::Coordinate& p,
+    static geom::Location locatePointInRing(const geom::Coordinate& p,
                                  const std::vector<const geom::Coordinate*>& ring);
 
     /** \brief
@@ -146,7 +147,7 @@ public:
      *
      * @return the Location of the point
      */
-    int getLocation();
+    geom::Location getLocation();
 
     /** \brief
      * Tests whether the point lies in or on the ring, polygon or multipolygon
diff --git a/include/geos/algorithm/locate/IndexedPointInAreaLocator.h b/include/geos/algorithm/locate/IndexedPointInAreaLocator.h
index 3914e21..f1dc458 100644
--- a/include/geos/algorithm/locate/IndexedPointInAreaLocator.h
+++ b/include/geos/algorithm/locate/IndexedPointInAreaLocator.h
@@ -112,7 +112,7 @@ public:
      * @param p the point to test
      * @return the location of the point in the geometry
      */
-    int locate(const geom::Coordinate* /*const*/ p) override;
+    geom::Location locate(const geom::Coordinate* /*const*/ p) override;
 
 };
 
diff --git a/include/geos/algorithm/locate/PointOnGeometryLocator.h b/include/geos/algorithm/locate/PointOnGeometryLocator.h
index 39e0b7f..c755de4 100644
--- a/include/geos/algorithm/locate/PointOnGeometryLocator.h
+++ b/include/geos/algorithm/locate/PointOnGeometryLocator.h
@@ -16,6 +16,8 @@
 #ifndef GEOS_ALGORITHM_LOCATE_POINTONGEOMETRYLOCATOR_H
 #define GEOS_ALGORITHM_LOCATE_POINTONGEOMETRYLOCATOR_H
 
+#include <geos/geom/Location.h>
+
 namespace geos {
 namespace geom {
 class Coordinate;
@@ -46,7 +48,7 @@ public:
      * @param p the point to test
      * @return the location of the point in the geometry
      */
-    virtual int locate(const geom::Coordinate* /*const*/ p) = 0;
+    virtual geom::Location locate(const geom::Coordinate* /*const*/ p) = 0;
 };
 
 } // geos::algorithm::locate
diff --git a/include/geos/algorithm/locate/SimplePointInAreaLocator.h b/include/geos/algorithm/locate/SimplePointInAreaLocator.h
index 22d7c8f..d1e84ef 100644
--- a/include/geos/algorithm/locate/SimplePointInAreaLocator.h
+++ b/include/geos/algorithm/locate/SimplePointInAreaLocator.h
@@ -48,7 +48,7 @@ class SimplePointInAreaLocator : public PointOnGeometryLocator {
 
 public:
 
-    static int locate(const geom::Coordinate& p,
+    static geom::Location locate(const geom::Coordinate& p,
                       const geom::Geometry* geom);
 
     /** \brief
@@ -67,8 +67,9 @@ public:
      * @param poly the geometry to test
      * @return the Location of the point in the polygon
      */
-    static int locatePointInPolygon(const geom::Coordinate& p,
+    static geom::Location locatePointInPolygon(const geom::Coordinate& p,
                                     const geom::Polygon* poly);
+
     /** \brief
      * Determines whether a point is contained in a [Geometry](@ref geom::Geometry),
      * or lies on its boundary.
@@ -88,7 +89,7 @@ public:
         : g(p_g)
     { }
 
-    int
+    geom::Location
     locate(const geom::Coordinate* p) override
     {
         return locate(*p, g);
@@ -96,7 +97,7 @@ public:
 
 private:
 
-    static int locateInGeometry(const geom::Coordinate& p,
+    static geom::Location locateInGeometry(const geom::Coordinate& p,
                                 const geom::Geometry* geom);
 
     const geom::Geometry* g;
diff --git a/include/geos/geom/IntersectionMatrix.h b/include/geos/geom/IntersectionMatrix.h
index e1c1dcb..a2353c7 100644
--- a/include/geos/geom/IntersectionMatrix.h
+++ b/include/geos/geom/IntersectionMatrix.h
@@ -19,7 +19,10 @@
 #ifndef GEOS_GEOM_INTERSECTIONMATRIX_H
 #define GEOS_GEOM_INTERSECTIONMATRIX_H
 
+#include <geos/geom/Location.h>
+
 #include <geos/export.h>
+#include <array>
 #include <string>
 
 #include <geos/inline.h>
@@ -143,7 +146,7 @@ public:
      *        second Geometry.
      * @param dimensionValue - the new value of the element.
      */
-    void set(int row, int column, int dimensionValue);
+    void set(Location row, Location column, int dimensionValue);
 
     /** \brief
      * Changes the elements of this IntersectionMatrix to the dimension
@@ -167,7 +170,7 @@ public:
      *        to compare the element.  The order of dimension values
      *        from least to greatest is {DONTCARE, TRUE, FALSE, 0, 1, 2}.
      */
-    void setAtLeast(size_t row, size_t column, int minimumDimensionValue);
+    void setAtLeast(Location row, Location column, int minimumDimensionValue);
 
     /** \brief
      * If row >= 0 and column >= 0, changes the specified element
@@ -189,7 +192,7 @@ public:
      *        to compare the element. The order of dimension values
      *        from least to greatest is {DONTCARE, TRUE, FALSE, 0, 1, 2}.
      */
-    void setAtLeastIfValid(int row, int column, int minimumDimensionValue);
+    void setAtLeastIfValid(Location row, Location column, int minimumDimensionValue);
 
     /** \brief
      * For each element in this IntersectionMatrix, changes the element to
@@ -226,7 +229,9 @@ public:
      *
      * @return the dimension value at the given matrix position.
      */
-    int get(int row, int column) const;
+    int get(geom::Location row, geom::Location column) const {
+        return matrix[static_cast<size_t>(row)][static_cast<size_t>(column)];
+    }
 
     /** \brief
      * Returns true if this IntersectionMatrix is FF*FF****.
@@ -368,7 +373,7 @@ private:
     static const int secondDim; // = 3;
 
     // Internal buffer for 3x3 matrix.
-    int matrix[3][3];
+    std::array<std::array<int, 3>, 3> matrix;
 
 }; // class IntersectionMatrix
 
diff --git a/include/geos/geom/Location.h b/include/geos/geom/Location.h
index 359bb9b..896a4dd 100644
--- a/include/geos/geom/Location.h
+++ b/include/geos/geom/Location.h
@@ -31,46 +31,38 @@ namespace geom { // geos::geom
  *  HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple Features
  *  Specification for SQL</A> .
  */
-class GEOS_DLL Location {
-public:
-    enum Value {
+enum class GEOS_DLL Location : char {
+    /**
+     *  Used for uninitialized location values.
+     */
+    UNDEF = -1, // Instead of NULL
 
-        /**
-         *  Used for uninitialized location values.
-         */
-        UNDEF = -1, // Instead of NULL
+    /**
+     * DE-9IM row index of the interior of the first geometry and
+     * column index of the interior of the second geometry.
+     * Location value for the interior of a geometry.
+     */
+    INTERIOR = 0,
 
-        /**
-         * DE-9IM row index of the interior of the first geometry and
-         * column index of the interior of the second geometry.
-         * Location value for the interior of a geometry.
-         */
-        INTERIOR = 0,
+    /**
+     * DE-9IM row index of the boundary of the first geometry and
+     * column index of the boundary of the second geometry.
+     * Location value for the boundary of a geometry.
+     */
+    BOUNDARY = 1,
 
-        /**
-         * DE-9IM row index of the boundary of the first geometry and
-         * column index of the boundary of the second geometry.
-         * Location value for the boundary of a geometry.
-         */
-        BOUNDARY = 1,
-
-        /**
-         * DE-9IM row index of the exterior of the first geometry and
-         * column index of the exterior of the second geometry.
-         * Location value for the exterior of a geometry.
-         */
-        EXTERIOR = 2
-    };
-
-    static char toLocationSymbol(int locationValue);
+    /**
+     * DE-9IM row index of the exterior of the first geometry and
+     * column index of the exterior of the second geometry.
+     * Location value for the exterior of a geometry.
+     */
+    EXTERIOR = 2
 };
 
+std::ostream& operator<<(std::ostream& os, const Location& loc);
+
 } // namespace geos::geom
 } // namespace geos
 
-//#ifdef GEOS_INLINE
-//# include "geos/geom/Location.inl"
-//#endif
-
 #endif // ndef GEOS_GEOM_LOCATION_H
 
diff --git a/include/geos/geom/prep/AbstractPreparedPolygonContains.h b/include/geos/geom/prep/AbstractPreparedPolygonContains.h
index 9325bfa..95a1fd2 100644
--- a/include/geos/geom/prep/AbstractPreparedPolygonContains.h
+++ b/include/geos/geom/prep/AbstractPreparedPolygonContains.h
@@ -106,7 +106,7 @@ protected:
      * @param outermostLoc outermost Location of all points in geom
      * @return true if the test geometry is contained/covered in the target
      */
-    bool evalPointTestGeom(const geom::Geometry* geom, geom::Location::Value outermostLoc);
+    bool evalPointTestGeom(const geom::Geometry* geom, geom::Location outermostLoc);
 
     /**
      * Computes the full topological predicate.
diff --git a/include/geos/geom/prep/PreparedPolygonPredicate.h b/include/geos/geom/prep/PreparedPolygonPredicate.h
index d983982..7fb9710 100644
--- a/include/geos/geom/prep/PreparedPolygonPredicate.h
+++ b/include/geos/geom/prep/PreparedPolygonPredicate.h
@@ -71,7 +71,7 @@ protected:
      * @param testGeom a geometry to test
      * @return the outermost Location
      */
-    geom::Location::Value getOutermostTestComponentLocation(const geom::Geometry* testGeom) const;
+    geom::Location getOutermostTestComponentLocation(const geom::Geometry* testGeom) const;
 
     /** \brief
      * Tests whether all components of the test Geometry
diff --git a/include/geos/geomgraph/Depth.h b/include/geos/geomgraph/Depth.h
index cb247f9..371b0a1 100644
--- a/include/geos/geomgraph/Depth.h
+++ b/include/geos/geomgraph/Depth.h
@@ -22,6 +22,7 @@
 #define GEOS_GEOMGRAPH_DEPTH_H
 
 #include <geos/export.h>
+#include <geos/geom/Location.h>
 #include <string>
 
 #include <geos/inline.h>
@@ -38,13 +39,13 @@ namespace geomgraph { // geos.geomgraph
 
 class GEOS_DLL Depth {
 public:
-    static int depthAtLocation(int location);
+    static int depthAtLocation(geom::Location location);
     Depth();
     virtual ~Depth(); // FIXME: shoudn't be virtual!
     int getDepth(int geomIndex, int posIndex) const;
     void setDepth(int geomIndex, int posIndex, int depthValue);
-    int getLocation(int geomIndex, int posIndex) const;
-    void add(int geomIndex, int posIndex, int location);
+    geom::Location getLocation(int geomIndex, int posIndex) const;
+    void add(int geomIndex, int posIndex, geom::Location location);
     bool isNull() const;
     bool isNull(int geomIndex) const;
     bool isNull(int geomIndex, int posIndex) const;
diff --git a/include/geos/geomgraph/DirectedEdge.h b/include/geos/geomgraph/DirectedEdge.h
index 74cf390..5f2ba1e 100644
--- a/include/geos/geomgraph/DirectedEdge.h
+++ b/include/geos/geomgraph/DirectedEdge.h
@@ -25,6 +25,7 @@
 #include <geos/export.h>
 #include <string>
 
+#include <geos/geom/Location.h>
 #include <geos/geomgraph/EdgeEnd.h> // for inheritance
 
 #include <geos/inline.h>
@@ -51,7 +52,7 @@ public:
      * E.g. if crossing from the INTERIOR to the EXTERIOR the depth
      * decreases, so the factor is -1
      */
-    static int depthFactor(int currLocation, int nextLocation);
+    static int depthFactor(geom::Location currLocation, geom::Location nextLocation);
 
     //DirectedEdge();
     //virtual ~DirectedEdge();
diff --git a/include/geos/geomgraph/EdgeEndStar.h b/include/geos/geomgraph/EdgeEndStar.h
index 28dd076..054ddc2 100644
--- a/include/geos/geomgraph/EdgeEndStar.h
+++ b/include/geos/geomgraph/EdgeEndStar.h
@@ -24,10 +24,12 @@
 
 #include <geos/export.h>
 #include <geos/geomgraph/EdgeEnd.h>  // for EdgeEndLT
+#include <geos/geom/Location.h>
 #include <geos/geom/Coordinate.h>  // for p0,p1
 
 #include <geos/inline.h>
 
+#include <array>
 #include <set>
 #include <string>
 #include <vector>
@@ -148,15 +150,15 @@ protected:
 
 private:
 
-    virtual int getLocation(int geomIndex,
-                            const geom::Coordinate& p,
-                            std::vector<GeometryGraph*>* geom);
+    virtual geom::Location getLocation(int geomIndex,
+                                       const geom::Coordinate& p,
+                                       std::vector<GeometryGraph*>* geom);
 
     /** \brief
      * The location of the point for this star in
      * Geometry i Areas
      */
-    int ptInAreaLocation[2];
+    std::array<geom::Location, 2> ptInAreaLocation;
 
     virtual void computeEdgeEndLabels(const algorithm::BoundaryNodeRule&);
 
diff --git a/include/geos/geomgraph/GeometryGraph.h b/include/geos/geomgraph/GeometryGraph.h
index a1e70f8..a33b4d5 100644
--- a/include/geos/geomgraph/GeometryGraph.h
+++ b/include/geos/geomgraph/GeometryGraph.h
@@ -123,14 +123,14 @@ private:
     void addPoint(const geom::Point* p);
 
     void addPolygonRing(const geom::LinearRing* lr,
-                        int cwLeft, int cwRight);
+                        geom::Location cwLeft, geom::Location cwRight);
 
     void addPolygon(const geom::Polygon* p);
 
     void addLineString(const geom::LineString* line);
 
     void insertPoint(int argIndex, const geom::Coordinate& coord,
-                     int onLocation);
+                     geom::Location onLocation);
 
     /** \brief
      * Adds candidate boundary points using the current
@@ -151,7 +151,7 @@ private:
      * Otherwise, just add it as a regular node.
      */
     void addSelfIntersectionNode(int argIndex,
-                                 const geom::Coordinate& coord, int loc);
+                                 const geom::Coordinate& coord, geom::Location loc);
 
     // Declare type as noncopyable
     GeometryGraph(const GeometryGraph& other) = delete;
@@ -161,9 +161,9 @@ public:
 
     static bool isInBoundary(int boundaryCount);
 
-    static int determineBoundary(int boundaryCount);
+    static geom::Location determineBoundary(int boundaryCount);
 
-    static int determineBoundary(
+    static geom::Location determineBoundary(
         const algorithm::BoundaryNodeRule& boundaryNodeRule,
         int boundaryCount);
 
diff --git a/include/geos/geomgraph/Label.h b/include/geos/geomgraph/Label.h
index b9a1a07..0582460 100644
--- a/include/geos/geomgraph/Label.h
+++ b/include/geos/geomgraph/Label.h
@@ -22,6 +22,7 @@
 #define GEOS_GEOMGRAPH_LABEL_H
 
 #include <geos/export.h>
+#include <geos/geom/Location.h>
 #include <geos/geomgraph/TopologyLocation.h>
 
 #include <geos/inline.h>
@@ -70,7 +71,7 @@ public:
     /** \brief
      * Construct a Label with a single location for both Geometries.
      */
-    Label(int onLoc);
+    Label(geom::Location onLoc);
 
     /** \brief
      * Construct a Label with the location specified
@@ -79,14 +80,14 @@ public:
      * Other geometry location will be set to
      * Location::UNDEF.
      */
-    Label(int geomIndex, int onLoc);
+    Label(int geomIndex, geom::Location onLoc);
 
     /** \brief
      * Construct a Label with On, Left and Right locations for both Geometries.
      *
      * Initialize the locations for both Geometries to the given values.
      */
-    Label(int onLoc, int leftLoc, int rightLoc);
+    Label(geom::Location onLoc, geom::Location leftLoc, geom::Location rightLoc);
 
     /// Copy ctor
     Label(const Label& l);
@@ -106,23 +107,23 @@ public:
      * Initialize the locations for the other Geometry to
      * Location::UNDEF
      */
-    Label(int geomIndex, int onLoc, int leftLoc, int rightLoc);
+    Label(int geomIndex, geom::Location onLoc, geom::Location leftLoc, geom::Location rightLoc);
 
     void flip();
 
-    int getLocation(int geomIndex, int posIndex) const;
+    geom::Location getLocation(int geomIndex, int posIndex) const;
 
-    int getLocation(int geomIndex) const;
+    geom::Location getLocation(int geomIndex) const;
 
-    void setLocation(int geomIndex, int posIndex, int location);
+    void setLocation(int geomIndex, int posIndex, geom::Location location);
 
-    void setLocation(int geomIndex, int location);
+    void setLocation(int geomIndex, geom::Location location);
 
-    void setAllLocations(int geomIndex, int location);
+    void setAllLocations(int geomIndex, geom::Location location);
 
-    void setAllLocationsIfNull(int geomIndex, int location);
+    void setAllLocationsIfNull(int geomIndex, geom::Location location);
 
-    void setAllLocationsIfNull(int location);
+    void setAllLocationsIfNull(geom::Location location);
 
     /** \brief
      * Merge this label with another one.
@@ -148,7 +149,7 @@ public:
 
     bool isEqualOnSide(const Label& lbl, int side) const;
 
-    bool allPositionsEqual(int geomIndex, int loc) const;
+    bool allPositionsEqual(int geomIndex, geom::Location loc) const;
 
     /** \brief
      * Converts one GeometryLocation to a Line location
diff --git a/include/geos/geomgraph/Node.h b/include/geos/geomgraph/Node.h
index 06da110..c28fbad 100644
--- a/include/geos/geomgraph/Node.h
+++ b/include/geos/geomgraph/Node.h
@@ -92,7 +92,7 @@ public:
      */
     virtual void mergeLabel(const Label& label2);
 
-    virtual void setLabel(int argIndex, int onLocation);
+    virtual void setLabel(int argIndex, geom::Location onLocation);
 
     /** \brief
      * Updates the label of a node to BOUNDARY,
@@ -108,7 +108,7 @@ public:
      * in the boundary.
      * The merged location is the maximum of the two input values.
      */
-    virtual int computeMergedLocation(const Label& label2, int eltIndex);
+    virtual geom::Location computeMergedLocation(const Label& label2, int eltIndex);
 
     virtual std::string print();
 
diff --git a/include/geos/geomgraph/TopologyLocation.h b/include/geos/geomgraph/TopologyLocation.h
index 5a568f5..d56803d 100644
--- a/include/geos/geomgraph/TopologyLocation.h
+++ b/include/geos/geomgraph/TopologyLocation.h
@@ -23,6 +23,7 @@
 
 #include <geos/export.h>
 #include <geos/inline.h>
+#include <geos/geom/Location.h>
 
 #include <vector>
 #include <string>
@@ -78,15 +79,15 @@ public:
      *
      * @see Location
      */
-    TopologyLocation(int on, int left, int right);
+    TopologyLocation(geom::Location on, geom::Location left, geom::Location right);
 
-    TopologyLocation(int on);
+    TopologyLocation(geom::Location on);
 
     TopologyLocation(const TopologyLocation& gl);
 
     TopologyLocation& operator= (const TopologyLocation& gl);
 
-    int get(std::size_t posIndex) const;
+    geom::Location get(std::size_t posIndex) const;
 
     /**
      * @return true if all locations are Location::UNDEF
@@ -106,20 +107,20 @@ public:
 
     void flip();
 
-    void setAllLocations(int locValue);
+    void setAllLocations(geom::Location locValue);
 
-    void setAllLocationsIfNull(int locValue);
+    void setAllLocationsIfNull(geom::Location locValue);
 
-    void setLocation(std::size_t locIndex, int locValue);
+    void setLocation(std::size_t locIndex, geom::Location locValue);
 
-    void setLocation(int locValue);
+    void setLocation(geom::Location locValue);
 
     /// Warning: returns reference to owned memory
-    const std::vector<int>& getLocations() const;
+    const std::vector<geom::Location>& getLocations() const;
 
-    void setLocations(int on, int left, int right);
+    void setLocations(geom::Location on, geom::Location left, geom::Location right);
 
-    bool allPositionsEqual(int loc) const;
+    bool allPositionsEqual(geom::Location loc) const;
 
     /** \brief
      * merge updates only the UNDEF attributes of this object
@@ -131,7 +132,7 @@ public:
 
 private:
 
-    std::vector<int> location;
+    std::vector<geom::Location> location;
 };
 
 std::ostream& operator<< (std::ostream&, const TopologyLocation&);
diff --git a/include/geos/operation/buffer/OffsetCurveSetBuilder.h b/include/geos/operation/buffer/OffsetCurveSetBuilder.h
index beb8219..62a1593 100644
--- a/include/geos/operation/buffer/OffsetCurveSetBuilder.h
+++ b/include/geos/operation/buffer/OffsetCurveSetBuilder.h
@@ -21,6 +21,7 @@
 #define GEOS_OP_BUFFER_OFFSETCURVESETBUILDER_H
 
 #include <geos/export.h>
+#include <geos/geom/Location.h>
 
 #include <vector>
 
@@ -98,8 +99,8 @@ private:
      *
      * @param coord is raw offset curve, ownership transferred here
      */
-    void addCurve(geom::CoordinateSequence* coord, int leftLoc,
-                  int rightLoc);
+    void addCurve(geom::CoordinateSequence* coord, geom::Location leftLoc,
+                  geom::Location rightLoc);
 
     void add(const geom::Geometry& g);
 
@@ -133,8 +134,8 @@ private:
      *                   (if it is CW)
      */
     void addPolygonRing(const geom::CoordinateSequence* coord,
-                        double offsetDistance, int side, int cwLeftLoc,
-                        int cwRightLoc);
+                        double offsetDistance, int side, geom::Location cwLeftLoc,
+                        geom::Location cwRightLoc);
 
     /**
      * The ringCoord is assumed to contain no repeated points.
@@ -200,7 +201,7 @@ public:
     /// @param rightLoc right location
     ///
     void addCurves(const std::vector<geom::CoordinateSequence*>& lineList,
-                   int leftLoc, int rightLoc);
+                   geom::Location leftLoc, geom::Location rightLoc);
 
 };
 
diff --git a/include/geos/operation/overlay/OverlayOp.h b/include/geos/operation/overlay/OverlayOp.h
index c9ae800..1a3d4ba 100644
--- a/include/geos/operation/overlay/OverlayOp.h
+++ b/include/geos/operation/overlay/OverlayOp.h
@@ -23,6 +23,7 @@
 
 #include <geos/algorithm/PointLocator.h> // for composition
 #include <geos/geom/Dimension.h> // for Dimension::DimensionType
+#include <geos/geom/Location.h>
 #include <geos/geomgraph/EdgeList.h> // for composition
 #include <geos/geomgraph/PlanarGraph.h> // for inline (GeometryGraph->PlanarGraph)
 #include <geos/operation/GeometryGraphOperation.h> // for inheritance
@@ -118,7 +119,7 @@ public:
     //
     /// @return true if the locations correspond to the opCode
     ///
-    static bool isResultOfOp(int loc0, int loc1, OpCode opCode);
+    static bool isResultOfOp(geom::Location loc0, geom::Location loc1, OpCode opCode);
 
     /// \brief Construct an OverlayOp with the given Geometry args.
     //
diff --git a/include/geos/operation/overlay/validate/FuzzyPointLocator.h b/include/geos/operation/overlay/validate/FuzzyPointLocator.h
index 3d093cc..13f2fbe 100644
--- a/include/geos/operation/overlay/validate/FuzzyPointLocator.h
+++ b/include/geos/operation/overlay/validate/FuzzyPointLocator.h
@@ -61,7 +61,7 @@ public:
 
     FuzzyPointLocator(const geom::Geometry& geom, double nTolerance);
 
-    geom::Location::Value getLocation(const geom::Coordinate& pt);
+    geom::Location getLocation(const geom::Coordinate& pt);
 
 private:
 
diff --git a/include/geos/operation/overlay/validate/OverlayResultValidator.h b/include/geos/operation/overlay/validate/OverlayResultValidator.h
index a4127b8..069b4d6 100644
--- a/include/geos/operation/overlay/validate/OverlayResultValidator.h
+++ b/include/geos/operation/overlay/validate/OverlayResultValidator.h
@@ -113,7 +113,7 @@ private:
     bool testValid(OverlayOp::OpCode overlayOp, const geom::Coordinate& pt);
 
     bool isValidResult(OverlayOp::OpCode overlayOp,
-                       std::vector<geom::Location::Value>& location);
+                       std::vector<geom::Location>& location);
 
     static double computeBoundaryDistanceTolerance(
         const geom::Geometry& g0, const geom::Geometry& g1);
diff --git a/src/algorithm/PointLocation.cpp b/src/algorithm/PointLocation.cpp
index 03dd7cf..ca38f95 100644
--- a/src/algorithm/PointLocation.cpp
+++ b/src/algorithm/PointLocation.cpp
@@ -67,7 +67,7 @@ PointLocation::isInRing(const geom::Coordinate& p,
 }
 
 /* public static */
-int
+geom::Location
 PointLocation::locateInRing(const geom::Coordinate& p,
                             const std::vector<const geom::Coordinate*>& ring)
 {
@@ -75,7 +75,7 @@ PointLocation::locateInRing(const geom::Coordinate& p,
 }
 
 /* public static */
-int
+geom::Location
 PointLocation::locateInRing(const geom::Coordinate& p,
                             const geom::CoordinateSequence& ring)
 {
diff --git a/src/algorithm/PointLocator.cpp b/src/algorithm/PointLocator.cpp
index 6b4ef7c..5854f89 100644
--- a/src/algorithm/PointLocator.cpp
+++ b/src/algorithm/PointLocator.cpp
@@ -38,7 +38,7 @@ namespace geos {
 namespace algorithm { // geos.algorithm
 
 
-int
+Location
 PointLocator::locate(const Coordinate& p, const Geometry* geom)
 {
     if(geom->isEmpty()) {
@@ -108,7 +108,7 @@ PointLocator::computeLocation(const Coordinate& p, const Geometry* geom)
 
 /* private */
 void
-PointLocator::updateLocationInfo(int loc)
+PointLocator::updateLocationInfo(geom::Location loc)
 {
     if(loc == Location::INTERIOR) {
         isIn = true;
@@ -119,7 +119,7 @@ PointLocator::updateLocationInfo(int loc)
 }
 
 /* private */
-int
+Location
 PointLocator::locate(const Coordinate& p, const Point* pt)
 {
     // no point in doing envelope test, since equality test is just as fast
@@ -131,7 +131,7 @@ PointLocator::locate(const Coordinate& p, const Point* pt)
 }
 
 /* private */
-int
+Location
 PointLocator::locate(const Coordinate& p, const LineString* l)
 {
     if(!l->getEnvelopeInternal()->intersects(p)) {
@@ -151,7 +151,7 @@ PointLocator::locate(const Coordinate& p, const LineString* l)
 }
 
 /* private */
-int
+Location
 PointLocator::locateInPolygonRing(const Coordinate& p, const LinearRing* ring)
 {
     if(!ring->getEnvelopeInternal()->intersects(p)) {
@@ -170,7 +170,7 @@ PointLocator::locateInPolygonRing(const Coordinate& p, const LinearRing* ring)
 }
 
 /* private */
-int
+Location
 PointLocator::locate(const Coordinate& p, const Polygon* poly)
 {
     if(poly->isEmpty()) {
@@ -180,7 +180,7 @@ PointLocator::locate(const Coordinate& p, const Polygon* poly)
     const LinearRing* shell = poly->getExteriorRing();
     assert(shell);
 
-    int shellLoc = locateInPolygonRing(p, shell);
+    Location shellLoc = locateInPolygonRing(p, shell);
     if(shellLoc == Location::EXTERIOR) {
         return Location::EXTERIOR;
     }
@@ -191,7 +191,7 @@ PointLocator::locate(const Coordinate& p, const Polygon* poly)
     // now test if the point lies in or on the holes
     for(size_t i = 0, n = poly->getNumInteriorRing(); i < n; ++i) {
         const LinearRing* hole = poly->getInteriorRingN(i);
-        int holeLoc = locateInPolygonRing(p, hole);
+        Location holeLoc = locateInPolygonRing(p, hole);
         if(holeLoc == Location::INTERIOR) {
             return Location::EXTERIOR;
         }
diff --git a/src/algorithm/RayCrossingCounter.cpp b/src/algorithm/RayCrossingCounter.cpp
index a4ae339..06b1eff 100644
--- a/src/algorithm/RayCrossingCounter.cpp
+++ b/src/algorithm/RayCrossingCounter.cpp
@@ -37,7 +37,7 @@ namespace algorithm {
 //
 // public:
 //
-/*static*/ int
+/*static*/ geom::Location
 RayCrossingCounter::locatePointInRing(const geom::Coordinate& point,
                                       const geom::CoordinateSequence& ring)
 {
@@ -56,7 +56,7 @@ RayCrossingCounter::locatePointInRing(const geom::Coordinate& point,
     return rcc.getLocation();
 }
 
-/*static*/ int
+/*static*/ geom::Location
 RayCrossingCounter::locatePointInRing(const geom::Coordinate& point,
                                       const std::vector<const geom::Coordinate*>& ring)
 {
@@ -141,7 +141,7 @@ RayCrossingCounter::countSegment(const geom::Coordinate& p1,
 }
 
 
-int
+geom::Location
 RayCrossingCounter::getLocation()
 {
     if(isPointOnSegment) {
diff --git a/src/algorithm/RayCrossingCounterDD.cpp b/src/algorithm/RayCrossingCounterDD.cpp
index bc9430f..eb8d8fb 100644
--- a/src/algorithm/RayCrossingCounterDD.cpp
+++ b/src/algorithm/RayCrossingCounterDD.cpp
@@ -38,7 +38,7 @@ namespace algorithm {
 // public:
 //
 /*static*/
-int
+geom::Location
 RayCrossingCounterDD::locatePointInRing(const geom::Coordinate& point,
                                         const geom::CoordinateSequence& ring)
 {
@@ -58,7 +58,7 @@ RayCrossingCounterDD::locatePointInRing(const geom::Coordinate& point,
 }
 
 /*static*/
-int
+geom::Location
 RayCrossingCounterDD::locatePointInRing(const geom::Coordinate& point,
                                         const std::vector<const geom::Coordinate*>& ring)
 {
@@ -151,7 +151,7 @@ RayCrossingCounterDD::countSegment(const geom::Coordinate& p1,
 }
 
 
-int
+geom::Location
 RayCrossingCounterDD::getLocation()
 {
     if(isPointOnSegment) {
diff --git a/src/algorithm/locate/IndexedPointInAreaLocator.cpp b/src/algorithm/locate/IndexedPointInAreaLocator.cpp
index 7bd347c..410fa36 100644
--- a/src/algorithm/locate/IndexedPointInAreaLocator.cpp
+++ b/src/algorithm/locate/IndexedPointInAreaLocator.cpp
@@ -96,7 +96,7 @@ IndexedPointInAreaLocator::IndexedPointInAreaLocator(const geom::Geometry& g)
     buildIndex(areaGeom);
 }
 
-int
+geom::Location
 IndexedPointInAreaLocator::locate(const geom::Coordinate* /*const*/ p)
 {
     algorithm::RayCrossingCounter rcc(*p);
diff --git a/src/algorithm/locate/SimplePointInAreaLocator.cpp b/src/algorithm/locate/SimplePointInAreaLocator.cpp
index b08ebc1..8affb66 100644
--- a/src/algorithm/locate/SimplePointInAreaLocator.cpp
+++ b/src/algorithm/locate/SimplePointInAreaLocator.cpp
@@ -37,7 +37,7 @@ namespace locate { // geos.algorithm
  * and multi-element Geometries.  The algorithm for multi-element Geometries
  * is more complex, since it has to take into account the boundaryDetermination rule
  */
-int
+geom::Location
 SimplePointInAreaLocator::locate(const Coordinate& p, const Geometry* geom)
 {
     if(geom->isEmpty()) {
@@ -59,7 +59,7 @@ SimplePointInAreaLocator::isContained(const Coordinate& p, const Geometry* geom)
     return Location::EXTERIOR != locate(p, geom);
 }
 
-int
+geom::Location
 SimplePointInAreaLocator::locateInGeometry(const Coordinate& p, const Geometry* geom)
 {
     if(const Polygon* poly = dynamic_cast<const Polygon*>(geom)) {
@@ -72,7 +72,7 @@ SimplePointInAreaLocator::locateInGeometry(const Coordinate& p, const Geometry*
     if(const GeometryCollection* col = dynamic_cast<const GeometryCollection*>(geom)) {
         for(auto g2 : *col) {
             assert(g2 != geom);
-            int loc = locateInGeometry(p, g2);
+            Location loc = locateInGeometry(p, g2);
             if(loc != Location::EXTERIOR) {
                 return loc;
             }
@@ -81,7 +81,7 @@ SimplePointInAreaLocator::locateInGeometry(const Coordinate& p, const Geometry*
     return Location::EXTERIOR;
 }
 
-int
+geom::Location
 SimplePointInAreaLocator::locatePointInPolygon(const Coordinate& p, const Polygon* poly)
 {
     if(poly->isEmpty()) {
@@ -93,7 +93,7 @@ SimplePointInAreaLocator::locatePointInPolygon(const Coordinate& p, const Polygo
     const LineString* shell = poly->getExteriorRing();
     const CoordinateSequence* cl;
     cl = shell->getCoordinatesRO();
-    int shellLoc = PointLocation::locateInRing(p, *cl);
+    Location shellLoc = PointLocation::locateInRing(p, *cl);
     if(shellLoc != Location::INTERIOR) {
         return shellLoc;
     }
@@ -103,7 +103,7 @@ SimplePointInAreaLocator::locatePointInPolygon(const Coordinate& p, const Polygo
         const LineString* hole = poly->getInteriorRingN(i);
         if(hole->getEnvelopeInternal()->contains(p)) {
             cl = hole->getCoordinatesRO();
-            int holeLoc = RayCrossingCounter::locatePointInRing(p, *cl);
+            Location holeLoc = RayCrossingCounter::locatePointInRing(p, *cl);
             if(holeLoc == Location::BOUNDARY) {
                 return Location::BOUNDARY;
             }
diff --git a/src/geom/IntersectionMatrix.cpp b/src/geom/IntersectionMatrix.cpp
index 740187b..f30216e 100644
--- a/src/geom/IntersectionMatrix.cpp
+++ b/src/geom/IntersectionMatrix.cpp
@@ -50,25 +50,19 @@ IntersectionMatrix::IntersectionMatrix(const string& elements)
 /*public*/
 IntersectionMatrix::IntersectionMatrix(const IntersectionMatrix& other)
 {
-    matrix[Location::INTERIOR][Location::INTERIOR] = other.matrix[Location::INTERIOR][Location::INTERIOR];
-    matrix[Location::INTERIOR][Location::BOUNDARY] = other.matrix[Location::INTERIOR][Location::BOUNDARY];
-    matrix[Location::INTERIOR][Location::EXTERIOR] = other.matrix[Location::INTERIOR][Location::EXTERIOR];
-    matrix[Location::BOUNDARY][Location::INTERIOR] = other.matrix[Location::BOUNDARY][Location::INTERIOR];
-    matrix[Location::BOUNDARY][Location::BOUNDARY] = other.matrix[Location::BOUNDARY][Location::BOUNDARY];
-    matrix[Location::BOUNDARY][Location::EXTERIOR] = other.matrix[Location::BOUNDARY][Location::EXTERIOR];
-    matrix[Location::EXTERIOR][Location::INTERIOR] = other.matrix[Location::EXTERIOR][Location::INTERIOR];
-    matrix[Location::EXTERIOR][Location::BOUNDARY] = other.matrix[Location::EXTERIOR][Location::BOUNDARY];
-    matrix[Location::EXTERIOR][Location::EXTERIOR] = other.matrix[Location::EXTERIOR][Location::EXTERIOR];
+    matrix = other.matrix;
 }
 
 /*public*/
 void
 IntersectionMatrix::add(IntersectionMatrix* other)
 {
-    for(int i = 0; i < firstDim; i++) {
-        for(int j = 0; j < secondDim; j++) {
-            setAtLeast(i, j, other->get(i, j));
+    for(size_t i = 0; i < firstDim; i++) {
+        for(size_t j = 0; j < secondDim; j++) {
+            setAtLeast(static_cast<Location>(i), static_cast<Location>(j),
+                    other->get(static_cast<Location>(i), static_cast<Location>(j)));
         }
+
     }
 }
 
@@ -82,8 +76,8 @@ IntersectionMatrix::matches(const string& requiredDimensionSymbols) const
           << "[" << requiredDimensionSymbols << "] instead" << endl;
         throw util::IllegalArgumentException(s.str());
     }
-    for(int ai = 0; ai < firstDim; ai++) {
-        for(int bi = 0; bi < secondDim; bi++) {
+    for(size_t ai = 0; ai < firstDim; ai++) {
+        for(size_t bi = 0; bi < secondDim; bi++) {
             if(!matches(matrix[ai][bi], requiredDimensionSymbols[3 * ai + bi])) {
                 return false;
             }
@@ -143,12 +137,9 @@ IntersectionMatrix::matches(const string& actualDimensionSymbols,
 
 /*public*/
 void
-IntersectionMatrix::set(int row, int col, int dimensionValue)
+IntersectionMatrix::set(Location row, Location col, int dimensionValue)
 {
-    assert(row >= 0 && row < firstDim);
-    assert(col >= 0 && col < secondDim);
-
-    matrix[row][col] = dimensionValue;
+    matrix[static_cast<size_t>(row)][static_cast<size_t>(col)] = dimensionValue;
 }
 
 /*public*/
@@ -166,24 +157,18 @@ IntersectionMatrix::set(const string& dimensionSymbols)
 
 /*public*/
 void
-IntersectionMatrix::setAtLeast(size_t row, size_t col, int minimumDimensionValue)
+IntersectionMatrix::setAtLeast(Location row, Location col, int minimumDimensionValue)
 {
-    assert(row < firstDim);
-    assert(col < secondDim);
-
-    if(matrix[row][col] < minimumDimensionValue) {
-        matrix[row][col] = minimumDimensionValue;
+    if(get(row, col) < minimumDimensionValue) {
+        set(row, col, minimumDimensionValue);
     }
 }
 
 /*public*/
 void
-IntersectionMatrix::setAtLeastIfValid(int row, int col, int minimumDimensionValue)
+IntersectionMatrix::setAtLeastIfValid(Location row, Location col, int minimumDimensionValue)
 {
-    assert(row >= 0 && row < firstDim);
-    assert(col >= 0 && col < secondDim);
-
-    if(row >= 0 && col >= 0) {
+    if(static_cast<size_t>(row) >= 0 && static_cast<size_t>(col) >= 0) {
         setAtLeast(row, col, minimumDimensionValue);
     }
 }
@@ -195,8 +180,8 @@ IntersectionMatrix::setAtLeast(string minimumDimensionSymbols)
     auto limit = minimumDimensionSymbols.length();
 
     for(size_t i = 0; i < limit; i++) {
-        auto row = i / firstDim;
-        auto col = i % secondDim;
+        auto row = static_cast<Location>(i / firstDim);
+        auto col = static_cast<Location>(i % secondDim);
         setAtLeast(row, col, Dimension::toDimensionValue(minimumDimensionSymbols[i]));
     }
 }
@@ -207,33 +192,23 @@ IntersectionMatrix::setAll(int dimensionValue)
 {
     for(int ai = 0; ai < firstDim; ai++) {
         for(int bi = 0; bi < secondDim; bi++) {
-            matrix[ai][bi] = dimensionValue;
+            set(static_cast<Location>(ai), static_cast<Location>(bi), dimensionValue);
         }
     }
 }
 
 /*public*/
-int
-IntersectionMatrix::get(int row, int col) const
-{
-    assert(row >= 0 && row < firstDim);
-    assert(col >= 0 && col < secondDim);
-
-    return matrix[row][col];
-}
-
-/*public*/
 bool
 IntersectionMatrix::isDisjoint() const
 {
     return
-        matrix[Location::INTERIOR][Location::INTERIOR] == Dimension::False
+        get(Location::INTERIOR, Location::INTERIOR) == Dimension::False
         &&
-        matrix[Location::INTERIOR][Location::BOUNDARY] == Dimension::False
+        get(Location::INTERIOR, Location::BOUNDARY) == Dimension::False
         &&
-        matrix[Location::BOUNDARY][Location::INTERIOR] == Dimension::False
+        get(Location::BOUNDARY, Location::INTERIOR) == Dimension::False
         &&
-        matrix[Location::BOUNDARY][Location::BOUNDARY] == Dimension::False;
+        get(Location::BOUNDARY, Location::BOUNDARY) == Dimension::False;
 }
 
 /*public*/
@@ -261,10 +236,10 @@ IntersectionMatrix::isTouches(int dimensionOfGeometryA,
             (dimensionOfGeometryA == Dimension::P && dimensionOfGeometryB == Dimension::A)
             ||
             (dimensionOfGeometryA == Dimension::P && dimensionOfGeometryB == Dimension::L)) {
-        return matrix[Location::INTERIOR][Location::INTERIOR] == Dimension::False &&
-               (matches(matrix[Location::INTERIOR][Location::BOUNDARY], 'T') ||
-                matches(matrix[Location::BOUNDARY][Location::INTERIOR], 'T') ||
-                matches(matrix[Location::BOUNDARY][Location::BOUNDARY], 'T'));
+        return get(Location::INTERIOR, Location::INTERIOR) == Dimension::False &&
+               (matches(get(Location::INTERIOR, Location::BOUNDARY), 'T') ||
+                matches(get(Location::BOUNDARY, Location::INTERIOR), 'T') ||
+                matches(get(Location::BOUNDARY, Location::BOUNDARY), 'T'));
     }
     return false;
 }
@@ -277,17 +252,17 @@ IntersectionMatrix::isCrosses(int dimensionOfGeometryA,
     if((dimensionOfGeometryA == Dimension::P && dimensionOfGeometryB == Dimension::L) ||
             (dimensionOfGeometryA == Dimension::P && dimensionOfGeometryB == Dimension::A) ||
             (dimensionOfGeometryA == Dimension::L && dimensionOfGeometryB == Dimension::A)) {
-        return matches(matrix[Location::INTERIOR][Location::INTERIOR], 'T') &&
-               matches(matrix[Location::INTERIOR][Location::EXTERIOR], 'T');
+        return matches(get(Location::INTERIOR, Location::INTERIOR), 'T') &&
+               matches(get(Location::INTERIOR, Location::EXTERIOR), 'T');
     }
     if((dimensionOfGeometryA == Dimension::L && dimensionOfGeometryB == Dimension::P) ||
             (dimensionOfGeometryA == Dimension::A && dimensionOfGeometryB == Dimension::P) ||
             (dimensionOfGeometryA == Dimension::A && dimensionOfGeometryB == Dimension::L)) {
-        return matches(matrix[Location::INTERIOR][Location::INTERIOR], 'T') &&
-               matches(matrix[Location::EXTERIOR][Location::INTERIOR], 'T');
+        return matches(get(Location::INTERIOR, Location::INTERIOR), 'T') &&
+               matches(get(Location::EXTERIOR, Location::INTERIOR), 'T');
     }
     if(dimensionOfGeometryA == Dimension::L && dimensionOfGeometryB == Dimension::L) {
-        return matrix[Location::INTERIOR][Location::INTERIOR] == 0;
+        return get(Location::INTERIOR, Location::INTERIOR) == 0;
     }
     return false;
 }
@@ -296,18 +271,18 @@ IntersectionMatrix::isCrosses(int dimensionOfGeometryA,
 bool
 IntersectionMatrix::isWithin() const
 {
-    return matches(matrix[Location::INTERIOR][Location::INTERIOR], 'T') &&
-           matrix[Location::INTERIOR][Location::EXTERIOR] == Dimension::False &&
-           matrix[Location::BOUNDARY][Location::EXTERIOR] == Dimension::False;
+    return matches(get(Location::INTERIOR, Location::INTERIOR), 'T') &&
+           get(Location::INTERIOR, Location::EXTERIOR) == Dimension::False &&
+           get(Location::BOUNDARY, Location::EXTERIOR) == Dimension::False;
 }
 
 /*public*/
 bool
 IntersectionMatrix::isContains() const
 {
-    return matches(matrix[Location::INTERIOR][Location::INTERIOR], 'T') &&
-           matrix[Location::EXTERIOR][Location::INTERIOR] == Dimension::False &&
-           matrix[Location::EXTERIOR][Location::BOUNDARY] == Dimension::False;
+    return matches(get(Location::INTERIOR, Location::INTERIOR), 'T') &&
+           get(Location::EXTERIOR, Location::INTERIOR) == Dimension::False &&
+           get(Location::EXTERIOR, Location::BOUNDARY) == Dimension::False;
 }
 
 /*public*/
@@ -318,11 +293,11 @@ IntersectionMatrix::isEquals(int dimensionOfGeometryA,
     if(dimensionOfGeometryA != dimensionOfGeometryB) {
         return false;
     }
-    return matches(matrix[Location::INTERIOR][Location::INTERIOR], 'T') &&
-           matrix[Location::EXTERIOR][Location::INTERIOR] == Dimension::False &&
-           matrix[Location::INTERIOR][Location::EXTERIOR] == Dimension::False &&
-           matrix[Location::EXTERIOR][Location::BOUNDARY] == Dimension::False &&
-           matrix[Location::BOUNDARY][Location::EXTERIOR] == Dimension::False;
+    return matches(get(Location::INTERIOR, Location::INTERIOR), 'T') &&
+           get(Location::EXTERIOR, Location::INTERIOR) == Dimension::False &&
+           get(Location::INTERIOR, Location::EXTERIOR) == Dimension::False &&
+           get(Location::EXTERIOR, Location::BOUNDARY) == Dimension::False &&
+           get(Location::BOUNDARY, Location::EXTERIOR) == Dimension::False;
 }
 
 /*public*/
@@ -332,14 +307,14 @@ IntersectionMatrix::isOverlaps(int dimensionOfGeometryA,
 {
     if((dimensionOfGeometryA == Dimension::P && dimensionOfGeometryB == Dimension::P) ||
             (dimensionOfGeometryA == Dimension::A && dimensionOfGeometryB == Dimension::A)) {
-        return matches(matrix[Location::INTERIOR][Location::INTERIOR], 'T') &&
-               matches(matrix[Location::INTERIOR][Location::EXTERIOR], 'T') &&
-               matches(matrix[Location::EXTERIOR][Location::INTERIOR], 'T');
+        return matches(get(Location::INTERIOR, Location::INTERIOR), 'T') &&
+               matches(get(Location::INTERIOR, Location::EXTERIOR), 'T') &&
+               matches(get(Location::EXTERIOR, Location::INTERIOR), 'T');
     }
     if(dimensionOfGeometryA == Dimension::L && dimensionOfGeometryB == Dimension::L) {
-        return matrix[Location::INTERIOR][Location::INTERIOR] == 1 &&
-               matches(matrix[Location::INTERIOR][Location::EXTERIOR], 'T') &&
-               matches(matrix[Location::EXTERIOR][Location::INTERIOR], 'T');
+        return get(Location::INTERIOR, Location::INTERIOR) == 1 &&
+               matches(get(Location::INTERIOR, Location::EXTERIOR), 'T') &&
+               matches(get(Location::EXTERIOR, Location::INTERIOR), 'T');
     }
     return false;
 }
@@ -349,20 +324,20 @@ bool
 IntersectionMatrix::isCovers() const
 {
     bool hasPointInCommon =
-        matches(matrix[Location::INTERIOR][Location::INTERIOR], 'T')
+        matches(get(Location::INTERIOR, Location::INTERIOR), 'T')
         ||
-        matches(matrix[Location::INTERIOR][Location::BOUNDARY], 'T')
+        matches(get(Location::INTERIOR, Location::BOUNDARY), 'T')
         ||
-        matches(matrix[Location::BOUNDARY][Location::INTERIOR], 'T')
+        matches(get(Location::BOUNDARY, Location::INTERIOR), 'T')
         ||
-        matches(matrix[Location::BOUNDARY][Location::BOUNDARY], 'T');
+        matches(get(Location::BOUNDARY, Location::BOUNDARY), 'T');
 
     return hasPointInCommon
            &&
-           matrix[Location::EXTERIOR][Location::INTERIOR] ==
+           get(Location::EXTERIOR, Location::INTERIOR) ==
            Dimension::False
            &&
-           matrix[Location::EXTERIOR][Location::BOUNDARY] ==
+           get(Location::EXTERIOR, Location::BOUNDARY) ==
            Dimension::False;
 }
 
@@ -371,21 +346,21 @@ bool
 IntersectionMatrix::isCoveredBy() const
 {
     bool hasPointInCommon =
-        matches(matrix[Location::INTERIOR][Location::INTERIOR], 'T')
+        matches(get(Location::INTERIOR, Location::INTERIOR), 'T')
         ||
-        matches(matrix[Location::INTERIOR][Location::BOUNDARY], 'T')
+        matches(get(Location::INTERIOR, Location::BOUNDARY), 'T')
         ||
-        matches(matrix[Location::BOUNDARY][Location::INTERIOR], 'T')
+        matches(get(Location::BOUNDARY, Location::INTERIOR), 'T')
         ||
-        matches(matrix[Location::BOUNDARY][Location::BOUNDARY], 'T');
+        matches(get(Location::BOUNDARY, Location::BOUNDARY), 'T');
 
     return
         hasPointInCommon
         &&
-        matrix[Location::INTERIOR][Location::EXTERIOR] ==
+        get(Location::INTERIOR, Location::EXTERIOR) ==
         Dimension::False
         &&
-        matrix[Location::BOUNDARY][Location::EXTERIOR] ==
+        get(Location::BOUNDARY, Location::EXTERIOR) ==
         Dimension::False;
 }
 
@@ -410,8 +385,8 @@ string
 IntersectionMatrix::toString() const
 {
     string result("");
-    for(int ai = 0; ai < firstDim; ai++) {
-        for(int bi = 0; bi < secondDim; bi++) {
+    for(size_t ai = 0; ai < firstDim; ai++) {
+        for(size_t bi = 0; bi < secondDim; bi++) {
             result += Dimension::toDimensionSymbol(matrix[ai][bi]);
         }
     }
diff --git a/src/geom/Location.cpp b/src/geom/Location.cpp
index cd1d51d..d96ef93 100644
--- a/src/geom/Location.cpp
+++ b/src/geom/Location.cpp
@@ -22,29 +22,24 @@ using namespace std;
 namespace geos {
 namespace geom { // geos::geom
 
-/**
- *  Converts the location value to a location symbol, for example, <code>EXTERIOR => 'e'</code>.
- *
- *@param  locationValue  either EXTERIOR, BOUNDARY, INTERIOR or NULL
- *@return                either 'e', 'b', 'i' or '-'
- */
-char
-Location::toLocationSymbol(int locationValue)
+std::ostream&
+operator<<(std::ostream& os, const Location& loc)
 {
-    switch(locationValue) {
-    case EXTERIOR:
-        return 'e';
-    case BOUNDARY:
-        return 'b';
-    case INTERIOR:
-        return 'i';
-    case UNDEF: //NULL
-        return '-';
-    default:
-        ostringstream s;
-        s << "Unknown location value: " << locationValue;
-        throw util::IllegalArgumentException(s.str());
+    switch(loc) {
+        case Location::EXTERIOR:
+            os << 'e';
+            break;
+        case Location::BOUNDARY:
+            os << 'b';
+            break;
+        case Location::INTERIOR:
+            os << 'i';
+            break;
+        case Location::UNDEF:
+            os << '-';
+            break;
     }
+    return os;
 }
 
 } // namespace geos::geom
diff --git a/src/geom/prep/AbstractPreparedPolygonContains.cpp b/src/geom/prep/AbstractPreparedPolygonContains.cpp
index 2cf2c6a..314a3bd 100644
--- a/src/geom/prep/AbstractPreparedPolygonContains.cpp
+++ b/src/geom/prep/AbstractPreparedPolygonContains.cpp
@@ -181,8 +181,7 @@ AbstractPreparedPolygonContains::eval(const geom::Geometry* geom)
     return true;
 }
 
-bool AbstractPreparedPolygonContains::evalPointTestGeom(const Geometry *geom,
-                                                      Location::Value outermostLoc) {
+bool AbstractPreparedPolygonContains::evalPointTestGeom(const Geometry *geom, Location outermostLoc) {
     // If we had a point on the ourside of the polygon,
     // we aren't covered or contained.
     if (outermostLoc == Location::EXTERIOR) {
diff --git a/src/geom/prep/PreparedPolygonPredicate.cpp b/src/geom/prep/PreparedPolygonPredicate.cpp
index cd6d4c5..83f8257 100644
--- a/src/geom/prep/PreparedPolygonPredicate.cpp
+++ b/src/geom/prep/PreparedPolygonPredicate.cpp
@@ -39,16 +39,16 @@ namespace prep { // geos.geom.prep
 // protected:
 //
 struct LocationMatchingFilter : public GeometryComponentFilter {
-    explicit LocationMatchingFilter(algorithm::locate::PointOnGeometryLocator* locator, int loc) :
+    explicit LocationMatchingFilter(algorithm::locate::PointOnGeometryLocator* locator, Location loc) :
         pt_locator(locator), test_loc(loc), found(false) {}
 
     algorithm::locate::PointOnGeometryLocator* pt_locator;
-    const int test_loc;
+    const Location test_loc;
     bool found;
 
     void filter_ro(const Geometry* g) override {
         const Coordinate* pt = g->getCoordinate();
-        const int loc = pt_locator->locate(pt);
+        const auto loc = pt_locator->locate(pt);
 
         if (loc == test_loc) {
             found = true;
@@ -61,16 +61,16 @@ struct LocationMatchingFilter : public GeometryComponentFilter {
 };
 
 struct LocationNotMatchingFilter : public GeometryComponentFilter {
-    explicit LocationNotMatchingFilter(algorithm::locate::PointOnGeometryLocator* locator, int loc) :
+    explicit LocationNotMatchingFilter(algorithm::locate::PointOnGeometryLocator* locator, Location loc) :
             pt_locator(locator), test_loc(loc), found(false) {}
 
     algorithm::locate::PointOnGeometryLocator* pt_locator;
-    const int test_loc;
+    const Location test_loc;
     bool found;
 
     void filter_ro(const Geometry* g) override {
         const Coordinate* pt = g->getCoordinate();
-        const int loc = pt_locator->locate(pt);
+        const auto loc = pt_locator->locate(pt);
 
         if (loc != test_loc) {
             found = true;
@@ -89,12 +89,12 @@ struct OutermostLocationFilter : public GeometryComponentFilter {
     done(false) {}
 
     algorithm::locate::PointOnGeometryLocator* pt_locator;
-    Location::Value outermost_loc;
+    Location outermost_loc;
     bool done;
 
     void filter_ro(const Geometry* g) override {
         const Coordinate* pt = g->getCoordinate();
-        auto loc = static_cast<Location::Value>(pt_locator->locate(pt));
+        auto loc = pt_locator->locate(pt);
 
         if (outermost_loc == Location::UNDEF || outermost_loc == Location::INTERIOR) {
             outermost_loc = loc;
@@ -108,12 +108,12 @@ struct OutermostLocationFilter : public GeometryComponentFilter {
         return done;
     }
 
-    Location::Value getOutermostLocation() {
+    Location getOutermostLocation() {
         return outermost_loc;
     }
 };
 
-Location::Value
+Location
 PreparedPolygonPredicate::getOutermostTestComponentLocation(const geom::Geometry* testGeom) const
 {
     OutermostLocationFilter filter(prepPoly->getPointLocator());
@@ -161,7 +161,7 @@ PreparedPolygonPredicate::isAnyTargetComponentInAreaTest(
 
     for(std::size_t i = 0, ni = targetRepPts->size(); i < ni; i++) {
         const geom::Coordinate* pt = (*targetRepPts)[i];
-        const int loc = piaLoc.locate(pt);
+        const Location loc = piaLoc.locate(pt);
         if(geom::Location::EXTERIOR != loc) {
             return true;
         }
diff --git a/src/geomgraph/Depth.cpp b/src/geomgraph/Depth.cpp
index e86fa48..a9bd7d2 100644
--- a/src/geomgraph/Depth.cpp
+++ b/src/geomgraph/Depth.cpp
@@ -34,7 +34,7 @@ namespace geos {
 namespace geomgraph { // geos.geomgraph
 
 int
-Depth::depthAtLocation(int location)
+Depth::depthAtLocation(geom::Location location)
 {
     if(location == Location::EXTERIOR) {
         return 0;
@@ -72,7 +72,7 @@ Depth::setDepth(int geomIndex, int posIndex, int depthValue)
     depth[geomIndex][posIndex] = depthValue;
 }
 
-int
+Location
 Depth::getLocation(int geomIndex, int posIndex) const
 {
     if(depth[geomIndex][posIndex] <= 0) {
@@ -82,7 +82,7 @@ Depth::getLocation(int geomIndex, int posIndex) const
 }
 
 void
-Depth::add(int geomIndex, int posIndex, int location)
+Depth::add(int geomIndex, int posIndex, Location location)
 {
     if(location == Location::INTERIOR) {
         depth[geomIndex][posIndex]++;
@@ -159,7 +159,7 @@ Depth::add(const Label& lbl)
 {
     for(int i = 0; i < 2; i++) {
         for(int j = 1; j < 3; j++) {
-            int loc = lbl.getLocation(i, j);
+            Location loc = lbl.getLocation(i, j);
             if(loc == Location::EXTERIOR || loc == Location::INTERIOR) {
                 // initialize depth if it is null, otherwise
                 // add this location value
diff --git a/src/geomgraph/DirectedEdge.cpp b/src/geomgraph/DirectedEdge.cpp
index 6e0307e..5e94845 100644
--- a/src/geomgraph/DirectedEdge.cpp
+++ b/src/geomgraph/DirectedEdge.cpp
@@ -44,7 +44,7 @@ namespace geomgraph { // geos.geomgraph
 
 /* public static */
 int
-DirectedEdge::depthFactor(int currLocation, int nextLocation)
+DirectedEdge::depthFactor(Location currLocation, Location nextLocation)
 {
     if(currLocation == Location::EXTERIOR && nextLocation == Location::INTERIOR) {
         return 1;
diff --git a/src/geomgraph/DirectedEdgeStar.cpp b/src/geomgraph/DirectedEdgeStar.cpp
index 60fbf84..e4c7827 100644
--- a/src/geomgraph/DirectedEdgeStar.cpp
+++ b/src/geomgraph/DirectedEdgeStar.cpp
@@ -155,7 +155,7 @@ DirectedEdgeStar::computeLabelling(std::vector<GeometryGraph*>* geom)
         assert(e);
         const Label& eLabel = e->getLabel();
         for(int i = 0; i < 2; ++i) {
-            int eLoc = eLabel.getLocation(i);
+            Location eLoc = eLabel.getLocation(i);
             if(eLoc == Location::INTERIOR || eLoc == Location::BOUNDARY) {
                 label.setLocation(i, Location::INTERIOR);
             }
@@ -378,7 +378,7 @@ DirectedEdgeStar::findCoveredLineEdges()
      * - INTERIOR if the edge is outgoing
      * - EXTERIOR if the edge is incoming
      */
-    int startLoc = Location::UNDEF;
+    Location startLoc = Location::UNDEF;
 
     EdgeEndStar::iterator endIt = end();
     for(EdgeEndStar::iterator it = begin(); it != endIt; ++it) {
@@ -411,7 +411,7 @@ DirectedEdgeStar::findCoveredLineEdges()
      * (Interior or Exterior) for the result area.
      * If L edges are found, mark them as covered if they are in the interior
      */
-    int currLoc = startLoc;
+    Location currLoc = startLoc;
     for(EdgeEndStar::iterator it = begin(); it != endIt; ++it) {
         assert(*it);
         assert(dynamic_cast<DirectedEdge*>(*it));
diff --git a/src/geomgraph/EdgeEndStar.cpp b/src/geomgraph/EdgeEndStar.cpp
index 4d601d0..b3a67ff 100644
--- a/src/geomgraph/EdgeEndStar.cpp
+++ b/src/geomgraph/EdgeEndStar.cpp
@@ -163,7 +163,7 @@ EdgeEndStar::computeLabelling(std::vector<GeometryGraph*>* geomGraph)
         Label& label = e->getLabel();
         for(int geomi = 0; geomi < 2; ++geomi) {
             if(label.isAnyNull(geomi)) {
-                int loc = Location::UNDEF;
+                Location loc = Location::UNDEF;
                 if(hasDimensionalCollapseEdge[geomi]) {
                     loc = Location::EXTERIOR;
                 }
@@ -191,7 +191,7 @@ EdgeEndStar::computeEdgeEndLabels(
 }
 
 /*public*/
-int
+Location
 EdgeEndStar::getLocation(int geomIndex,
                          const Coordinate& p, std::vector<GeometryGraph*>* geom)
 {
@@ -227,12 +227,12 @@ EdgeEndStar::checkAreaLabelsConsistent(int geomIndex)
     // initialize startLoc to location of last L side (if any)
     assert(*rbegin());
     const Label& startLabel = (*rbegin())->getLabel();
-    int startLoc = startLabel.getLocation(geomIndex, Position::LEFT);
+    Location startLoc = startLabel.getLocation(geomIndex, Position::LEFT);
 
     // Found unlabelled area edge
     assert(startLoc != Location::UNDEF);
 
-    int currLoc = startLoc;
+    Location currLoc = startLoc;
 
     for(EdgeEndStar::iterator it = begin(), itEnd = end(); it != itEnd; ++it) {
         EdgeEnd* e = *it;
@@ -244,8 +244,8 @@ EdgeEndStar::checkAreaLabelsConsistent(int geomIndex)
         // Found non-area edge
         assert(eLabel.isArea(geomIndex));
 
-        int leftLoc = eLabel.getLocation(geomIndex, Position::LEFT);
-        int rightLoc = eLabel.getLocation(geomIndex, Position::RIGHT);
+        Location leftLoc = eLabel.getLocation(geomIndex, Position::LEFT);
+        Location rightLoc = eLabel.getLocation(geomIndex, Position::RIGHT);
         // check that edge is really a boundary between inside and outside!
         if(leftLoc == rightLoc) {
             return false;
@@ -268,7 +268,7 @@ EdgeEndStar::propagateSideLabels(int geomIndex)
     // Since edges are stored in CCW order around the node,
     // As we move around the ring we move from the right to the
     // left side of the edge
-    int startLoc = Location::UNDEF;
+    Location startLoc = Location::UNDEF;
 
     EdgeEndStar::iterator beginIt = begin();
     EdgeEndStar::iterator endIt = end();
@@ -290,7 +290,7 @@ EdgeEndStar::propagateSideLabels(int geomIndex)
         return;
     }
 
-    int currLoc = startLoc;
+    Location currLoc = startLoc;
     for(it = beginIt; it != endIt; ++it) {
         EdgeEnd* e = *it;
         assert(e);
@@ -303,11 +303,11 @@ EdgeEndStar::propagateSideLabels(int geomIndex)
         // set side labels (if any)
         // if (label.isArea())  //ORIGINAL
         if(label.isArea(geomIndex)) {
-            int leftLoc = label.getLocation(geomIndex,
-                                            Position::LEFT);
+            Location leftLoc = label.getLocation(geomIndex,
+                                                 Position::LEFT);
 
-            int rightLoc = label.getLocation(geomIndex,
-                                             Position::RIGHT);
+            Location rightLoc = label.getLocation(geomIndex,
+                                                  Position::RIGHT);
 
             // if there is a right location, that is the next
             // location to propagate
diff --git a/src/geomgraph/EdgeRing.cpp b/src/geomgraph/EdgeRing.cpp
index 89d2749..e6e54c9 100644
--- a/src/geomgraph/EdgeRing.cpp
+++ b/src/geomgraph/EdgeRing.cpp
@@ -307,7 +307,7 @@ EdgeRing::mergeLabel(const Label& deLabel, int geomIndex)
 
     testInvariant();
 
-    int loc = deLabel.getLocation(geomIndex, Position::RIGHT);
+    Location loc = deLabel.getLocation(geomIndex, Position::RIGHT);
     // no information to be had from this label
     if(loc == Location::UNDEF) {
         return;
diff --git a/src/geomgraph/GeometryGraph.cpp b/src/geomgraph/GeometryGraph.cpp
index eaa140b..c5b14c3 100644
--- a/src/geomgraph/GeometryGraph.cpp
+++ b/src/geomgraph/GeometryGraph.cpp
@@ -91,7 +91,7 @@ GeometryGraph::isInBoundary(int boundaryCount)
     return boundaryCount % 2 == 1;
 }
 
-int
+Location
 GeometryGraph::determineBoundary(int boundaryCount)
 {
     return isInBoundary(boundaryCount) ? Location::BOUNDARY : Location::INTERIOR;
@@ -236,7 +236,7 @@ GeometryGraph::addPoint(const Point* p)
  * the left and right locations must be interchanged.
  */
 void
-GeometryGraph::addPolygonRing(const LinearRing* lr, int cwLeft, int cwRight)
+GeometryGraph::addPolygonRing(const LinearRing* lr, Location cwLeft, Location cwRight)
 // throw IllegalArgumentException (see below)
 {
     // skip empty component (see bug #234)
@@ -252,8 +252,8 @@ GeometryGraph::addPolygonRing(const LinearRing* lr, int cwLeft, int cwRight)
         invalidPoint = coord->getAt(0); // its now a Coordinate
         return;
     }
-    int left = cwLeft;
-    int right = cwRight;
+    Location left = cwLeft;
+    Location right = cwRight;
 
     /*
      * the isCCW call might throw an
@@ -430,7 +430,7 @@ GeometryGraph::computeEdgeIntersections(GeometryGraph* g,
 
 void
 GeometryGraph::insertPoint(int p_argIndex, const Coordinate& coord,
-                           int onLocation)
+                           geom::Location onLocation)
 {
 #if GEOS_DEBUG > 1
     cerr << "GeometryGraph::insertPoint(" << coord.toString() << " called" << endl;
@@ -462,14 +462,14 @@ GeometryGraph::insertBoundaryPoint(int p_argIndex, const Coordinate& coord)
     int boundaryCount = 1;
 
     // determine the current location for the point (if any)
-    int loc = lbl.getLocation(p_argIndex, Position::ON);
+    Location loc = lbl.getLocation(p_argIndex, Position::ON);
     if(loc == Location::BOUNDARY) {
         boundaryCount++;
     }
 
     // determine the boundary status of the point according to the
     // Boundary Determination Rule
-    int newLoc = determineBoundary(boundaryNodeRule, boundaryCount);
+    Location newLoc = determineBoundary(boundaryNodeRule, boundaryCount);
     lbl.setLocation(p_argIndex, newLoc);
 }
 
@@ -480,7 +480,7 @@ GeometryGraph::addSelfIntersectionNodes(int p_argIndex)
     for(vector<Edge*>::iterator i = edges->begin(), endIt = edges->end();
             i != endIt; ++i) {
         Edge* e = *i;
-        int eLoc = e->getLabel().getLocation(p_argIndex);
+        Location eLoc = e->getLabel().getLocation(p_argIndex);
         EdgeIntersectionList& eiL = e->eiList;
         for(EdgeIntersectionList::iterator
                 eiIt = eiL.begin(), eiEnd = eiL.end();
@@ -495,7 +495,7 @@ GeometryGraph::addSelfIntersectionNodes(int p_argIndex)
 /*private*/
 void
 GeometryGraph::addSelfIntersectionNode(int p_argIndex,
-                                       const Coordinate& coord, int loc)
+                                       const Coordinate& coord, Location loc)
 {
     // if this node is already a boundary node, don't change it
     if(isBoundaryNode(p_argIndex, coord)) {
@@ -571,7 +571,7 @@ GeometryGraph::GeometryGraph()
 
 
 /* public static */
-int
+Location
 GeometryGraph::determineBoundary(
     const algorithm::BoundaryNodeRule& boundaryNodeRule,
     int boundaryCount)
diff --git a/src/geomgraph/Label.cpp b/src/geomgraph/Label.cpp
index b8c14a8..d0a05cb 100644
--- a/src/geomgraph/Label.cpp
+++ b/src/geomgraph/Label.cpp
@@ -46,14 +46,14 @@ Label::toLineLabel(const Label& label)
 }
 
 /*public*/
-Label::Label(int onLoc)
+Label::Label(Location onLoc)
 {
     elt[0] = TopologyLocation(onLoc);
     elt[1] = TopologyLocation(onLoc);
 }
 
 /*public*/
-Label::Label(int geomIndex, int onLoc)
+Label::Label(int geomIndex, Location onLoc)
 {
     assert(geomIndex >= 0 && geomIndex < 2);
     elt[0] = TopologyLocation(Location::UNDEF);
@@ -62,7 +62,7 @@ Label::Label(int geomIndex, int onLoc)
 }
 
 /*public*/
-Label::Label(int onLoc, int leftLoc, int rightLoc)
+Label::Label(Location onLoc, Location leftLoc, Location rightLoc)
 {
     elt[0] = TopologyLocation(onLoc, leftLoc, rightLoc);
     elt[1] = TopologyLocation(onLoc, leftLoc, rightLoc);
@@ -92,7 +92,7 @@ Label::operator=(const Label& l)
 }
 
 /*public*/
-Label::Label(int geomIndex, int onLoc, int leftLoc, int rightLoc)
+Label::Label(int geomIndex, Location onLoc, Location leftLoc, Location rightLoc)
 {
     elt[0] = TopologyLocation(Location::UNDEF, Location::UNDEF, Location::UNDEF);
     elt[1] = TopologyLocation(Location::UNDEF, Location::UNDEF, Location::UNDEF);
@@ -108,7 +108,7 @@ Label::flip()
 }
 
 /*public*/
-int
+Location
 Label::getLocation(int geomIndex, int posIndex) const
 {
     assert(geomIndex >= 0 && geomIndex < 2);
@@ -116,7 +116,7 @@ Label::getLocation(int geomIndex, int posIndex) const
 }
 
 /*public*/
-int
+Location
 Label::getLocation(int geomIndex) const
 {
     assert(geomIndex >= 0 && geomIndex < 2);
@@ -125,7 +125,7 @@ Label::getLocation(int geomIndex) const
 
 /*public*/
 void
-Label::setLocation(int geomIndex, int posIndex, int location)
+Label::setLocation(int geomIndex, int posIndex, Location location)
 {
     assert(geomIndex >= 0 && geomIndex < 2);
     elt[geomIndex].setLocation(posIndex, location);
@@ -133,7 +133,7 @@ Label::setLocation(int geomIndex, int posIndex, int location)
 
 /*public*/
 void
-Label::setLocation(int geomIndex, int location)
+Label::setLocation(int geomIndex, Location location)
 {
     assert(geomIndex >= 0 && geomIndex < 2);
     elt[geomIndex].setLocation(Position::ON, location);
@@ -141,7 +141,7 @@ Label::setLocation(int geomIndex, int location)
 
 /*public*/
 void
-Label::setAllLocations(int geomIndex, int location)
+Label::setAllLocations(int geomIndex, Location location)
 {
     assert(geomIndex >= 0 && geomIndex < 2);
     elt[geomIndex].setAllLocations(location);
@@ -149,7 +149,7 @@ Label::setAllLocations(int geomIndex, int location)
 
 /*public*/
 void
-Label::setAllLocationsIfNull(int geomIndex, int location)
+Label::setAllLocationsIfNull(int geomIndex, Location location)
 {
     assert(geomIndex >= 0 && geomIndex < 2);
     elt[geomIndex].setAllLocationsIfNull(location);
@@ -157,7 +157,7 @@ Label::setAllLocationsIfNull(int geomIndex, int location)
 
 /*public*/
 void
-Label::setAllLocationsIfNull(int location)
+Label::setAllLocationsIfNull(Location location)
 {
     setAllLocationsIfNull(0, location);
     setAllLocationsIfNull(1, location);
@@ -243,7 +243,7 @@ Label::isEqualOnSide(const Label& lbl, int side) const
 
 /*public*/
 bool
-Label::allPositionsEqual(int geomIndex, int loc) const
+Label::allPositionsEqual(int geomIndex, Location loc) const
 {
     assert(geomIndex >= 0 && geomIndex < 2);
     return elt[geomIndex].allPositionsEqual(loc);
diff --git a/src/geomgraph/Node.cpp b/src/geomgraph/Node.cpp
index 40209b3..fcd8a21 100644
--- a/src/geomgraph/Node.cpp
+++ b/src/geomgraph/Node.cpp
@@ -175,8 +175,8 @@ void
 Node::mergeLabel(const Label& label2)
 {
     for(int i = 0; i < 2; i++) {
-        int loc = computeMergedLocation(label2, i);
-        int thisLoc = label.getLocation(i);
+        Location loc = computeMergedLocation(label2, i);
+        Location thisLoc = label.getLocation(i);
         if(thisLoc == Location::UNDEF) {
             label.setLocation(i, loc);
         }
@@ -186,7 +186,7 @@ Node::mergeLabel(const Label& label2)
 
 /*public*/
 void
-Node::setLabel(int argIndex, int onLocation)
+Node::setLabel(int argIndex, Location onLocation)
 {
     if(label.isNull()) {
         label = Label(argIndex, onLocation);
@@ -202,9 +202,9 @@ Node::setLabel(int argIndex, int onLocation)
 void
 Node::setLabelBoundary(int argIndex)
 {
-    int loc = label.getLocation(argIndex);
+    Location loc = label.getLocation(argIndex);
     // flip the loc
-    int newLoc;
+    Location newLoc;
     switch(loc) {
     case Location::BOUNDARY:
         newLoc = Location::INTERIOR;
@@ -222,13 +222,13 @@ Node::setLabelBoundary(int argIndex)
 }
 
 /*public*/
-int
+Location
 Node::computeMergedLocation(const Label& label2, int eltIndex)
 {
-    int loc = Location::UNDEF;
+    Location loc = Location::UNDEF;
     loc = label.getLocation(eltIndex);
     if(!label2.isNull(eltIndex)) {
-        int nLoc = label2.getLocation(eltIndex);
+        Location nLoc = label2.getLocation(eltIndex);
         if(loc != Location::BOUNDARY) {
             loc = nLoc;
         }
diff --git a/src/geomgraph/TopologyLocation.cpp b/src/geomgraph/TopologyLocation.cpp
index 173237d..a7e0918 100644
--- a/src/geomgraph/TopologyLocation.cpp
+++ b/src/geomgraph/TopologyLocation.cpp
@@ -49,7 +49,7 @@ TopologyLocation::~TopologyLocation()
 }
 
 /*public*/
-TopologyLocation::TopologyLocation(int on, int left, int right):
+TopologyLocation::TopologyLocation(Location on, Location left, Location right):
     location(3)
 {
     location[Position::ON] = on;
@@ -58,7 +58,7 @@ TopologyLocation::TopologyLocation(int on, int left, int right):
 }
 
 /*public*/
-TopologyLocation::TopologyLocation(int on):
+TopologyLocation::TopologyLocation(Location on):
     location(1, on)
 {
     //(*location)[Position::ON]=on;
@@ -80,7 +80,7 @@ TopologyLocation::operator= (const TopologyLocation& gl)
 }
 
 /*public*/
-int
+Location
 TopologyLocation::get(size_t posIndex) const
 {
     // should be an assert() instead ?
@@ -142,14 +142,12 @@ TopologyLocation::flip()
     if(location.size() <= 1) {
         return;
     }
-    int temp = location[Position::LEFT];
-    location[Position::LEFT] = location[Position::RIGHT];
-    location[Position::RIGHT] = temp;
+    std::swap(location[Position::LEFT], location[Position::RIGHT]);
 }
 
 /*public*/
 void
-TopologyLocation::setAllLocations(int locValue)
+TopologyLocation::setAllLocations(Location locValue)
 {
     for(size_t i = 0, sz = location.size(); i < sz; ++i) {
         location[i] = locValue;
@@ -158,7 +156,7 @@ TopologyLocation::setAllLocations(int locValue)
 
 /*public*/
 void
-TopologyLocation::setAllLocationsIfNull(int locValue)
+TopologyLocation::setAllLocationsIfNull(Location locValue)
 {
     for(size_t i = 0, sz = location.size(); i < sz; ++i) {
         if(location[i] == Location::UNDEF) {
@@ -169,20 +167,20 @@ TopologyLocation::setAllLocationsIfNull(int locValue)
 
 /*public*/
 void
-TopologyLocation::setLocation(size_t locIndex, int locValue)
+TopologyLocation::setLocation(size_t locIndex, Location locValue)
 {
     location[locIndex] = locValue;
 }
 
 /*public*/
 void
-TopologyLocation::setLocation(int locValue)
+TopologyLocation::setLocation(Location locValue)
 {
     setLocation(Position::ON, locValue);
 }
 
 /*public*/
-const vector<int>&
+const vector<Location>&
 TopologyLocation::getLocations() const
 {
     return location;
@@ -190,7 +188,7 @@ TopologyLocation::getLocations() const
 
 /*public*/
 void
-TopologyLocation::setLocations(int on, int left, int right)
+TopologyLocation::setLocations(Location on, Location left, Location right)
 {
     assert(location.size() >= 3);
     location[Position::ON] = on;
@@ -200,7 +198,7 @@ TopologyLocation::setLocations(int on, int left, int right)
 
 /*public*/
 bool
-TopologyLocation::allPositionsEqual(int loc) const
+TopologyLocation::allPositionsEqual(Location loc) const
 {
     for(size_t i = 0, sz = location.size(); i < sz; ++i) {
         if(location[i] != loc) {
@@ -241,11 +239,11 @@ std::ostream&
 operator<< (std::ostream& os, const TopologyLocation& tl)
 {
     if(tl.location.size() > 1) {
-        os << Location::toLocationSymbol(tl.location[Position::LEFT]);
+        os << tl.location[Position::LEFT];
     }
-    os << Location::toLocationSymbol(tl.location[Position::ON]);
+    os << tl.location[Position::ON];
     if(tl.location.size() > 1) {
-        os << Location::toLocationSymbol(tl.location[Position::RIGHT]);
+        os << tl.location[Position::RIGHT];
     }
     return os;
 }
diff --git a/src/operation/buffer/BufferBuilder.cpp b/src/operation/buffer/BufferBuilder.cpp
index e35a0c2..0bc6d7e 100644
--- a/src/operation/buffer/BufferBuilder.cpp
+++ b/src/operation/buffer/BufferBuilder.cpp
@@ -109,8 +109,8 @@ static Profiler* profiler = Profiler::instance();
 int
 BufferBuilder::depthDelta(const Label& label)
 {
-    int lLoc = label.getLocation(0, Position::LEFT);
-    int rLoc = label.getLocation(0, Position::RIGHT);
+    Location lLoc = label.getLocation(0, Position::LEFT);
+    Location rLoc = label.getLocation(0, Position::RIGHT);
     if(lLoc == Location::INTERIOR && rLoc == Location::EXTERIOR) {
         return 1;
     }
diff --git a/src/operation/buffer/OffsetCurveSetBuilder.cpp b/src/operation/buffer/OffsetCurveSetBuilder.cpp
index ed3522c..bbc50b3 100644
--- a/src/operation/buffer/OffsetCurveSetBuilder.cpp
+++ b/src/operation/buffer/OffsetCurveSetBuilder.cpp
@@ -92,7 +92,7 @@ OffsetCurveSetBuilder::getCurves()
 /*public*/
 void
 OffsetCurveSetBuilder::addCurves(const std::vector<CoordinateSequence*>& lineList,
-                                 int leftLoc, int rightLoc)
+                                 geom::Location leftLoc, geom::Location rightLoc)
 {
     for(size_t i = 0, n = lineList.size(); i < n; ++i) {
         CoordinateSequence* coords = lineList[i];
@@ -103,7 +103,7 @@ OffsetCurveSetBuilder::addCurves(const std::vector<CoordinateSequence*>& lineLis
 /*private*/
 void
 OffsetCurveSetBuilder::addCurve(CoordinateSequence* coord,
-                                int leftLoc, int rightLoc)
+                                geom::Location leftLoc, geom::Location rightLoc)
 {
 #if GEOS_DEBUG
     std::cerr << __FUNCTION__ << ": coords=" << coord->toString() << std::endl;
@@ -281,7 +281,7 @@ OffsetCurveSetBuilder::addPolygon(const Polygon* p)
 /* private */
 void
 OffsetCurveSetBuilder::addPolygonRing(const CoordinateSequence* coord,
-                                      double offsetDistance, int side, int cwLeftLoc, int cwRightLoc)
+                                      double offsetDistance, int side, geom::Location cwLeftLoc, geom::Location cwRightLoc)
 {
 
     // don't bother adding ring if it is "flat" and
@@ -290,8 +290,8 @@ OffsetCurveSetBuilder::addPolygonRing(const CoordinateSequence* coord,
         return;
     }
 
-    int leftLoc = cwLeftLoc;
-    int rightLoc = cwRightLoc;
+    Location leftLoc = cwLeftLoc;
+    Location rightLoc = cwRightLoc;
 #if GEOS_DEBUG
     std::cerr << "OffsetCurveSetBuilder::addPolygonRing: CCW: " << Orientation::isCCW(coord) << std::endl;
 #endif
diff --git a/src/operation/overlay/LineBuilder.cpp b/src/operation/overlay/LineBuilder.cpp
index 99512fd..372c382 100644
--- a/src/operation/overlay/LineBuilder.cpp
+++ b/src/operation/overlay/LineBuilder.cpp
@@ -305,7 +305,7 @@ LineBuilder::labelIsolatedLines(vector<Edge*>* edgesList)
 void
 LineBuilder::labelIsolatedLine(Edge* e, int targetIndex)
 {
-    int loc = ptLocator->locate(e->getCoordinate(),
+    Location loc = ptLocator->locate(e->getCoordinate(),
                                 op->getArgGeometry(targetIndex));
     e->getLabel().setLocation(targetIndex, loc);
 }
diff --git a/src/operation/overlay/OverlayOp.cpp b/src/operation/overlay/OverlayOp.cpp
index 65274a6..13361a1 100644
--- a/src/operation/overlay/OverlayOp.cpp
+++ b/src/operation/overlay/OverlayOp.cpp
@@ -97,15 +97,15 @@ OverlayOp::overlayOp(const Geometry* geom0, const Geometry* geom1,
 bool
 OverlayOp::isResultOfOp(const Label& label, OverlayOp::OpCode opCode)
 {
-    int loc0 = label.getLocation(0);
-    int loc1 = label.getLocation(1);
+    Location loc0 = label.getLocation(0);
+    Location loc1 = label.getLocation(1);
     return isResultOfOp(loc0, loc1, opCode);
 }
 
 
 /* static public */
 bool
-OverlayOp::isResultOfOp(int loc0, int loc1, OverlayOp::OpCode opCode)
+OverlayOp::isResultOfOp(Location loc0, Location loc1, OverlayOp::OpCode opCode)
 {
     if(loc0 == Location::BOUNDARY) {
         loc0 = Location::INTERIOR;
@@ -406,7 +406,7 @@ OverlayOp::labelIncompleteNode(Node* n, int targetIndex)
     cerr << "OverlayOp::labelIncompleteNode(" << n->print() << ", " << targetIndex << ")" << endl;
 #endif
     const Geometry* targetGeom = arg[targetIndex]->getGeometry();
-    int loc = ptLocator.locate(n->getCoordinate(), targetGeom);
+    Location loc = ptLocator.locate(n->getCoordinate(), targetGeom);
     n->getLabel().setLocation(targetIndex, loc);
 
 #if GEOS_DEBUG
@@ -606,7 +606,7 @@ OverlayOp::isCovered(const Coordinate& coord, vector<Geometry*>* geomList)
 {
     for(size_t i = 0, n = geomList->size(); i < n; ++i) {
         Geometry* geom = (*geomList)[i];
-        int loc = ptLocator.locate(coord, geom);
+        Location loc = ptLocator.locate(coord, geom);
         if(loc != Location::EXTERIOR) {
             return true;
         }
@@ -620,7 +620,7 @@ OverlayOp::isCovered(const Coordinate& coord, vector<LineString*>* geomList)
 {
     for(size_t i = 0, n = geomList->size(); i < n; ++i) {
         Geometry* geom = (Geometry*)(*geomList)[i];
-        int loc = ptLocator.locate(coord, geom);
+        Location loc = ptLocator.locate(coord, geom);
         if(loc != Location::EXTERIOR) {
             return true;
         }
@@ -634,7 +634,7 @@ OverlayOp::isCovered(const Coordinate& coord, vector<Polygon*>* geomList)
 {
     for(size_t i = 0, n = geomList->size(); i < n; ++i) {
         Geometry* geom = (Geometry*)(*geomList)[i];
-        int loc = ptLocator.locate(coord, geom);
+        Location loc = ptLocator.locate(coord, geom);
         if(loc != Location::EXTERIOR) {
             return true;
         }
@@ -1015,7 +1015,7 @@ struct PointCoveredByAny: public geom::CoordinateFilter {
     filter_ro(const Coordinate* coord) override
     {
         for(size_t i = 0, n = geoms.size(); i < n; ++i) {
-            int loc = locator.locate(*coord, geoms[i]);
+            Location loc = locator.locate(*coord, geoms[i]);
             if(loc == Location::INTERIOR ||
                     loc == Location::BOUNDARY) {
                 return;
diff --git a/src/operation/overlay/validate/FuzzyPointLocator.cpp b/src/operation/overlay/validate/FuzzyPointLocator.cpp
index 4abac71..e9cc604 100644
--- a/src/operation/overlay/validate/FuzzyPointLocator.cpp
+++ b/src/operation/overlay/validate/FuzzyPointLocator.cpp
@@ -123,7 +123,7 @@ FuzzyPointLocator::getLineWork(const geom::Geometry& geom)
 }
 
 /* public */
-Location::Value
+Location
 FuzzyPointLocator::getLocation(const Coordinate& pt)
 {
     unique_ptr<Geometry> point(g.getFactory()->createPoint(pt));
@@ -138,10 +138,7 @@ FuzzyPointLocator::getLocation(const Coordinate& pt)
 
     // now we know point must be clearly inside or outside geometry,
     // so return actual location value
-
-    // (the static_cast is needed because PointLocator doesn't cleanly
-    // return a Location::Value - it should !!)
-    return static_cast<Location::Value>(ptLocator.locate(pt, &g));
+    return ptLocator.locate(pt, &g);
 }
 
 } // namespace geos.operation.overlay.validate
diff --git a/src/operation/overlay/validate/OverlayResultValidator.cpp b/src/operation/overlay/validate/OverlayResultValidator.cpp
index 5900cb5..44e3974 100644
--- a/src/operation/overlay/validate/OverlayResultValidator.cpp
+++ b/src/operation/overlay/validate/OverlayResultValidator.cpp
@@ -172,7 +172,8 @@ bool
 OverlayResultValidator::testValid(OverlayOp::OpCode overlayOp,
                                   const Coordinate& pt)
 {
-    std::vector<geom::Location::Value> location(3);
+    // TODO use std::array<geom::Location, 3> ?
+    std::vector<geom::Location> location(3);
 
     location[0] = fpl0.getLocation(pt);
     location[1] = fpl1.getLocation(pt);
@@ -203,7 +204,7 @@ OverlayResultValidator::testValid(OverlayOp::OpCode overlayOp,
 /* private */
 bool
 OverlayResultValidator::isValidResult(OverlayOp::OpCode overlayOp,
-                                      std::vector<geom::Location::Value>& location)
+                                      std::vector<geom::Location>& location)
 {
     bool expectedInterior = OverlayOp::isResultOfOp(location[0],
                             location[1], overlayOp);
diff --git a/src/operation/relate/EdgeEndBundle.cpp b/src/operation/relate/EdgeEndBundle.cpp
index 81f3a14..3f458d8 100644
--- a/src/operation/relate/EdgeEndBundle.cpp
+++ b/src/operation/relate/EdgeEndBundle.cpp
@@ -115,7 +115,7 @@ EdgeEndBundle::computeLabelOn(int geomIndex, const algorithm::BoundaryNodeRule&
 
     for(vector<EdgeEnd*>::iterator it = edgeEnds->begin(); it < edgeEnds->end(); it++) {
         EdgeEnd* e = *it;
-        int loc = e->getLabel().getLocation(geomIndex);
+        Location loc = e->getLabel().getLocation(geomIndex);
         if(loc == Location::BOUNDARY) {
             boundaryCount++;
         }
@@ -123,7 +123,7 @@ EdgeEndBundle::computeLabelOn(int geomIndex, const algorithm::BoundaryNodeRule&
             foundInterior = true;
         }
     }
-    int loc = Location::UNDEF;
+    Location loc = Location::UNDEF;
     if(foundInterior) {
         loc = Location::INTERIOR;
     }
@@ -165,7 +165,7 @@ EdgeEndBundle::computeLabelSide(int geomIndex, int side)
     for(vector<EdgeEnd*>::iterator it = edgeEnds->begin(); it < edgeEnds->end(); it++) {
         EdgeEnd* e = *it;
         if(e->getLabel().isArea()) {
-            int loc = e->getLabel().getLocation(geomIndex, side);
+            Location loc = e->getLabel().getLocation(geomIndex, side);
             if(loc == Location::INTERIOR) {
                 label.setLocation(geomIndex, side, Location::INTERIOR);
                 return;
diff --git a/src/operation/relate/RelateComputer.cpp b/src/operation/relate/RelateComputer.cpp
index edc010e..fbe5b4c 100644
--- a/src/operation/relate/RelateComputer.cpp
+++ b/src/operation/relate/RelateComputer.cpp
@@ -346,7 +346,7 @@ RelateComputer::computeIntersectionNodes(int argIndex)
     std::vector<Edge*>* edges = (*arg)[argIndex]->getEdges();
     for(std::vector<Edge*>::iterator i = edges->begin(); i < edges->end(); i++) {
         Edge* e = *i;
-        int eLoc = e->getLabel().getLocation(argIndex);
+        Location eLoc = e->getLabel().getLocation(argIndex);
         EdgeIntersectionList& eiL = e->getEdgeIntersectionList();
         EdgeIntersectionList::iterator it = eiL.begin();
         EdgeIntersectionList::iterator end = eiL.end();
@@ -379,7 +379,7 @@ RelateComputer::labelIntersectionNodes(int argIndex)
     std::vector<Edge*>* edges = (*arg)[argIndex]->getEdges();
     for(std::vector<Edge*>::iterator i = edges->begin(); i < edges->end(); i++) {
         Edge* e = *i;
-        int eLoc = e->getLabel().getLocation(argIndex);
+        Location eLoc = e->getLabel().getLocation(argIndex);
         EdgeIntersectionList& eiL = e->getEdgeIntersectionList();
         EdgeIntersectionList::iterator eiIt = eiL.begin();
         EdgeIntersectionList::iterator eiEnd = eiL.end();
@@ -481,7 +481,7 @@ RelateComputer::labelIsolatedEdge(Edge* e, int targetIndex, const Geometry* targ
         // since edge is not in boundary, may not need the full generality of PointLocator?
         // Possibly should use ptInArea locator instead?  We probably know here
         // that the edge does not touch the bdy of the target Geometry
-        int loc = ptLocator.locate(e->getCoordinate(), target);
+        Location loc = ptLocator.locate(e->getCoordinate(), target);
         e->getLabel().setAllLocations(targetIndex, loc);
     }
     else {
@@ -515,7 +515,7 @@ RelateComputer::labelIsolatedNodes()
 void
 RelateComputer::labelIsolatedNode(Node* n, int targetIndex)
 {
-    int loc = ptLocator.locate(n->getCoordinate(),
+    Location loc = ptLocator.locate(n->getCoordinate(),
                                (*arg)[targetIndex]->getGeometry());
     n->getLabel().setAllLocations(targetIndex, loc);
     //debugPrintln(n.getLabel());
diff --git a/src/operation/relate/RelateNodeGraph.cpp b/src/operation/relate/RelateNodeGraph.cpp
index 28dbd68..270ce16 100644
--- a/src/operation/relate/RelateNodeGraph.cpp
+++ b/src/operation/relate/RelateNodeGraph.cpp
@@ -97,7 +97,7 @@ RelateNodeGraph::computeIntersectionNodes(GeometryGraph* geomGraph,
     vector<Edge*>::iterator edgeIt = edges->begin();
     for(; edgeIt < edges->end(); ++edgeIt) {
         Edge* e = *edgeIt;
-        int eLoc = e->getLabel().getLocation(argIndex);
+        Location eLoc = e->getLabel().getLocation(argIndex);
         EdgeIntersectionList& eiL = e->getEdgeIntersectionList();
         EdgeIntersectionList::iterator eiIt = eiL.begin();
         EdgeIntersectionList::iterator eiEnd = eiL.end();
diff --git a/src/operation/union/PointGeometryUnion.cpp b/src/operation/union/PointGeometryUnion.cpp
index baa6382..83e5e6d 100644
--- a/src/operation/union/PointGeometryUnion.cpp
+++ b/src/operation/union/PointGeometryUnion.cpp
@@ -50,7 +50,7 @@ PointGeometryUnion::Union() const
         const Point* point = dynamic_cast<const Point*>(pointGeom.getGeometryN(i));
         assert(point);
         const Coordinate* coord = point->getCoordinate();
-        int loc = locater.locate(*coord, &otherGeom);
+        Location loc = locater.locate(*coord, &otherGeom);
         if(loc == Location::EXTERIOR) {
             exteriorCoords.insert(*coord);
         }
diff --git a/tests/unit/algorithm/LocatePointInRingTest.cpp b/tests/unit/algorithm/LocatePointInRingTest.cpp
index 7edde30..b75307d 100644
--- a/tests/unit/algorithm/LocatePointInRingTest.cpp
+++ b/tests/unit/algorithm/LocatePointInRingTest.cpp
@@ -50,24 +50,24 @@ static GeometryFactory::Ptr gf = GeometryFactory::create(&pm);
 static geos::io::WKTReader reader(gf.get());
 
 static void
-runPtLocator(int expected, const Coordinate& pt,
+runPtLocator(Location expected, const Coordinate& pt,
              const std::string& wkt)
 {
     std::unique_ptr<Geometry> geom(reader.read(wkt));
     const Polygon* poly = dynamic_cast<Polygon*>(geom.get());
     const CoordinateSequence* cs = poly->getExteriorRing()->getCoordinatesRO();
-    int loc = PointLocation::locateInRing(pt, *cs);
+    Location loc = PointLocation::locateInRing(pt, *cs);
     ensure_equals(loc, expected);
 }
 
 static void
-runPtLocatorDD(int expected, const Coordinate& pt,
+runPtLocatorDD(Location expected, const Coordinate& pt,
                const std::string& wkt)
 {
     std::unique_ptr<Geometry> geom(reader.read(wkt));
     const Polygon* poly = dynamic_cast<Polygon*>(geom.get());
     const CoordinateSequence* cs = poly->getExteriorRing()->getCoordinatesRO();
-    int loc = RayCrossingCounterDD::locatePointInRing(pt, *cs);
+    Location loc = RayCrossingCounterDD::locatePointInRing(pt, *cs);
     ensure_equals(loc, expected);
 }
 
diff --git a/tests/unit/algorithm/PointLocatorTest.cpp b/tests/unit/algorithm/PointLocatorTest.cpp
index 5168448..bc63b07 100644
--- a/tests/unit/algorithm/PointLocatorTest.cpp
+++ b/tests/unit/algorithm/PointLocatorTest.cpp
@@ -47,12 +47,12 @@ static geos::io::WKTReader reader(gf.get());
 typedef std::unique_ptr<Geometry> GeomPtr;
 
 void
-runPtLocator(int expected, const Coordinate& pt,
+runPtLocator(Location expected, const Coordinate& pt,
              const std::string& wkt)
 {
     GeomPtr geom(reader.read(wkt));
     geos::algorithm::PointLocator pointLocator;
-    int loc = pointLocator.locate(pt, geom.get());
+    Location loc = pointLocator.locate(pt, geom.get());
     ensure_equals(loc, expected);
 }
 
diff --git a/tests/unit/geom/IntersectionMatrixTest.cpp b/tests/unit/geom/IntersectionMatrixTest.cpp
index c6bdeae..1e52533 100644
--- a/tests/unit/geom/IntersectionMatrixTest.cpp
+++ b/tests/unit/geom/IntersectionMatrixTest.cpp
@@ -5,6 +5,7 @@
 // geos
 #include <geos/geom/IntersectionMatrix.h>
 #include <geos/geom/Dimension.h>
+#include <geos/geom/Location.h>
 // std
 #include <memory>
 #include <string>
@@ -176,11 +177,13 @@ template<>
 void object::test<11>
 ()
 {
+    using geos::geom::Location;
+
     // 'im_' is initialized with 'FFFFFFFFF'
     ensure_equals(im_.toString(), pattern_false_);
 
     // Do some changes and checks
-    im_.set(0, 0, geos::geom::Dimension::P);
+    im_.set(Location::INTERIOR, Location::INTERIOR, geos::geom::Dimension::P);
 
     ensure_equals(im_.toString(), "0FFFFFFFF");
 
@@ -248,15 +251,17 @@ template<>
 void object::test<15>
 ()
 {
+    using geos::geom::Location;
+
     // 'im_' is initialized with 'FFFFFFFFF'
     ensure_equals(im_.toString(), pattern_false_);
 
     // 1. No change expected
-    im_.setAtLeast(0, 0, geos::geom::Dimension::False);
+    im_.setAtLeast(Location::INTERIOR, Location::INTERIOR, geos::geom::Dimension::False);
     ensure_equals(im_.toString(), pattern_false_);
 
     // 2. Change is expected
-    im_.setAtLeast(0, 0, geos::geom::Dimension::A);
+    im_.setAtLeast(Location::INTERIOR, Location::INTERIOR, geos::geom::Dimension::A);
     ensure_equals(im_.toString(), "2FFFFFFFF");
 }
 
@@ -267,13 +272,15 @@ template<>
 void object::test<16>
 ()
 {
+    using geos::geom::Location;
+
     // 'im_' is initialized with 'FFFFFFFFF'
     ensure_equals(im_.toString(), pattern_false_);
 
     // 1. No change expected
-    im_.setAtLeast(0, 0, geos::geom::Dimension::A);
+    im_.setAtLeast(Location::INTERIOR, Location::INTERIOR, geos::geom::Dimension::A);
     ensure(im_.toString() != pattern_false_);
-    ensure_equals(im_.get(0, 0), geos::geom::Dimension::A);
+    ensure_equals(im_.get(Location::INTERIOR, Location::INTERIOR), geos::geom::Dimension::A);
 }
 
 // Test of get(int row, int column)
@@ -282,17 +289,19 @@ template<>
 void object::test<17>
 ()
 {
-    // Test on the original pattern 'FFFFFFFFF' of the 'im_' object
+    using geos::geom::Location;
+
+    // Test on the original p0attern 'FFFFFFFFF' of the 'im_' object
     ensure_equals(im_.toString(), pattern_false_);
-    ensure_equals(im_.get(0, 0), geos::geom::Dimension::False);
+    ensure_equals(im_.get(Location::INTERIOR, Location::INTERIOR), geos::geom::Dimension::False);
 
     // Change first value and test again
-    im_.setAtLeast(0, 0, geos::geom::Dimension::A);
-    ensure_equals(im_.get(0, 0), geos::geom::Dimension::A);
+    im_.setAtLeast(Location::INTERIOR, Location::INTERIOR, geos::geom::Dimension::A);
+    ensure_equals(im_.get(Location::INTERIOR, Location::INTERIOR), geos::geom::Dimension::A);
 
     // Change last value and test again
-    im_.setAtLeast(2, 2, geos::geom::Dimension::L);
-    ensure_equals(im_.get(2, 2), geos::geom::Dimension::L);
+    im_.setAtLeast(Location::EXTERIOR, Location::EXTERIOR, geos::geom::Dimension::L);
+    ensure_equals(im_.get(Location::EXTERIOR, Location::EXTERIOR), geos::geom::Dimension::L);
 }
 
 
diff --git a/tests/unit/geom/LocationTest.cpp b/tests/unit/geom/LocationTest.cpp
index cdde19d..3a1d0f0 100644
--- a/tests/unit/geom/LocationTest.cpp
+++ b/tests/unit/geom/LocationTest.cpp
@@ -6,6 +6,7 @@
 // geos
 #include <geos/geom/Location.h>
 #include <geos/util/IllegalArgumentException.h>
+#include <sstream>
 
 namespace tut {
 //
@@ -14,10 +15,10 @@ namespace tut {
 
 // Common data used by tests
 struct test_location_data {
-    int undef;
-    int interior;
-    int boundary;
-    int exterior;
+    geos::geom::Location undef;
+    geos::geom::Location interior;
+    geos::geom::Location boundary;
+    geos::geom::Location exterior;
     test_location_data()
         : undef(geos::geom::Location::UNDEF),
           interior(geos::geom::Location::INTERIOR),
@@ -44,7 +45,7 @@ void object::test<1>
     ensure("NOTE: Location has no default constructor.", true);
 }
 
-// Test of toLocationSymbol()
+// Test of << operator
 template<>
 template<>
 void object::test<2>
@@ -52,30 +53,25 @@ void object::test<2>
 {
     using geos::geom::Location;
 
-    ensure_equals(Location::toLocationSymbol(exterior), 'e');
-    ensure_equals(Location::toLocationSymbol(boundary), 'b');
-    ensure_equals(Location::toLocationSymbol(interior), 'i');
-    ensure_equals(Location::toLocationSymbol(undef), '-');
-}
+    std::stringstream s;
 
-// Test of toLocationSymbol() throwing IllegalArgumentException
-template<>
-template<>
-void object::test<3>
-()
-{
-    using geos::geom::Location;
+    s << Location::EXTERIOR;
+    ensure_equals(s.str(), "e");
+    s.str(""); // reset
+    s.clear();
+
+    s << Location::BOUNDARY;
+    ensure_equals(s.str(), "b");
+    s.str(""); // reset
+    s.clear();
 
-    try {
-        Location::toLocationSymbol(101);
-        Location::toLocationSymbol(-101);
+    s << Location::INTERIOR;
+    ensure_equals(s.str(), "i");
+    s.str(""); // reset
+    s.clear();
 
-        fail("IllegalArgumentException expected");
-    }
-    catch(geos::util::IllegalArgumentException const& e) {
-        const char* msg = e.what(); // ok
-        ensure(msg != nullptr);
-    }
+    s << Location::UNDEF;
+    ensure_equals(s.str(), "-");
 }
 
 } // namespace tut

-----------------------------------------------------------------------

Summary of changes:
 include/geos/algorithm/PointLocation.h             |  25 ++--
 include/geos/algorithm/PointLocator.h              |  12 +-
 include/geos/algorithm/RayCrossingCounter.h        |   7 +-
 include/geos/algorithm/RayCrossingCounterDD.h      |   7 +-
 .../algorithm/locate/IndexedPointInAreaLocator.h   |   2 +-
 .../geos/algorithm/locate/PointOnGeometryLocator.h |   4 +-
 .../algorithm/locate/SimplePointInAreaLocator.h    |   9 +-
 include/geos/geom/IntersectionMatrix.h             |  15 ++-
 include/geos/geom/Location.h                       |  58 ++++----
 .../geom/prep/AbstractPreparedPolygonContains.h    |   2 +-
 include/geos/geom/prep/PreparedPolygonPredicate.h  |   2 +-
 include/geos/geomgraph/Depth.h                     |   7 +-
 include/geos/geomgraph/DirectedEdge.h              |   3 +-
 include/geos/geomgraph/EdgeEndStar.h               |  10 +-
 include/geos/geomgraph/GeometryGraph.h             |  10 +-
 include/geos/geomgraph/Label.h                     |  25 ++--
 include/geos/geomgraph/Node.h                      |   4 +-
 include/geos/geomgraph/TopologyLocation.h          |  23 ++--
 .../geos/operation/buffer/OffsetCurveSetBuilder.h  |  11 +-
 include/geos/operation/overlay/OverlayOp.h         |   3 +-
 .../operation/overlay/validate/FuzzyPointLocator.h |   2 +-
 .../overlay/validate/OverlayResultValidator.h      |   2 +-
 src/algorithm/PointLocation.cpp                    |   4 +-
 src/algorithm/PointLocator.cpp                     |  16 +--
 src/algorithm/RayCrossingCounter.cpp               |   6 +-
 src/algorithm/RayCrossingCounterDD.cpp             |   6 +-
 src/algorithm/locate/IndexedPointInAreaLocator.cpp |   2 +-
 src/algorithm/locate/SimplePointInAreaLocator.cpp  |  12 +-
 src/geom/IntersectionMatrix.cpp                    | 149 +++++++++------------
 src/geom/Location.cpp                              |  37 +++--
 src/geom/prep/AbstractPreparedPolygonContains.cpp  |   3 +-
 src/geom/prep/PreparedPolygonPredicate.cpp         |  22 +--
 src/geomgraph/Depth.cpp                            |   8 +-
 src/geomgraph/DirectedEdge.cpp                     |   2 +-
 src/geomgraph/DirectedEdgeStar.cpp                 |   6 +-
 src/geomgraph/EdgeEndStar.cpp                      |  24 ++--
 src/geomgraph/EdgeRing.cpp                         |   2 +-
 src/geomgraph/GeometryGraph.cpp                    |  20 +--
 src/geomgraph/Label.cpp                            |  24 ++--
 src/geomgraph/Node.cpp                             |  16 +--
 src/geomgraph/TopologyLocation.cpp                 |  30 ++---
 src/operation/buffer/BufferBuilder.cpp             |   4 +-
 src/operation/buffer/OffsetCurveSetBuilder.cpp     |  10 +-
 src/operation/overlay/LineBuilder.cpp              |   2 +-
 src/operation/overlay/OverlayOp.cpp                |  16 +--
 .../overlay/validate/FuzzyPointLocator.cpp         |   7 +-
 .../overlay/validate/OverlayResultValidator.cpp    |   5 +-
 src/operation/relate/EdgeEndBundle.cpp             |   6 +-
 src/operation/relate/RelateComputer.cpp            |   8 +-
 src/operation/relate/RelateNodeGraph.cpp           |   2 +-
 src/operation/union/PointGeometryUnion.cpp         |   2 +-
 tests/unit/algorithm/LocatePointInRingTest.cpp     |   8 +-
 tests/unit/algorithm/PointLocatorTest.cpp          |   4 +-
 tests/unit/geom/IntersectionMatrixTest.cpp         |  31 +++--
 tests/unit/geom/LocationTest.cpp                   |  48 +++----
 55 files changed, 383 insertions(+), 402 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list