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 }
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); }
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); }
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)
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 */ }