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_), ...);
        }
    }
示例#2
0
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"
        ));
    }
示例#6
0
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;
  }
}