예제 #1
0
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();
	}
}
예제 #2
0
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;
}
예제 #3
0
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);
}
예제 #4
0
/*
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");
}