Skip to content

Commit

Permalink
Add GEOSSegmentIntersection to CAPI
Browse files Browse the repository at this point in the history
Closes #873
Closes #101
  • Loading branch information
dbaston committed Jun 4, 2018
1 parent d1614d4 commit 9c1c5e0
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 0 deletions.
11 changes: 11 additions & 0 deletions capi/geos_c.cpp
Expand Up @@ -1394,4 +1394,15 @@ GEOSVoronoiDiagram(const Geometry *g, const Geometry *env, double tolerance, int
return GEOSVoronoiDiagram_r(handle, g, env, tolerance, onlyEdges);
}

int
GEOSSegmentIntersection(double ax0, double ay0, double ax1, double ay1,
double bx0, double by0, double bx1, double by1,
double* cx, double* cy)
{
return GEOSSegmentIntersection_r(handle,
ax0, ay0, ax1, ay1,
bx0, by0, bx1, by1,
cx, cy);
}

} /* extern "C" */
47 changes: 47 additions & 0 deletions capi/geos_c.h.in
Expand Up @@ -721,6 +721,30 @@ extern GEOSGeometry GEOS_DLL * GEOSVoronoiDiagram_r(
double tolerance,
int onlyEdges);

/*
* Computes the coordinate where two line segments intersect, if any
*
* @param ax0 x-coordinate of first point in first segment
* @param ay0 y-coordinate of first point in first segment
* @param ax1 x-coordinate of second point in first segment
* @param ay1 y-coordinate of second point in first segment
* @param bx0 x-coordinate of first point in second segment
* @param by0 y-coordinate of first point in second segment
* @param bx1 x-coordinate of second point in second segment
* @param by1 y-coordinate of second point in second segment
* @param cx x-coordinate of intersection point
* @param cy y-coordinate of intersection point
*
* @return 0 on error, 1 on success, -1 if segments do not intersect
*/

extern int GEOS_DLL GEOSSegmentIntersection_r(
GEOSContextHandle_t extHandle,
double ax0, double ay0,
double ax1, double ay1,
double bx0, double by0,
double bx1, double by1,
double* cx, double* cy);

/************************************************************************
*
Expand Down Expand Up @@ -1687,6 +1711,29 @@ extern GEOSGeometry GEOS_DLL * GEOSVoronoiDiagram(
const GEOSGeometry *env,
double tolerance,
int onlyEdges);
/*
* Computes the coordinate where two line segments intersect, if any
*
* @param ax0 x-coordinate of first point in first segment
* @param ay0 y-coordinate of first point in first segment
* @param ax1 x-coordinate of second point in first segment
* @param ay1 y-coordinate of second point in first segment
* @param bx0 x-coordinate of first point in second segment
* @param by0 y-coordinate of first point in second segment
* @param bx1 x-coordinate of second point in second segment
* @param by1 y-coordinate of second point in second segment
* @param cx x-coordinate of intersection point
* @param cy y-coordinate of intersection point
*
* @return 0 on error, 1 on success, -1 if segments do not intersect
*/

extern int GEOS_DLL GEOSSegmentIntersection(
double ax0, double ay0,
double ax1, double ay1,
double bx0, double by0,
double bx1, double by1,
double* cx, double* cy);

/************************************************************************
*
Expand Down
44 changes: 44 additions & 0 deletions capi/geos_ts_c.cpp
Expand Up @@ -17,6 +17,7 @@
***********************************************************************/

#include <geos/platform.h> // for FINITE
#include <geos/geom/Coordinate.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/prep/PreparedGeometry.h>
#include <geos/geom/prep/PreparedGeometryFactory.h>
Expand All @@ -27,6 +28,7 @@
#include <geos/geom/MultiLineString.h>
#include <geos/geom/MultiPolygon.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/LineSegment.h>
#include <geos/geom/LineString.h>
#include <geos/geom/PrecisionModel.h>
#include <geos/geom/GeometryFactory.h>
Expand Down Expand Up @@ -7132,5 +7134,47 @@ GEOSVoronoiDiagram_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Ge
return NULL;
}

int
GEOSSegmentIntersection_r(GEOSContextHandle_t extHandle,
double ax0, double ay0, double ax1, double ay1,
double bx0, double by0, double bx1, double by1,
double* cx, double* cy)
{
if ( 0 == extHandle ) return 0;

GEOSContextHandleInternal_t *handle = 0;
handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
if ( 0 == handle->initialized ) return 0;

try
{
geos::geom::LineSegment a(ax0, ay0, ax1, ay1);
geos::geom::LineSegment b(bx0, by0, bx1, by1);
geos::geom::Coordinate isect;

bool intersects = a.intersection(b, isect);

if (!intersects)
{
return -1;
}

*cx = isect.x;
*cy = isect.y;

return 1;
}
catch(const std::exception &e)
{
handle->ERROR_MESSAGE("%s", e.what());
}
catch(...)
{
handle->ERROR_MESSAGE("Unknown exception thrown");
}

return 0;
}

} /* extern "C" */

83 changes: 83 additions & 0 deletions tests/unit/capi/GEOSSegmentIntersectionTest.cpp
@@ -0,0 +1,83 @@
//
// Test Suite for C-API GEOSSegmentIntersection
#include <tut/tut.hpp>
// geos
#include <geos_c.h>
// std
#include <cstdarg>
#include <cstdio>
#include <cstdlib>

namespace tut
{
//
// Test Group
//

// Common data used in test cases.
struct test_capigeossegmentintersection
{
static void notice(const char *fmt, ...)
{
std::fprintf( stdout, "NOTICE: ");

va_list ap;
va_start(ap, fmt);
std::vfprintf(stdout, fmt, ap);
va_end(ap);

std::fprintf(stdout, "\n");
}

test_capigeossegmentintersection()
{
initGEOS(notice, notice);
}

~test_capigeossegmentintersection()
{
finishGEOS();
}
};

typedef test_group<test_capigeossegmentintersection> group;
typedef group::object object;

group test_capigeossegmentintersection_group("capi::GEOSSegmentIntersection");

//
// Test Cases
//
template<>
template<>
void object::test<1>()
{
// plain old intersection
int result;
double x,y;

result = GEOSSegmentIntersection(0, 0, 10, 10,
8, 0, 8, 10,
&x, &y);

ensure_equals(result, 1);
ensure_equals(x, 8);
ensure_equals(y, 8);
}

template<>
template<>
void object::test<2>()
{
// no intersection
int result;
double x,y;

result = GEOSSegmentIntersection(0, 0, 10, 10,
8, 0, 8, 2,
&x, &y);

ensure_equals(result, -1);
}

} // namespace tut

0 comments on commit 9c1c5e0

Please sign in to comment.