[GRASS-dev] how to derive polygons (bounding boxes) from text strings

Hello list,

I have a point feature layer with attributes for a text string (call it ‘label’) and the fontsize in map units (which are meters in my case).

Is there a way in Grass to derive polygons (like boundig boxes) from this input information which enclose the label string letter when those are used to label the points?

For those who know ArcMap: what I mean is exactly what happens when you export Annotation features as Shapes in ArcCatalog: you get a polygon layer in which each text string has a polygon hull which fits the height and width, respectively.

From a developer, I heard that this can be done d_get_text_box from display library, which is not exposed to the end user.

Since I am not a programmer, I am looking for help how to use d_get_text_box. My goal ist o integrate it in a simple Python script which I already have. This script can import Shapefiles, do simple GIS processing using GRASS modules and write the shapes back.

Of course, if coding is necessary to accomplish this, I will pay for it.

thank you and best regards, Uwe

Hello Uwe,

On Fri, Dec 9, 2022 at 10:29 AM <gisfisch@t-online.de> wrote:

Hello list,

I have a point feature layer with attributes for a text string (call it 'label') and the fontsize in map units (which are meters in my case).

Is there a way in Grass to derive polygons (like boundig boxes) from this input information which enclose the label string letter when those are used to label the points?

For those who know ArcMap: what I mean is exactly what happens when you export Annotation features as Shapes in ArcCatalog: you get a polygon layer in which each text string has a polygon hull which fits the height and width, respectively.

From a developer, I heard that this can be done d_get_text_box from display library, which is not exposed to the end user.

Well, it is exposed to the "C language" end user :slight_smile:

For a local test, I have added these lines (as a simple debug output):

git diff display/d.text/
diff --git a/display/d.text/main.c b/display/d.text/main.c
index a5fb7fec7..0aab3db8d 100644
--- a/display/d.text/main.c
+++ b/display/d.text/main.c
@@ -626,10 +626,12 @@ static void draw_text(char *text, double *x,
double *y, double size,
        D_text_rotation(0.0);

     D_get_text_box(text, &t, &b, &l, &r);
+ fprintf(stdout, "t: %.2f, b: %.2f, l: %.2f, r: %.2f\n", t, b, l, r);
     t = D_u_to_d_row(t);
     b = D_u_to_d_row(b);
     l = D_u_to_d_col(l);
     r = D_u_to_d_col(r);
+ fprintf(stdout, "t: %.2f, b: %.2f, l: %.2f, r: %.2f\n", t, b, l, r);

     if (rotation != 0.0)
        D_text_rotation(rotation * 180.0 / M_PI);

I guess it would do what you need - tested in North Carolina sample
data location:

GRASS nc_spm_08_grass7/user1:d.text >

g.region raster=zipcodes_elev_avg
d.mon wx0

# test 1: font size 4
d.text text="This is a test of d.text" color=yellow bgcolor=gray size=4
t: 228897.44, b: 228500.00, l: 626709.08, r: 634951.64
t: -26.02, b: 0.00, l: 3.39, r: 543.13

# test 2: font size 6
d.text text="This is a test of d.text" color=yellow bgcolor=gray size=6
t: 229096.16, b: 228500.00, l: 626735.00, r: 639098.84
t: -39.04, b: 0.00, l: 5.09, r: 814.69

Since I am not a programmer, I am looking for help how to use d_get_text_box. My goal ist o integrate it in a
simple Python script which I already have. This script can import Shapefiles, do simple GIS processing using
GRASS modules and write the shapes back.

The (current) pity is that there is no Python wrapper around the
display library in

https://github.com/OSGeo/grass/tree/main/python/grass/pygrass
https://github.com/OSGeo/grass/tree/main/python/grass/script

Of course, if coding is necessary to accomplish this, I will pay for it.

Maybe not a hard task to write this Python access to the C function
D_get_text_box() but unfortunately I am lacking time.
Hopefully someone else here is willing to pick up the task.

Best,
Markus

thank you and best regards, Uwe

I did some tinkering around the potential interface for such module:
https://github.com/marisn/grass-addons/tree/v_text_bbox/src/vector/v.text.bbox

Uwe, if nobody else has stepped up to help you, poke me after
Christmas as I might have some spare evening before the New Years eave
to do more fiddling.
Māris.

trešd., 2022. g. 14. dec., plkst. 22:16 — lietotājs Markus Neteler
(<neteler@osgeo.org>) rakstīja:

Hello Uwe,

On Fri, Dec 9, 2022 at 10:29 AM <gisfisch@t-online.de> wrote:
>
> Hello list,
>
> I have a point feature layer with attributes for a text string (call it 'label') and the fontsize in map units (which are meters in my case).
>
> Is there a way in Grass to derive polygons (like boundig boxes) from this input information which enclose the label string letter when those are used to label the points?
>
> For those who know ArcMap: what I mean is exactly what happens when you export Annotation features as Shapes in ArcCatalog: you get a polygon layer in which each text string has a polygon hull which fits the height and width, respectively.
>
> From a developer, I heard that this can be done d_get_text_box from display library, which is not exposed to the end user.

Well, it is exposed to the "C language" end user :slight_smile:

For a local test, I have added these lines (as a simple debug output):

git diff display/d.text/
diff --git a/display/d.text/main.c b/display/d.text/main.c
index a5fb7fec7..0aab3db8d 100644
--- a/display/d.text/main.c
+++ b/display/d.text/main.c
@@ -626,10 +626,12 @@ static void draw_text(char *text, double *x,
double *y, double size,
        D_text_rotation(0.0);

     D_get_text_box(text, &t, &b, &l, &r);
+ fprintf(stdout, "t: %.2f, b: %.2f, l: %.2f, r: %.2f\n", t, b, l, r);
     t = D_u_to_d_row(t);
     b = D_u_to_d_row(b);
     l = D_u_to_d_col(l);
     r = D_u_to_d_col(r);
+ fprintf(stdout, "t: %.2f, b: %.2f, l: %.2f, r: %.2f\n", t, b, l, r);

     if (rotation != 0.0)
        D_text_rotation(rotation * 180.0 / M_PI);

I guess it would do what you need - tested in North Carolina sample
data location:

GRASS nc_spm_08_grass7/user1:d.text >

g.region raster=zipcodes_elev_avg
d.mon wx0

# test 1: font size 4
d.text text="This is a test of d.text" color=yellow bgcolor=gray size=4
t: 228897.44, b: 228500.00, l: 626709.08, r: 634951.64
t: -26.02, b: 0.00, l: 3.39, r: 543.13

# test 2: font size 6
d.text text="This is a test of d.text" color=yellow bgcolor=gray size=6
t: 229096.16, b: 228500.00, l: 626735.00, r: 639098.84
t: -39.04, b: 0.00, l: 5.09, r: 814.69

> Since I am not a programmer, I am looking for help how to use d_get_text_box. My goal ist o integrate it in a
> simple Python script which I already have. This script can import Shapefiles, do simple GIS processing using
> GRASS modules and write the shapes back.

The (current) pity is that there is no Python wrapper around the
display library in

https://github.com/OSGeo/grass/tree/main/python/grass/pygrass
https://github.com/OSGeo/grass/tree/main/python/grass/script

> Of course, if coding is necessary to accomplish this, I will pay for it.

Maybe not a hard task to write this Python access to the C function
D_get_text_box() but unfortunately I am lacking time.
Hopefully someone else here is willing to pick up the task.

Best,
Markus

> thank you and best regards, Uwe
>
_______________________________________________
grass-dev mailing list
grass-dev@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/grass-dev