示例#1
0
double msGEOSDistance(shapeObj *shape1, shapeObj *shape2)
{
#ifdef USE_GEOS
  GEOSGeom g1, g2;
  double distance;
  int result;

  if(!shape1 || !shape2)
    return -1;

  if(!shape1->geometry) /* if no geometry for shape1 then build one */
    shape1->geometry = (GEOSGeom) msGEOSShape2Geometry(shape1);
  g1 = (GEOSGeom) shape1->geometry;
  if(!g1) return -1;

  if(!shape2->geometry) /* if no geometry for shape2 then build one */
    shape2->geometry = (GEOSGeom) msGEOSShape2Geometry(shape2);
  g2 = (GEOSGeom) shape2->geometry;
  if(!g2) return -1;

  result = GEOSDistance(g1, g2, &distance);  
  return ((result==0) ? -1 : distance);
#else
  return msDistanceShapeToShape(shape1, shape2); /* fall back on brute force method (for MapScript) */
#endif
}
示例#2
0
    void object::test<1>()
    {
        geom1_ = GEOSGeomFromWKT("POINT(10 10)");
        geom2_ = GEOSGeomFromWKT("POINT(3 6)");

        double dist;
        int ret = GEOSDistance(geom1_, geom2_, &dist);

        ensure_equals(ret, 1);
        ensure_distance(dist, 8.06225774829855, 1e-12);
    }
示例#3
0
Handle<Value> Geometry::Distance(const Arguments& args)
{
    Geometry *geom = ObjectWrap::Unwrap<Geometry>(args.This());
    HandleScope scope;
    if (args.Length() != 1)
        return ThrowException(String::New("missing other geometry"));
    Geometry *other = ObjectWrap::Unwrap<Geometry>(args[0]->ToObject());
    double distance;
    int r = GEOSDistance(geom->geos_geom_, other->geos_geom_, &distance);
    if (r != 1)
        return ThrowException(String::New("couldn't get distance"));
    Handle<Value> distance_obj = Number::New(distance);
    return scope.Close(distance_obj);
}
示例#4
0
    void object::test<2>()
    {
        std::srand(12345);

        GEOSGeometry* g1 = random_polygon(-3, -8, 7, 1000);
        GEOSGeometry* g2 = random_polygon(14, 22, 6, 500);

        double d_raw, d_indexed;
        ensure(GEOSDistance(g1, g2, &d_raw));
        ensure(GEOSDistanceIndexed(g1, g2, &d_indexed));

        ensure_equals(d_indexed, d_raw);

        GEOSGeom_destroy(g1);
        GEOSGeom_destroy(g2);
    }
