[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