int geos_buffer(struct Map_info *In, struct Map_info *Out, struct Map_info *Buf, int id, int type, double da, struct spatial_index *si, struct line_cats *Cats, struct buf_contours **arr_bc, int *buffers_count, int *arr_bc_alloc, int flat, int no_caps) { GEOSGeometry *IGeom = NULL; GEOSGeometry *OGeom = NULL; G_debug(3, "geos_buffer(): id=%d", id); if (type == GV_AREA) IGeom = Vect_read_area_geos(In, id); else IGeom = Vect_read_line_geos(In, id, &type); /* GEOS code comment on the number of quadrant segments: * A value of 8 gives less than 2% max error in the buffer distance. * For a max error of < 1%, use QS = 12. * For a max error of < 0.1%, use QS = 18. */ #ifdef GEOS_3_3 if (flat || no_caps) { GEOSBufferParams* geos_params = GEOSBufferParams_create(); GEOSBufferParams_setEndCapStyle(geos_params, no_caps ? GEOSBUF_CAP_FLAT : GEOSBUF_CAP_SQUARE); OGeom = GEOSBufferWithParams(IGeom, geos_params, da); GEOSBufferParams_destroy(geos_params); } else { OGeom = GEOSBuffer(IGeom, da, 12); } #else OGeom = GEOSBuffer(IGeom, da, 12); #endif if (!OGeom) { G_fatal_error(_("Buffering failed (feature %d)"), id); } geom2ring(OGeom, Out, Buf, si, Cats, arr_bc, buffers_count, arr_bc_alloc); if (IGeom) GEOSGeom_destroy(IGeom); if (OGeom) GEOSGeom_destroy(OGeom); return 1; }
void object::test<1> () { numcalls = 0; initGEOS(notice, notice); GEOS_interruptRegisterCallback(countCalls); ensure_equals(numcalls, 0); GEOSGeometry* geom1 = GEOSGeomFromWKT("LINESTRING(0 0, 1 0)"); ensure("GEOSGeomFromWKT failed", nullptr != geom1); GEOSGeometry* geom2 = GEOSBuffer(geom1, 1, 8); ensure("GEOSBufferWithStyle failed", nullptr != geom2); ensure("interrupt callback never called", numcalls > 0); GEOSGeom_destroy(geom1); GEOSGeom_destroy(geom2); GEOS_interruptRegisterCallback(nullptr); /* unregister */ finishGEOS(); }
Handle<Value> Geometry::Buffer(const Arguments& args) { HandleScope scope; double width; int quadsegs = 8; if (args.Length() < 1) return ThrowException(String::New("requires width argument")); if (!args[0]->IsNumber()) return ThrowException(Exception::TypeError(String::New("width argument must be a number"))); Geometry *geom = ObjectWrap::Unwrap<Geometry>(args.This()); width = args[0]->NumberValue(); if (args.Length() == 2) quadsegs = args[1]->Int32Value(); GEOSGeometry *buffer = GEOSBuffer(geom->geos_geom_, width, quadsegs); if (buffer == NULL) return ThrowException(String::New("couldn't buffer geometry")); Handle<Object> buffer_obj = WrapNewGEOSGeometry(buffer); return scope.Close(buffer_obj); }
void object::test<4> () { initGEOS(notice, notice); GEOSGeometry* geom1 = GEOSGeomFromWKT("LINESTRING(0 0, 1 0)"); ensure("GEOSGeomFromWKT failed", nullptr != geom1); GEOS_interruptRegisterCallback(interruptNow); GEOSGeometry* geom2 = GEOSBuffer(geom1, 1, 8); ensure("GEOSBuffer wasn't interrupted", nullptr == geom2); GEOS_interruptRegisterCallback(nullptr); /* unregister */ // TODO: check the actual exception ? (sent to notice() callback) GEOSGeom_destroy(geom1); finishGEOS(); }
shapeObj *msGEOSBuffer(shapeObj *shape, double width) { #ifdef USE_GEOS GEOSGeom g1, g2; if(!shape) return NULL; if(!shape->geometry) /* if no geometry for the shape then build one */ shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape); g1 = (GEOSGeom) shape->geometry; if(!g1) return NULL; g2 = GEOSBuffer(g1, width, 30); return msGEOSGeometry2Shape(g2); #else msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSBuffer()"); return NULL; #endif }
char *msudf_buffer(UDF_INIT *initid,UDF_ARGS *args, char *buf, unsigned long *length, char *is_null, char *error) { char *result; GEOSGeom geom1,geom2; double buffer; int quadsegs; DEBUG("msudf_buffer"); geom1 = msudf_getGeometry((unsigned char *)args->args[0],args->lengths[0]); if (geom1 == NULL) { strcpy(error,"Invalid geometry."); *is_null = 1; return NULL; } buffer = *((double*) args->args[1]); if (args->arg_count > 2 && args->arg_type[2] == INT_RESULT) { quadsegs = *((int *)args->args[2]); } else { quadsegs = 8; } geom2 = GEOSBuffer(geom1,buffer,quadsegs); if (geom2 != NULL) { GEOSSetSRID(geom2,GEOSGetSRID(geom1)); result = msudf_returnGeometry(initid,length,geom2); GEOSGeom_destroy(geom1); GEOSGeom_destroy(geom2); return result; } else { GEOSGeom_destroy(geom1); *is_null = 1; return NULL; } }
void object::test<5> () { numcalls = 0; initGEOS(notice, notice); GEOSGeometry* geom1 = GEOSGeomFromWKT("LINESTRING(0 0, 1 0)"); ensure("GEOSGeomFromWKT failed", nullptr != geom1); GEOS_interruptRegisterCallback(interruptNow); nextcb = GEOS_interruptRegisterCallback(countCalls); GEOSGeometry* geom2 = GEOSBuffer(geom1, 1, 8); ensure("GEOSBuffer wasn't interrupted", nullptr == geom2); ensure_equals(numcalls, 1); GEOS_interruptRegisterCallback(nullptr); /* unregister */ nextcb = nullptr; GEOSGeom_destroy(geom1); finishGEOS(); }