bool VertexSnapper::isClose( const GEOSGeometry * g1, const GEOSGeometry * g2)
{
    qDebug("VertexSnapper::isClose: ENTERING ISCLOSE");

    // distance
    double dist;
    GEOSDistance( g1, g2, &dist );
    qDebug("VertexSnapper::isClose: Distance computed");

    // min distance between geometries is less than tolerance
    if ( dist < tolDistance )
    {
       return true;
    }

    return false;

} // bool VertexSnapper::isClose(MyGEOSGeom & g1, MyGEOSGeom & g2)
void VertexSnapper::snapVertices(MyGEOSGeom *geom, GEOSCoordSequence *closeCoord)
{
    qDebug("VertexSnapper::snapVertices: ENTERING SNAP VERTICES");

    // tested geometry as coordination sequence
    //GEOSGeometry* points = GEOSGeom_extractUniquePoints( geom->getGEOSGeom() );
    const GEOSCoordSequence *s = GEOSGeom_getCoordSeq( geom->getGEOSGeom() );
    GEOSCoordSequence *coord =  GEOSCoordSeq_clone( s );

    qDebug("VertexSnapper::snapVertices: GEOSCoordSequence cloned from geom Geometry");

    // get dimension of geometry
    int dim = GEOSGeom_getDimensions( geom->getGEOSGeom() );

    // get number of points
    unsigned int cSize;
    GEOSCoordSeq_getSize( coord, &cSize );

    unsigned int ccSize;
    GEOSCoordSeq_getSize( closeCoord, &ccSize );

    // find closest point from closeCoord
    for ( unsigned int i = 0; i < cSize; i++)
    {
        // get point from coordinate sequence
        double x, y;
        GEOSCoordSeq_getX( coord, i, &x);
        GEOSCoordSeq_getY( coord, i, &y);
        GEOSCoordSequence *point = GEOSCoordSeq_create( 1, dim );
        GEOSCoordSeq_setX( point, 0, x);
        GEOSCoordSeq_setY( point, 0, y);
        GEOSGeometry * pointGeom = GEOSGeom_createPoint( point );

        // minimal distance
        double minDist = tolDistance;// = coord->getAt(i).distance( closeCoord.getAt(0) );

        unsigned int indMin = 0;
        bool isMin = false;

        for ( unsigned int j = 0; j < ccSize; j++ )
        {
            // get point from coordinate sequence
            double xx, yy;
            GEOSCoordSeq_getX( closeCoord, j, &xx);
            GEOSCoordSeq_getY( closeCoord, j, &yy);
            GEOSCoordSequence *pointj = GEOSCoordSeq_create( 1, dim );
            GEOSCoordSeq_setX( pointj, 0, xx);
            GEOSCoordSeq_setY( pointj, 0, yy);
            GEOSGeometry * pointGeomj = GEOSGeom_createPoint( pointj );

            // compute distance between two tested points
            double dist =  GEOSDistance( pointGeomj, pointGeom, &minDist ); //coord->getAt(i).distance( closeCoord.getAt(j) );

            if( dist <= minDist )
            {
                minDist = dist;
                indMin = j;
                isMin = true;
            }

            GEOSGeom_destroy(pointGeomj);
        }

        // set new coordinate to the closest point if there is some
        if ( isMin )
        {
            double newX, newY;
            GEOSCoordSeq_getX( closeCoord, indMin, &newX);
            GEOSCoordSeq_getY( closeCoord, indMin, &newY);
            GEOSCoordSeq_setX( coord, i, newX);
            GEOSCoordSeq_setY( coord, i, newY);
            //coord->setAt( closeCoord.getAt(indMin), i );
        }

        //GEOSCoordSeq_destroy(point);
        GEOSGeom_destroy(pointGeom);

    }

    // edit geometry
    editGeometry( geom, coord);

    //GEOSCoordSeq_destroy(coord);
    //GEOSCoordSeq_destroy(point0);
    //GEOSGeom_destroy(pointGeom0);

} // MyGEOSGeom& VertexSnapper::snapVertices(MyGEOSGeom &geom, CoordinateSequence &closeCoord)
示例#7
0
static CPLErr
BlendMaskGenerator( int nXOff, int nYOff, int nXSize, int nYSize, 
                    GByte *pabyPolyMask, float *pafValidityMask,
                    OGRGeometryH hPolygon, double dfBlendDist )

