MODULE = Geo::Geos PACKAGE = Geo::Geos::Operation PROTOTYPES: DISABLE Sv buffer(Geometry& g, double distance, SV* quadrantSegments = NULL, SV* endCapStyle = NULL) { int vQuadrantSegments = quadrantSegments ? SvIV(quadrantSegments) : (int)BufferParameters::DEFAULT_QUADRANT_SEGMENTS; int vEndCapStyle = endCapStyle? SvIV(endCapStyle) : (int)BufferParameters::CAP_ROUND; Geometry* r = BufferOp::bufferOp(&g, distance, vQuadrantSegments, vEndCapStyle); RETVAL = Helper::uplift(r); } double distance(Geometry& g0, Geometry& g1) { RETVAL = DistanceOp::distance(&g0, &g1); } Array nearestPoints(Geometry& g0, Geometry& g1) { Array r; auto seq = DistanceOp::nearestPoints(&g0, &g1); if(seq) { auto seq_ptr = std::unique_ptr(seq); r = Helper::convert_copy(seq); } RETVAL = r; } Array closestPoints(Geometry& g0, Geometry& g1) { Array r; auto seq = DistanceOp::closestPoints(&g0, &g1); if(seq) { auto seq_ptr = std::unique_ptr(seq); r = Helper::convert_copy(seq); } RETVAL = r; } Sv overlayOp(Geometry& g0, Geometry& g1, int opCode) { if (opCode > 4) throw "wrong opCode"; OverlayOp::OpCode code = static_cast(opCode); Geometry* g = OverlayOp::overlayOp(&g0, &g1, code); RETVAL = Helper::uplift(g); } bool isValid(Object obj) { if (obj.stash().name() == "Geo::Geos::Coordinate") { auto& c = xs::in(obj); RETVAL = IsValidOp::isValid(c); } else { auto& g = xs::in(obj); RETVAL = IsValidOp::isValid(g); } } IntersectionMatrix* relate(Geometry& g0, Geometry& g1, SV* boundaryNodeRule = NULL) { if (!boundaryNodeRule) RETVAL = RelateOp::relate(&g0, &g1); else { const BoundaryNodeRule* rule; auto rule_id = SvIV(boundaryNodeRule); switch(rule_id) { case 0: rule = &BoundaryNodeRule::getBoundaryRuleMod2(); break; case 1: rule = &BoundaryNodeRule::getBoundaryEndPoint(); break; case 2: rule = &BoundaryNodeRule::getBoundaryMultivalentEndPoint(); break; case 3: rule = &BoundaryNodeRule::getBoundaryMonovalentEndPoint(); break; case 4: rule = &BoundaryNodeRule::getBoundaryOGCSFS(); break; default: throw("Wrong boundaryNodeRule"); } RETVAL = RelateOp::relate(&g0, &g1, *rule); } } Array mergeLines(Array in) { LineMerger lm; for(auto it: in) { lm.add(&xs::in(it)); } auto v = lm.getMergedLineStrings(); Array out = Array::create(v->size()); for(LineString* it: *v) { auto wrapped = xs::out(it); out.push(wrapped); } RETVAL = out; delete v; } bool isSequenced(Geometry& g) { RETVAL = LineSequencer::isSequenced(&g); } Sv sequence(Geometry& g) { RETVAL = Helper::uplift(LineSequencer::sequence(g)); } BOOT { auto this_stash = Stash(__PACKAGE__); xs::exp::create_constants(this_stash, { {"TYPE_OP_INTERSECTION", OverlayOp::OpCode::opINTERSECTION}, {"TYPE_OP_UNION", OverlayOp::OpCode::opUNION}, {"TYPE_OP_DIFFERENCE", OverlayOp::OpCode::opDIFFERENCE}, {"TYPE_OP_SYMDIFFERENCE", OverlayOp::OpCode::opSYMDIFFERENCE}, {"TYPE_BOUNDARY_NODE_RULE_MOD2", 0}, {"TYPE_BOUNDARY_ENDPOINT", 1}, {"TYPE_BOUNDARY_MULTIVALENT_ENDPOINT", 2}, {"TYPE_BOUNDARY_MONOVALENT_ENDPOINT", 3}, {"TYPE_BOUNDARY_OGCSFS", 4} }); xs::exp::autoexport(this_stash); }