MODULE = Geo::Geos PACKAGE = Geo::Geos::Algorithm
PROTOTYPES: DISABLE
double toDegrees (double radians) { RETVAL = Angle::toDegrees(radians); }
double toRadians (double angleDegrees) { RETVAL = Angle::toRadians(angleDegrees); }
double angle (Coordinate& p0) { RETVAL = Angle::angle(p0); }
bool isAcute (Coordinate* p0, Coordinate* p1, Coordinate *p2) {
RETVAL = Angle::isAcute(*p0, *p1, *p2);
}
bool isObtuse (Coordinate& p0, Coordinate& p1, Coordinate& p2) {
RETVAL = Angle::isObtuse(p0, p1, p2);
}
double angleBetween (Coordinate& tip1, Coordinate& tail, Coordinate& tip2) {
RETVAL = Angle::angleBetween(tip1, tail, tip2);
}
double angleBetweenOriented (Coordinate& tip1, Coordinate& tail, Coordinate& tip2) {
RETVAL = Angle::angleBetweenOriented (tip1, tail, tip2);
}
double interiorAngle(Coordinate& p0, Coordinate& p1, Coordinate& p2) {
RETVAL = Angle::interiorAngle(p0, p1, p2);
}
int getTurn (double ang1, double ang2) { RETVAL = Angle::getTurn(ang1, ang2); }
double normalize (double angle) { RETVAL = Angle::normalize(angle); }
double normalizePositive (double angle) { RETVAL = Angle::normalizePositive(angle); }
double diff (double ang1, double ang2) { RETVAL = Angle::diff(ang1, ang2); }
Coordinate* centroid (Geometry& g) {
Coordinate c;
if (Centroid::getCentroid(g, c)) RETVAL = new Coordinate(c);
else XSRETURN_UNDEF;
}
Coordinate* centroidArea (Array geoms) {
Coordinate result;
CentroidArea acc;
for(size_t i = 0; i < geoms.size(); ++i) {
auto item = geoms.at(i);
if (item.is_array_ref()) {
auto seq = Helper::convert_coords(Array(item));
acc.add(&seq);
}
else {
acc.add(&xs::in<Geometry&>(item));
}
}
if (acc.getCentroid(result)) RETVAL = new Coordinate(result);
else XSRETURN_UNDEF;
}
Coordinate* centroidLine (Array geoms) {
Coordinate result;
CentroidLine acc;
for(size_t i = 0; i < geoms.size(); ++i) {
auto item = geoms.at(i);
if (item.is_array_ref()) {
auto seq = Helper::convert_coords(Array(item));
acc.add(&seq);
}
else {
acc.add(&xs::in<Geometry&>(item));
}
}
if (acc.getCentroid(result)) RETVAL = new Coordinate(result);
else XSRETURN_UNDEF;
}
Coordinate* centroidPoint (Array geoms) {
Coordinate result;
CentroidPoint acc;
for(size_t i = 0; i < geoms.size(); ++i) {
Object item = Object(geoms.at(i));
if (!item) throw ("invalid argument");
if (item.stash().name() == "Geo::Geos::Coordinate") {
acc.add(&xs::in<Coordinate&>(item));
}
else acc.add(&xs::in<Geometry&>(item));
}
if (acc.getCentroid(result)) RETVAL = new Coordinate(result);
else XSRETURN_UNDEF;
}
bool isPointInRing(Coordinate& p, Array ring) {
auto seq = Helper::convert_coords(ring);
RETVAL = CGAlgorithms::isPointInRing(p, &seq);
}
int locatePointInRing(Coordinate& p,Array ring) {
auto seq = Helper::convert_coords(ring);
RETVAL = CGAlgorithms::locatePointInRing(p, seq);
}
bool isOnLine(Coordinate& p, Array line) {
auto seq = Helper::convert_coords(line);
RETVAL = CGAlgorithms::isPointInRing(p, &seq);
}
bool isCCW(Array ring) {
auto seq = Helper::convert_coords(ring);
RETVAL = CGAlgorithms::isCCW(&seq);
}
int computeOrientation(Coordinate& p1, Coordinate& p2, Coordinate& q){
RETVAL = CGAlgorithms::computeOrientation(p1, p2, q);
}
double distancePointLine(Coordinate& p, Coordinate& A, Coordinate& B) {
RETVAL = CGAlgorithms::distancePointLine(p, A, B);
}
double distancePointLinePerpendicular(Coordinate& p, Coordinate& A, Coordinate& B) {
RETVAL = CGAlgorithms::distancePointLinePerpendicular(p, A, B);
}
double distanceLineLine (Coordinate& A, Coordinate& B, Coordinate& C, Coordinate& D) {
RETVAL = CGAlgorithms::distanceLineLine(A, B, C, D);
}
double signedArea (Array ring) {
auto seq = Helper::convert_coords(ring);
RETVAL = CGAlgorithms::signedArea(&seq);
}
double length(Array pts) {
auto seq = Helper::convert_coords(pts);
RETVAL = CGAlgorithms::length(&seq);
}
int orientationIndex(Coordinate& p1, Coordinate& p2, Coordinate& q) {
RETVAL = CGAlgorithms::computeOrientation(p1, p2, q);
}
Coordinate* getIntersection(Coordinate& p00, Coordinate& p01, Coordinate& p10, Coordinate& p11) {
//auto& c = CentralEndpointIntersector::getIntersection(p00, p01, p10, p11);
// ^ buggy implementation in 3.6.3, as it returns dangling reference;
CentralEndpointIntersector intor(p00, p01, p10, p11);
auto& c = intor.getIntersection();
RETVAL = new Coordinate(c);
}
Sv convexHull(Geometry& newGeometry) {
auto ch = ConvexHull(&newGeometry);
RETVAL = Helper::uplift(ch.getConvexHull());
}
Coordinate* interiorPointArea(Geometry& g) {
InteriorPointArea ip(&g);
Coordinate c;
if (ip.getInteriorPoint(c)) RETVAL = new Coordinate(c);
else XSRETURN_UNDEF;
}
Coordinate* interiorPointLine(Geometry& g) {
InteriorPointLine ip(&g);
Coordinate c;
if (ip.getInteriorPoint(c)) RETVAL = new Coordinate(c);
else XSRETURN_UNDEF;
}
Coordinate* interiorPointPoint(Geometry& g) {
InteriorPointPoint ip(&g);
Coordinate c;
if (ip.getInteriorPoint(c)) RETVAL = new Coordinate(c);
else XSRETURN_UNDEF;
}
int locate(Coordinate& p, Geometry& geom) {
PointLocator pl;
RETVAL = pl.locate(p, &geom);
}
bool intersects(Coordinate& p, Geometry& geom) {
PointLocator pl;
RETVAL = pl.intersects(p, &geom);
}
int signOfDet2x2(double x1, double y1, double x2, double y2) {
RETVAL = RobustDeterminant::signOfDet2x2(x1, y1, x2, y2);
}
int locateIndexedPointInArea(Coordinate& p, Geometry& geom) {
locate::IndexedPointInAreaLocator locator(geom);
RETVAL = locator.locate(&p);
}
int locateSimplePointInArea(Coordinate& p, Geometry& geom) {
locate::SimplePointInAreaLocator locator(&geom);
RETVAL = locator.locate(&p);
}
BOOT {
auto this_stash = Stash(__PACKAGE__);
xs::exp::create_constants(this_stash, {
{"TYPE_TURN_CLOCKWISE", CGAlgorithms::CLOCKWISE},
{"TYPE_TURN_COLLINEAR", CGAlgorithms::COLLINEAR},
{"TYPE_TURN_COUNTERCLOCKWISE", CGAlgorithms::COUNTERCLOCKWISE},
{"TYPE_ORIENT_RIGHT", CGAlgorithms::RIGHT},
{"TYPE_ORIENT_LEFT" , CGAlgorithms::LEFT},
{"TYPE_ORIENT_STRAIGHT", CGAlgorithms::STRAIGHT}
});
xs::exp::autoexport(this_stash);
}