{
#ifndef HAVE_GEOS 
    CPLError( CE_Failure, CPLE_AppDefined, 
              "Blend distance support not available without the GEOS library.");
    return CE_Failure;

#else /* HAVE_GEOS */

/* -------------------------------------------------------------------- */
/*      Convert the polygon into a collection of lines so that we       */
/*      measure distance from the edge even on the inside.              */
/* -------------------------------------------------------------------- */
    OGRGeometry *poLines
        = OGRGeometryFactory::forceToMultiLineString( 
            ((OGRGeometry *) hPolygon)->clone() );

/* -------------------------------------------------------------------- */
/*      Prepare a clipping polygon a bit bigger than the area of        */
/*      interest in the hopes of simplifying the cutline down to        */
/*      stuff that will be relavent for this area of interest.          */
/* -------------------------------------------------------------------- */
    CPLString osClipRectWKT;

    osClipRectWKT.Printf( "POLYGON((%g %g,%g %g,%g %g,%g %g,%g %g))", 
                          nXOff - (dfBlendDist+1), 
                          nYOff - (dfBlendDist+1), 
                          nXOff + nXSize + (dfBlendDist+1), 
                          nYOff - (dfBlendDist+1), 
                          nXOff + nXSize + (dfBlendDist+1), 
                          nYOff + nYSize + (dfBlendDist+1), 
                          nXOff - (dfBlendDist+1), 
                          nYOff + nYSize + (dfBlendDist+1), 
                          nXOff - (dfBlendDist+1), 
                          nYOff - (dfBlendDist+1) );
    
    OGRPolygon *poClipRect = NULL;
    char *pszWKT = (char *) osClipRectWKT.c_str();
    
    OGRGeometryFactory::createFromWkt( &pszWKT, NULL, 
                                       (OGRGeometry**) (&poClipRect) );

    if( poClipRect )
    {
        OGRGeometry *poClippedLines = 
            poLines->Intersection( poClipRect );
        delete poLines;
        poLines = poClippedLines;
        delete poClipRect;
    }

/* -------------------------------------------------------------------- */
/*      Convert our polygon into GEOS format, and compute an            */
/*      envelope to accelerate later distance operations.               */
/* -------------------------------------------------------------------- */
    OGREnvelope sEnvelope;
    int iXMin, iYMin, iXMax, iYMax;
    GEOSGeom poGEOSPoly;

    poGEOSPoly = poLines->exportToGEOS();
    OGR_G_GetEnvelope( hPolygon, &sEnvelope );

    delete poLines;

    if( sEnvelope.MinY - dfBlendDist > nYOff+nYSize 
        || sEnvelope.MaxY + dfBlendDist < nYOff 
        || sEnvelope.MinX - dfBlendDist > nXOff+nXSize
        || sEnvelope.MaxX + dfBlendDist < nXOff )
        return CE_None;
    
    iXMin = MAX(0,(int) floor(sEnvelope.MinX - dfBlendDist - nXOff));
    iXMax = MIN(nXSize, (int) ceil(sEnvelope.MaxX + dfBlendDist - nXOff));
    iYMin = MAX(0,(int) floor(sEnvelope.MinY - dfBlendDist - nYOff));
    iYMax = MIN(nYSize, (int) ceil(sEnvelope.MaxY + dfBlendDist - nYOff));

/* -------------------------------------------------------------------- */
/*      Loop over potential area within blend line distance,            */
/*      processing each pixel.                                          */
/* -------------------------------------------------------------------- */
    int iY, iX;
    double dfLastDist;
    
    for( iY = 0; iY < nYSize; iY++ )
    {
        dfLastDist = 0.0;

        for( iX = 0; iX < nXSize; iX++ )
        {
            if( iX < iXMin || iX >= iXMax
                || iY < iYMin || iY > iYMax
                || dfLastDist > dfBlendDist + 1.5 )
            {
                if( pabyPolyMask[iX + iY * nXSize] == 0 )
                    pafValidityMask[iX + iY * nXSize] = 0.0;

                dfLastDist -= 1.0;
                continue;
            }
            
            double dfDist, dfRatio;
            CPLString osPointWKT;
            GEOSGeom poGEOSPoint;

            osPointWKT.Printf( "POINT(%d.5 %d.5)", iX + nXOff, iY + nYOff );
            poGEOSPoint = GEOSGeomFromWKT( osPointWKT );

            GEOSDistance( poGEOSPoly, poGEOSPoint, &dfDist );
            GEOSGeom_destroy( poGEOSPoint );

            dfLastDist = dfDist;

            if( dfDist > dfBlendDist )
            {
                if( pabyPolyMask[iX + iY * nXSize] == 0 )
                    pafValidityMask[iX + iY * nXSize] = 0.0;

                continue;
            }

            if( pabyPolyMask[iX + iY * nXSize] == 0 )
            {
                /* outside */
                dfRatio = 0.5 - (dfDist / dfBlendDist) * 0.5;
            }
            else 
            {
                /* inside */
                dfRatio = 0.5 + (dfDist / dfBlendDist) * 0.5;
            }                

            pafValidityMask[iX + iY * nXSize] *= dfRatio;
        }
    }

/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */
    GEOSGeom_destroy( poGEOSPoly );

    return CE_None;

#endif /* HAVE_GEOS */
}