[postgis-users] AsSvg

TECHER Jean David davidtecher at yahoo.fr
Wed Sep 8 05:20:19 PDT 2004


Hi Klaus

Happy to see you... :-)

I think it could be a great new if assvg was a native part of PostGIS

TECHER JEAN DAVID
- Responsable Informatique 01MAP -
e-mail:davidtecher at yahoo.fr
Tel: 06 85 37 36 75
Site PostGIS: http://techer.pascal.free.fr/postgis/index.htm 

> -----Message d'origine-----
> De : postgis-users-bounces at postgis.refractions.net
> [mailto:postgis-users-bounces at postgis.refractions.net]De la part de
> Olivier Courtin
> Envoye : mercredi 8 septembre 2004 13:57
> A : postgis-users at postgis.refractions.net
> Cc : klaus at svg.cc
> Objet : [postgis-users] AsSvg
> 
> 
> Hi,
> 
> I currently use PostGIS with AsSvg for several month (mostly web carto
> usage).
> Current AsSvg projet from klaus Foerster is available here :
> <http://svg.cc/pg/assvg/>
> 
> And i find a bit pity following things :
> 1) AsSvg is not a native part of PostGIS (even if SVG output is in
> PostGIS TODO)
> 2) AsSvg output use double for decimal part (useless for most web carto 
> application)
> 
> 
> For the second point, i've decided to add a new optional parameter in 
> AsSvg prototype to handle decimal precision (now default is 0 decimal).
> I've also correct some very little things, like to avoid gcc to warn on
> compiletime and so on...
> 
> For the first point nevertheless, i don't know why AsSvg never add been
> included directly in PostGIS source... Is there a real reason ? 
> I've found nothing on this ml archive...
> It will be IMHO a great thing... :)
> 
> 
> (Following code seems to work fine with PostGIS 0.8.1 or 0.8.2, not
> tested with current CVS)
> 
> 
> 
> =============== assvg.c.in ========================================
> 
> 
> 
> 
> /**
>  * SVG features
>  */
> 
> PG_FUNCTION_INFO_V1(assvg_geometry);
> Datum assvg_geometry(PG_FUNCTION_ARGS)
> {
> 	GEOMETRY 	*geom1 = (GEOMETRY *) 
> 				PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
> 	char	   	*wkt;
> 	char	   	*result;
> 	int	   	len;
> 	int32           svgrel;
> 	int32		precision;
> 
> 
> 	// check for relative path notation
> 	if ( ! PG_ARGISNULL(1) )
> 		svgrel = PG_GETARG_INT32(1);
> 	else
> 		svgrel = 0;
> 
> 	if ( ! PG_ARGISNULL(2) )
> 		precision = PG_GETARG_INT32(2);
> 	else
> 		precision = 0;
> 		
> 	wkt = geometry_to_svg(geom1, svgrel, precision);
> 
> 	len = strlen(wkt) + 5;
> 
> 	result= palloc(len);
> 	*((int *) result) = len;
> 
> 	memcpy(result +4, wkt, len-4);
> 
> 	pfree(wkt);
> 
> 	PG_RETURN_CSTRING(result);
> }
> 
> 
> //takes a GEOMETRY and returns a SVG representation
> char *geometry_to_svg(GEOMETRY  *geometry, int svgrel, int precision)
> {
> 	char		*result;
> 	int		t,u;
> 	int32		*offsets;
> 	char		*obj;
> 	POINT3D	*pts;
> 	POLYGON3D	*polygon;
> 	LINE3D	*line;
> 	POINT3D	*point;
> 
> 	int		pt_off,size;
> 	bool		first_sub_obj = TRUE;
> 	int		mem_size,npts;
> 
> 	size = 30;	//just enough to put in object type
> 	//try to limit number of repalloc()s
> 	result = (char *) palloc(30); mem_size= 30;
> 
> 	// TODO BBox, from where is it called?...
> 	if (geometry->type == BBOXONLYTYPE)
> 	{
> 		if (svgrel == 1)
> 		{
> 			// 5 double digits+ "Mhvhz"+ spaces +null
> 			mem_size = MAX_DIGS_DOUBLE*5+5+6+1;
> 			pfree(result);
> 			result = (char *) palloc(mem_size); 
> 
> 			sprintf(result, "M %.*f %.*f h%.*f v%.*f h%.*f z",
> 				precision, 
> 				geometry->bvol.LLB.x,
> 				precision, 
> 				geometry->bvol.URT.y*-1,
> 				precision, 
> 				(geometry->bvol.URT.x 
> 				 - geometry->bvol.LLB.x),
> 				precision, 
> 				(geometry->bvol.URT.y 
> 				 - geometry->bvol.LLB.y),
> 				precision, 
> 				(geometry->bvol.URT.x 
> 				 - geometry->bvol.LLB.x)*-1);
> 		}
> 		else
> 		{
> 			mem_size = MAX_DIGS_DOUBLE*4+3+1;
> 			pfree(result);
> 			result = (char *) palloc(mem_size); 
> 			// 4 double digits + 3 spaces +null
> 
> 			sprintf(result, "%.*f %.*f %.*f %.*f",
> 				precision,
> 				geometry->bvol.LLB.x,
> 				precision,
> 				geometry->bvol.URT.y*-1,
> 				precision,
> 				(geometry->bvol.URT.x - 
> geometry->bvol.LLB.x),
> 				precision, 
> 				(geometry->bvol.URT.y - 
> geometry->bvol.LLB.y)
> 				);
> 		}
> 		return result;
> 	}
> 
> 	// no more warnings on compiletime
> 	sprintf(result,"%s", "");
> 
> 	if (geometry->type == COLLECTIONTYPE)
> 	{
> 		sprintf(result, "GEOMETRYCOLLECTION not yet supported");
> 		return result;
> 	}
> 
> 	//where are the objects?
> 	offsets = (int32 *) ( ((char *) &(geometry->objType[0] ))
> 			+ sizeof(int32) * geometry->nobjs ) ;
> 
> 	for(t=0;t<geometry->nobjs; t++)  //for each object
> 	{
> 		obj = (char *) geometry +offsets[t] ;
> 
> 		if (geometry->objType[t] == 1)   //POINT
> 		{
> 			point = (POINT3D *) obj;
> 			size +=MAX_DIGS_DOUBLE*3 + 2 +10  ;
> 			//make memory bigger
> 			result = repalloc(result, size );
> 
> 			if (!(first_sub_obj))
> 			{	
> 				// next circle ...
> 				strcat(result,",");
> 			}
> 			else
> 			{
> 				first_sub_obj = FALSE;
> 			}
> 			if (svgrel == 1)
> 			{  
> 				//render circle
> 				print_svg_coords(result, point, precision);
> 			}
> 			else
> 			{  
> 				//render circle
> 				print_svg_circle(result, point, precision);
> 			}
> 
> 		}
> 		if (geometry->objType[t] == 2)	//LINESTRING
> 		{
> 			line = (LINE3D *) obj;
> 
> 			size +=(MAX_DIGS_DOUBLE*3+5)*line->npoints +12+3;
> 			result = repalloc(result, size );
> 
> 			// start path with moveto
> 			strcat(result, "M ");
> 
> 			if (svgrel == 1)
> 				print_svg_path_rel(
> 						result,
> 						&line->points[0],
> 						line->npoints, 
> 						precision
> 						);
> 			else
> 				print_svg_path_abs(
> 						result,
> 						&line->points[0],
> 						line->npoints,
> 						precision
> 						);
> 
> 			strcat(result," ");
> 		}
> 		if (geometry->objType[t] == 3)	//POLYGON
> 		{
> 			polygon = (POLYGON3D *) obj;
> 			pt_off = 0;	//where is the first point 
> in this ring?
> 
> 			//where are the points
> 			pts = (POINT3D *)
> 				((char 
> *)&(polygon->npoints[polygon->nrings]));
> 			pts = (POINT3D *) MAXALIGN(pts);
> 
> 			npts = 0;
> 			for (u=0; u< polygon->nrings ; u++)
> 				npts += polygon->npoints[u];
> 
> 			size += (MAX_DIGS_DOUBLE*3+3) 
> 				* npts + 5* polygon->nrings;
> 			result = repalloc(result, size );
> 
> 			for (u=0; u< polygon->nrings ; u++)  //for each ring
> 			{
> 				strcat(result,"M ");	//begin ring
> 				if (svgrel == 1)
> 					print_svg_path_rel(result, 
> 							&pts[pt_off] ,
> 							polygon->npoints[u],
> 							precision);
> 				else
> 					print_svg_path_abs(result,
> 							&pts[pt_off],
> 							polygon->npoints[u],
> 							precision);
> 				
> 				//where is first point of next ring?
> 				pt_off = pt_off + polygon->npoints[u]; 
> 				strcat(result," ");	//end ring
> 			}
> 		}
> 	}
> 	return(result);
> }
> 
> 
> void print_svg_coords(char *result, POINT3D *pt, int precision)
> {
> 	char	temp[MAX_DIGS_DOUBLE*3 +12];
> 
> 	if ( (pt == NULL) || (result == NULL) )
> 		return;
> 
> 	sprintf(temp, "x=\"%.*f\" y=\"%.*f\"", 
> 			precision, pt->x, 
> 			precision, pt->y*-1);
> 	strcat(result,temp);
> }
> 
> 
> void print_svg_circle(char *result, POINT3D *pt, int precision)
> {
> 	char	temp[MAX_DIGS_DOUBLE*3 +12];
> 
> 	if ( (pt == NULL) || (result == NULL) )
> 		return;
> 
> 	sprintf(temp, "cx=\"%.*f\" cy=\"%.*f\"", 
> 			precision, pt->x, 
> 			precision, pt->y*-1);
> 	strcat(result,temp);
> }
> 
> 
> void print_svg_path_abs(char *result, POINT3D *pt ,int npoints, int
> precision){
> 	int	u;
> 
> 	result += strlen(result);
> 	for (u=0;u<npoints;u++)
> 	{
> 		if (u != 0)
> 		{
> 			result[0] = ' ';
> 			result++;
> 		}
> 		result+= sprintf(result,"%.*f %.*f", 
> 				precision, pt[u].x, 
> 				precision, pt[u].y*-1);
> 	}
> }
> 
> 
> void print_svg_path_rel(char *result, POINT3D *pt ,int npoints, int
> precision){
> 	int	u;
> 
> 	result += strlen(result);
> 	for (u=0;u<npoints;u++)
> 	{
> 		if (u == 0)
> 		{
> 			result+= sprintf(result,"%.*f %.*f l", 
> 					precision, pt[u].x, 
> 					precision, pt[u].y*-1);
> 		}
> 		else
> 		{
> 			result+= sprintf(result," %.*f %.*f", 
> 					precision, (pt[u].x-pt[u-1].x), 
> 					precision, (pt[u].y-pt[u-1].y)*-1);
> 		}
> 	}
> }
> 
> 
> 
> 
> 
> =========================== assvg.h.in ================================
> 
> Datum assvg_geometry(PG_FUNCTION_ARGS);
> char *geometry_to_svg(GEOMETRY  *geometry, int svgrel, int precision);
> void print_svg_coords(char *result, POINT3D *pt, int precision);
> void print_svg_circle(char *result, POINT3D *pt, int precision);
> void print_svg_path_abs(char *result, POINT3D *pt ,int npoints, int
> precision); void print_svg_path_rel(char *result, POINT3D *pt ,int
> npoints, int precision);
> 
> 
> =========================== assvg.sql.in ==============================
> 
> CREATE FUNCTION assvg(geometry)
> 	RETURNS TEXT
> 	AS '@MODULE_FILENAME@','assvg_geometry'
> 	LANGUAGE 'c'  with (isstrict);
> 
> CREATE FUNCTION assvg(geometry,int4)
> 	RETURNS TEXT
> 	AS '@MODULE_FILENAME@','assvg_geometry'
> 	LANGUAGE 'c'  with (isstrict);
> 
> CREATE FUNCTION assvg(geometry,int4,int4)
> 	RETURNS TEXT
> 	AS '@MODULE_FILENAME@','assvg_geometry'
> 	LANGUAGE 'c'  with (isstrict);
> 
> 
> =====================================================================
> 
> HTH :)
> 
> --
> Ol
> 
> _______________________________________________
> postgis-users mailing list
> postgis-users at postgis.refractions.net
> http://postgis.refractions.net/mailman/listinfo/postgis-users




More information about the postgis-users mailing list