void object::test<7>() { std::string wkt0("LINESTRING (" "665.7317504882812500 133.0762634277343700," "1774.4752197265625000 19.9391822814941410," "756.2413940429687500 466.8306579589843700," "626.1337890625000000 1898.0147705078125000," "433.8007202148437500 404.6052856445312500)"); geom1_ = GEOSGeomFromWKT(wkt0.c_str()); ensure( 0 != geom1_ ); double width = 57.164000837203; // left-sided { geom2_ = GEOSOffsetCurve(geom1_, width, 8, GEOSBUF_JOIN_MITRE, 5.57); ensure( 0 != geom2_ ); // likely, 5 >= 5 ensure(GEOSGeomGetNumPoints(geom2_) >= GEOSGeomGetNumPoints(geom1_)); wkt_ = GEOSWKTWriter_write(wktw_, geom2_); //ensure_equals(std::string(wkt_), ...); } // right-sided { width = -width; geom2_ = GEOSOffsetCurve(geom1_, width, 8, GEOSBUF_JOIN_MITRE, 5.57); ensure( 0 != geom2_ ); // likely, 5 >= 7 ensure(GEOSGeomGetNumPoints(geom2_) >= GEOSGeomGetNumPoints(geom1_)); wkt_ = GEOSWKTWriter_write(wktw_, geom2_); //ensure_equals(std::string(wkt_), ...); } }
LWGEOM* lwgeom_offsetcurve(const LWLINE *lwline, double size, int quadsegs, int joinStyle, double mitreLimit) { #if POSTGIS_GEOS_VERSION < 32 lwerror("lwgeom_offsetcurve: GEOS 3.2 or higher required"); #else GEOSGeometry *g1, *g3; LWGEOM *lwgeom_result; LWGEOM *lwgeom_in = lwline_as_lwgeom(lwline); initGEOS(lwnotice, lwgeom_geos_error); g1 = (GEOSGeometry *)LWGEOM2GEOS(lwgeom_in); if ( ! g1 ) { lwerror("lwgeom_offsetcurve: Geometry could not be converted to GEOS: %s", lwgeom_geos_errmsg); return NULL; } #if POSTGIS_GEOS_VERSION < 33 /* Size is always positive for GEOSSingleSidedBuffer, and a flag determines left/right */ g3 = GEOSSingleSidedBuffer(g1, size < 0 ? -size : size, quadsegs, joinStyle, mitreLimit, size < 0 ? 0 : 1); #else g3 = GEOSOffsetCurve(g1, size, quadsegs, joinStyle, mitreLimit); #endif /* Don't need input geometry anymore */ GEOSGeom_destroy(g1); if (g3 == NULL) { GEOSGeom_destroy(g1); lwerror("GEOSOffsetCurve: %s", lwgeom_geos_errmsg); return NULL; } LWDEBUGF(3, "result: %s", GEOSGeomToWKT(g3)); GEOSSetSRID(g3, lwgeom_get_srid(lwgeom_in)); lwgeom_result = GEOS2LWGEOM(g3, lwgeom_has_z(lwgeom_in)); GEOSGeom_destroy(g3); if (lwgeom_result == NULL) { lwerror("lwgeom_offsetcurve: GEOS2LWGEOM returned null"); return NULL; } return lwgeom_result; #endif /* POSTGIS_GEOS_VERSION < 32 */ }
void QgsMapToolOffsetCurve::setOffsetForRubberBand( double offset, bool leftSide ) { // need at least geos 3.3 for OffsetCurve tool #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \ ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3))) if ( !mRubberBand || !mOriginalGeometry ) { return; } QgsVectorLayer* sourceLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( mSourceLayerId ) ); if ( !sourceLayer ) { return; } QgsGeometry geomCopy( *mOriginalGeometry ); const GEOSGeometry* geosGeom = geomCopy.asGeos(); if ( geosGeom ) { QSettings s; int joinStyle = s.value( "/qgis/digitizing/offset_join_style", 0 ).toInt(); int quadSegments = s.value( "/qgis/digitizing/offset_quad_seg", 8 ).toInt(); double mitreLimit = s.value( "/qgis/digitizing/offset_miter_limit", 5.0 ).toDouble(); GEOSGeometry* offsetGeom = GEOSOffsetCurve( geosGeom, leftSide ? offset : -offset, quadSegments, joinStyle, mitreLimit ); if ( !offsetGeom ) { deleteRubberBandAndGeometry(); deleteDistanceItem(); delete mSnapVertexMarker; mSnapVertexMarker = 0; mForceCopy = false; mGeometryModified = false; deleteDistanceItem(); QMessageBox::critical( 0, tr( "Geometry error" ), tr( "Creating offset geometry failed" ) ); return; } if ( offsetGeom ) { mModifiedGeometry.fromGeos( offsetGeom ); mRubberBand->setToGeometry( &mModifiedGeometry, sourceLayer ); } } #else //GEOS_VERSION>=3.3 Q_UNUSED( offset ); Q_UNUSED( leftSide ); #endif //GEOS_VERSION>=3.3 }
void object::test<1>() { geom1_ = GEOSGeomFromWKT("LINESTRING(0 0, 10 0)"); ensure( 0 != geom1_ ); geom2_ = GEOSOffsetCurve(geom1_, 2, 0, GEOSBUF_JOIN_ROUND, 2); ensure( 0 != geom2_ ); wkt_ = GEOSWKTWriter_write(wktw_, geom2_); ensure_equals(std::string(wkt_), std::string( "LINESTRING (0 2, 10 2)")); }
void object::test<5>() { geom1_ = GEOSGeomFromWKT("LINESTRING(33282908 6005055,33282900 6005050,33282892 6005042,33282876 6005007,33282863 6004982,33282866 6004971,33282876 6004975,33282967 6005018,33282999 6005031)"); ensure( 0 != geom1_ ); geom2_ = GEOSOffsetCurve(geom1_, 44, 1, GEOSBUF_JOIN_MITRE, 1); ensure( 0 != geom2_ ); wkt_ = GEOSWKTWriter_write(wktw_, geom2_); ensure_equals(std::string(wkt_), std::string( "LINESTRING EMPTY" )); }
shapeObj *msGEOSOffsetCurve(shapeObj *p, double offset) { #if defined USE_GEOS && defined HAVE_GEOS_OFFSET_CURVE GEOSGeom g1, g2; if(!p) return NULL; if(!p->geometry) /* if no geometry for the shape then build one */ p->geometry = (GEOSGeom) msGEOSShape2Geometry(p); g1 = (GEOSGeom) p->geometry; if(!g1) return NULL; g2 = GEOSOffsetCurve(g1, offset, 4, GEOSBUF_JOIN_MITRE, fabs(offset*1.5)); return msGEOSGeometry2Shape(g2); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSingleSidedBuffer()"); return NULL; #endif }
void QgsGeometryAnalyzer::createOffsetGeometry( QgsGeometry* geom, QgsGeometry* lineGeom, double offset ) { if ( !geom || !lineGeom ) { return; } QList<QgsGeometry*> inputGeomList; if ( geom->isMultipart() ) { inputGeomList = geom->asGeometryCollection(); } else { inputGeomList.push_back( geom ); } QList<GEOSGeometry*> outputGeomList; QList<QgsGeometry*>::const_iterator inputGeomIt = inputGeomList.constBegin(); for ( ; inputGeomIt != inputGeomList.constEnd(); ++inputGeomIt ) { if ( geom->type() == QGis::Line ) { //geos 3.3 needed for line offsets #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \ ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3))) outputGeomList.push_back( GEOSOffsetCurve(( *inputGeomIt )->asGeos(), -offset, 8 /*quadSegments*/, 0 /*joinStyle*/, 5.0 /*mitreLimit*/ ) ); #else outputGeomList.push_back( GEOSGeom_clone(( *inputGeomIt )->asGeos() ) ); #endif } else if ( geom->type() == QGis::Point ) { QgsPoint p = ( *inputGeomIt )->asPoint(); p = createPointOffset( p.x(), p.y(), offset, lineGeom ); GEOSCoordSequence* ptSeq = GEOSCoordSeq_create( 1, 2 ); GEOSCoordSeq_setX( ptSeq, 0, p.x() ); GEOSCoordSeq_setY( ptSeq, 0, p.y() ); GEOSGeometry* geosPt = GEOSGeom_createPoint( ptSeq ); outputGeomList.push_back( geosPt ); } } if ( !geom->isMultipart() ) { GEOSGeometry* outputGeom = outputGeomList.at( 0 ); if ( outputGeom ) { geom->fromGeos( outputGeom ); } } else { GEOSGeometry** geomArray = new GEOSGeometry*[outputGeomList.size()]; for ( int i = 0; i < outputGeomList.size(); ++i ) { geomArray[i] = outputGeomList.at( i ); } GEOSGeometry* collection = 0; if ( geom->type() == QGis::Point ) { collection = GEOSGeom_createCollection( GEOS_MULTIPOINT, geomArray, outputGeomList.size() ); } else if ( geom->type() == QGis::Line ) { collection = GEOSGeom_createCollection( GEOS_MULTILINESTRING, geomArray, outputGeomList.size() ); } geom->fromGeos( collection ); delete[] geomArray; } }