void geo_bound(sqlite3_context *context,int argc,sqlite3_value **argv) { if(argc >= 1) { const unsigned char* ogc; unsigned char* ret_geo_buf; size_t size; double x1,x2,y1,y2; GEOSCoordSequence* seq = 0; GEOSGeometry* geometry = 0; GEOSGeometry* middle_geo = 0; _init_geos(); if(argc == 1 && sqlite3_value_type(argv[0]) == SQLITE_BLOB) { size = sqlite3_value_bytes(argv[0]); ogc = (const unsigned char*)sqlite3_value_blob(argv[0]); middle_geo = _geo_from_wkb(ogc,size); } else if(argc == 1 && sqlite3_value_type(argv[0]) == SQLITE_TEXT) { ogc = sqlite3_value_text(argv[0]); middle_geo = _geo_from_wkt(ogc); } else if(argc == 4) { x1 = sqlite3_value_double(argv[0]); y1 = sqlite3_value_double(argv[1]); x2 = sqlite3_value_double(argv[2]); y2 = sqlite3_value_double(argv[3]); seq = GEOSCoordSeq_create(2,2); GEOSCoordSeq_setX(seq,0,x1); GEOSCoordSeq_setY(seq,0,y1); GEOSCoordSeq_setX(seq,1,x2); GEOSCoordSeq_setY(seq,1,y2); middle_geo = GEOSGeom_createLineString(seq); } if(middle_geo != 0) { geometry = GEOSEnvelope(middle_geo); if(geometry != 0) { ret_geo_buf = GEOSGeomToWKB_buf(geometry,&size); sqlite3_result_blob(context,ret_geo_buf,size,SQLITE_TRANSIENT); GEOSGeom_destroy(geometry); GEOSFree(ret_geo_buf); } GEOSGeom_destroy(middle_geo); } finishGEOS(); } }
static Face* newFace(const GEOSGeometry* g) { Face* f = lwalloc(sizeof(Face)); f->geom = g; f->env = GEOSEnvelope(f->geom); GEOSArea(f->env, &f->envarea); f->parent = NULL; /* lwnotice("Built Face with area %g and %d holes", f->envarea, GEOSGetNumInteriorRings(f->geom)); */ return f; }
static void _get_envelope(GEOSGeometry* geometry,Rect* rect) { unsigned int num_pnt; GEOSGeometry* env; const GEOSGeometry* ring; const GEOSCoordSequence* seq; double x,y; unsigned int loop=0; assert(rect != 0); assert(geometry != 0); rect->minX = rect->minY = rect->maxX = rect->maxY = 0; if(GEOSGeomTypeId(geometry) == GEOS_POINT) { GEOSGeomGetX(geometry,&x); GEOSGeomGetY(geometry,&y); rect->minX = rect->maxX = x; rect->minY = rect->maxY = y; return; } env = GEOSEnvelope(geometry); ring = GEOSGetExteriorRing(env); seq = GEOSGeom_getCoordSeq(ring); GEOSCoordSeq_getSize(seq,&num_pnt); if(num_pnt == 0 || num_pnt > 5)return; GEOSCoordSeq_getX(seq,0,&x); GEOSCoordSeq_getY(seq,0,&y); rect->minX = rect->maxX = x; rect->minY = rect->maxY = y; for(loop=1;loop<num_pnt;loop++) { GEOSCoordSeq_getX(seq,loop,&x); GEOSCoordSeq_getY(seq,loop,&y); if(x > rect->maxX) rect->maxX = x; if(x < rect->minX) rect->minX = x; if(y > rect->maxY) rect->maxY = y; if(y < rect->minY) rect->minY = y; } GEOSGeom_destroy(env); }
/* extern void GEOS_DLL GEOSSTRtree_insert(GEOSSTRtree *tree, const GEOSGeometry *g, void *item); GeosSTRtree = lgeo_geos_index:strtree_create(), Element = {element, 1}, Geom = lgeo_geos_index:to_geom({'LineString', [[4,4], [4.5, 4.5], [10,10]]}), lgeo_geos_index:strtree_insert(GeosSTRtree, Geom, Element). ok */ static ERL_NIF_TERM strtree_insert(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { GeosSTRtree_t **tree; GEOSGeometry **geom; if (argc != 3) { return enif_make_badarg(env); } if(!enif_get_resource(env, argv[0], GEOSSTRTREE_RESOURCE, (void**)&tree)) { return enif_make_badarg(env); } if(!enif_get_resource(env, argv[1], GEOSGEOM_RESOURCE, (void**)&geom)) { return enif_make_badarg(env); } ERL_NIF_TERM copy = enif_make_copy((**tree).env, argv[2]); GEOSSTRtree_insert((**tree).tree, GEOSEnvelope(*geom), (void *)copy); return enif_make_atom(env, "ok"); }