Skip to content

Commit f152773

Browse files
Francois Blackburntbonfort
Francois Blackburn
authored andcommitted
Reduce UTF grid size by removing unused entries (#5002)
1 parent 2dca9cb commit f152773

File tree

1 file changed

+134
-29
lines changed

1 file changed

+134
-29
lines changed

maputfgrid.cpp

Lines changed: 134 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static utfpix32 UTF_WATER = utfpix32(32);
5050

5151
#define utfitem(c) utfpix32(c)
5252

53-
struct shapeData
53+
struct shapeData
5454
{
5555
char *datavalues;
5656
char *itemvalue;
@@ -71,7 +71,7 @@ class lookupTable {
7171
counter = 0;
7272
}
7373

74-
~lookupTable()
74+
~lookupTable()
7575
{
7676
int i;
7777

@@ -82,7 +82,7 @@ class lookupTable {
8282
if(table[i].itemvalue)
8383
msFree(table[i].itemvalue);
8484
}
85-
msFree(table);
85+
msFree(table);
8686
}
8787

8888
shapeData *table;
@@ -96,12 +96,12 @@ class lookupTable {
9696
class polygon_adaptor_utf:public polygon_adaptor
9797
{
9898
public:
99-
polygon_adaptor_utf(shapeObj *shape,int utfres_in):polygon_adaptor(shape)
99+
polygon_adaptor_utf(shapeObj *shape,int utfres_in):polygon_adaptor(shape)
100100
{
101101
utfresolution = utfres_in;
102102
}
103103

104-
virtual unsigned vertex(double* x, double* y)
104+
virtual unsigned vertex(double* x, double* y)
105105
{
106106
if(m_point < m_pend) {
107107
bool first = m_point == m_line->point;
@@ -125,7 +125,7 @@ class polygon_adaptor_utf:public polygon_adaptor
125125
}
126126
return mapserver::path_cmd_stop;
127127
}
128-
128+
129129
private:
130130
int utfresolution;
131131
};
@@ -136,7 +136,7 @@ class polygon_adaptor_utf:public polygon_adaptor
136136
class line_adaptor_utf:public line_adaptor
137137
{
138138
public:
139-
line_adaptor_utf(shapeObj *shape,int utfres_in):line_adaptor(shape)
139+
line_adaptor_utf(shapeObj *shape,int utfres_in):line_adaptor(shape)
140140
{
141141
utfresolution = utfres_in;
142142
}
@@ -152,8 +152,8 @@ class line_adaptor_utf:public line_adaptor
152152
}
153153
m_line++;
154154
*x = *y = 0.0;
155-
if(m_line>=m_lend)
156-
return mapserver::path_cmd_stop;
155+
if(m_line>=m_lend)
156+
return mapserver::path_cmd_stop;
157157

158158
m_point=m_line->point;
159159
m_pend=&(m_line->point[m_line->numpoints]);
@@ -217,6 +217,24 @@ unsigned int encodeForRendering(unsigned int toencode)
217217
return encoded;
218218
}
219219

220+
/*
221+
* Decode value to have the initial one
222+
*/
223+
unsigned int decodeRendered(unsigned int todecode)
224+
{
225+
unsigned int decoded;
226+
227+
if(todecode >= 92)
228+
todecode --;
229+
230+
if(todecode >= 34)
231+
todecode --;
232+
233+
decoded = todecode-32;
234+
235+
return decoded;
236+
}
237+
220238
/*
221239
* Allocate more memory to the table if necessary.
222240
*/
@@ -285,8 +303,8 @@ band_type addToTable(UTFGridRenderer *r, shapeObj *p)
285303
/*
286304
* Use AGG to render any path.
287305
*/
288-
template<class vertex_source>
289-
int utfgridRenderPath(imageObj *img, vertex_source &path)
306+
template<class vertex_source>
307+
int utfgridRenderPath(imageObj *img, vertex_source &path)
290308
{
291309
UTFGridRenderer *r = UTFGRID_RENDERER(img);
292310
r->m_rasterizer.reset();
@@ -359,6 +377,91 @@ int utfgridFreeImage(imageObj *img)
359377
return MS_SUCCESS;
360378
}
361379

380+
/*
381+
* Update a character in the utfgrid.
382+
*/
383+
384+
int utfgridUpdateChar(imageObj *img, band_type oldChar, band_type newChar)
385+
{
386+
UTFGridRenderer *r = UTFGRID_RENDERER(img);
387+
int i,bufferLength;
388+
389+
bufferLength = (img->height/r->utfresolution) * (img->width/r->utfresolution);
390+
391+
for(i=0;i<bufferLength;i++){
392+
if(r->buffer[i] == oldChar)
393+
r->buffer[i] = newChar;
394+
}
395+
396+
return MS_SUCCESS;
397+
}
398+
399+
/*
400+
* Remove unnecessary data that didn't made it to the final grid.
401+
*/
402+
403+
int utfgridCleanData(imageObj *img)
404+
{
405+
UTFGridRenderer *r = UTFGRID_RENDERER(img);
406+
unsigned char* usedChar;
407+
int i,bufferLength,itemFound,dataCounter;
408+
shapeData* updatedData;
409+
band_type utfvalue;
410+
411+
bufferLength = (img->height/r->utfresolution) * (img->width/r->utfresolution);
412+
413+
usedChar =(unsigned char*) msSmallMalloc(r->data->counter*sizeof(unsigned char));
414+
415+
for(i=0;i<r->data->counter;i++){
416+
usedChar[i]=0;
417+
}
418+
419+
itemFound=0;
420+
421+
for(i=0;i<bufferLength;i++)
422+
{
423+
if(decodeRendered(r->buffer[i]) != 0 && usedChar[decodeRendered(r->buffer[i])-1]==0)
424+
{
425+
itemFound++;
426+
usedChar[decodeRendered(r->buffer[i])-1] = 1;
427+
}
428+
}
429+
430+
updatedData = (shapeData*) msSmallMalloc(itemFound * sizeof(shapeData));
431+
dataCounter = 0;
432+
433+
for(i=0; i< r->data->counter; i++){
434+
if(usedChar[decodeRendered(r->data->table[i].utfvalue)-1]==1){
435+
updatedData[dataCounter] = r->data->table[i];
436+
437+
updatedData[dataCounter].serialid=dataCounter+1;
438+
439+
utfvalue=encodeForRendering(dataCounter+1);
440+
441+
utfgridUpdateChar(img,updatedData[dataCounter].utfvalue,utfvalue);
442+
updatedData[dataCounter].utfvalue = utfvalue;
443+
444+
dataCounter++;
445+
}
446+
else {
447+
if(r->data->table[i].datavalues)
448+
msFree(r->data->table[i].datavalues);
449+
if(r->data->table[i].itemvalue)
450+
msFree(r->data->table[i].itemvalue);
451+
}
452+
}
453+
454+
msFree(usedChar);
455+
456+
msFree(r->data->table);
457+
458+
r->data->table = updatedData;
459+
r->data->counter = dataCounter;
460+
r->data->size = dataCounter;
461+
462+
return MS_SUCCESS;
463+
}
464+
362465
/*
363466
* Print the renderer datas as a JSON.
364467
*/
@@ -367,20 +470,22 @@ int utfgridSaveImage(imageObj *img, mapObj *map, FILE *fp, outputFormatObj *form
367470
int row, col, i, imgheight, imgwidth;
368471
band_type pixelid;
369472
char* pszEscaped;
370-
473+
474+
utfgridCleanData(img);
475+
371476
UTFGridRenderer *renderer = UTFGRID_RENDERER(img);
372477

373478
if(renderer->layerwatch>1)
374-
return MS_FAILURE;
479+
return MS_FAILURE;
375480

376481
imgheight = img->height/renderer->utfresolution;
377482
imgwidth = img->width/renderer->utfresolution;
378483

379484
fprintf(fp,"{\"grid\":[");
380485

381-
/* Print the buffer, also */
486+
/* Print the buffer, also */
382487
for(row=0; row<imgheight; row++) {
383-
488+
384489
wchar_t *string = (wchar_t*) msSmallMalloc ((imgwidth + 1) * sizeof(wchar_t));
385490
wchar_t *stringptr;
386491
stringptr = string;
@@ -393,11 +498,11 @@ int utfgridSaveImage(imageObj *img, mapObj *map, FILE *fp, outputFormatObj *form
393498
pixelid = renderer->buffer[(row*imgwidth)+col];
394499

395500
*stringptr = pixelid;
396-
stringptr++;
501+
stringptr++;
397502
}
398503

399504
/* Convertion to UTF-8 encoding */
400-
*stringptr = '\0';
505+
*stringptr = '\0';
401506
char * utf8;
402507
utf8 = msConvertWideStringToUTF8 (string, "UCS-4LE");
403508
fprintf(fp,"%s", utf8);
@@ -409,7 +514,7 @@ int utfgridSaveImage(imageObj *img, mapObj *map, FILE *fp, outputFormatObj *form
409514
fprintf(fp,"],\"keys\":[\"\"");
410515

411516
/* Prints the key specified */
412-
for(i=0;i<renderer->data->counter;i++) {
517+
for(i=0;i<renderer->data->counter;i++) {
413518
fprintf(fp,",");
414519

415520
if(renderer->useutfitem)
@@ -504,11 +609,11 @@ int utfgridEndLayer(imageObj *img, mapObj *map, layerObj *layer)
504609
* Do the table operations on the shapes. Allow multiple type of data to be rendered.
505610
*/
506611
int utfgridStartShape(imageObj *img, shapeObj *shape)
507-
{
612+
{
508613
UTFGridRenderer *r = UTFGRID_RENDERER(img);
509614

510615
if(!r->renderlayer)
511-
return MS_FAILURE;
616+
return MS_FAILURE;
512617

513618
/* Table operations */
514619
r->utfvalue = addToTable(r, shape);
@@ -521,7 +626,7 @@ int utfgridStartShape(imageObj *img, shapeObj *shape)
521626
*/
522627
int utfgridEndShape(imageObj *img, shapeObj *shape)
523628
{
524-
UTFGridRenderer *r = UTFGRID_RENDERER(img);
629+
UTFGridRenderer *r = UTFGRID_RENDERER(img);
525630

526631
r->utfvalue = 0;
527632
return MS_SUCCESS;
@@ -547,7 +652,7 @@ int utfgridRenderPolygon(imageObj *img, shapeObj *polygonshape, colorObj *color)
547652
}
548653

549654
/*
550-
* Function that render lines into UTFGrid. Starts by looking if the line is a polygon
655+
* Function that render lines into UTFGrid. Starts by looking if the line is a polygon
551656
* outline. Then draw it if it's not.
552657
*/
553658
int utfgridRenderLine(imageObj *img, shapeObj *lineshape, strokeStyleObj *linestyle)
@@ -567,7 +672,7 @@ int utfgridRenderLine(imageObj *img, shapeObj *lineshape, strokeStyleObj *linest
567672
} else {
568673
r->stroke->attach(lines);
569674
}
570-
r->stroke->width(linestyle->width/r->utfresolution);
675+
r->stroke->width(linestyle->width/r->utfresolution);
571676
utfgridRenderPath(img, *r->stroke);
572677

573678
return MS_SUCCESS;
@@ -585,7 +690,7 @@ int utfgridRenderVectorSymbol(imageObj *img, double x, double y, symbolObj *symb
585690
/* utfvalue is set to 0 if the shape isn't in the table. */
586691
if(r->utfvalue == 0) {
587692
return MS_FAILURE;
588-
}
693+
}
589694

590695
/* Pathing the symbol */
591696
mapserver::path_storage path = imageVectorSymbol(symbol);
@@ -615,12 +720,12 @@ int utfgridRenderPixmapSymbol(imageObj *img, double x, double y, symbolObj *symb
615720
/* utfvalue is set to 0 if the shape isn't in the table. */
616721
if(r->utfvalue == 0) {
617722
return MS_FAILURE;
618-
}
723+
}
619724

620725
/* Pathing the symbol BBox */
621726
mapserver::path_storage pixmap_bbox;
622727
double w, h;
623-
w = pixmap->width*style->scale/(2.0);
728+
w = pixmap->width*style->scale/(2.0);
624729
h= pixmap->height*style->scale/(2.0);
625730
pixmap_bbox.move_to((x-w)/r->utfresolution,(y-h)/r->utfresolution);
626731
pixmap_bbox.line_to((x+w)/r->utfresolution,(y-h)/r->utfresolution);
@@ -643,13 +748,13 @@ int utfgridRenderEllipseSymbol(imageObj *img, double x, double y, symbolObj *sym
643748
/* utfvalue is set to 0 if the shape isn't in the table. */
644749
if(r->utfvalue == 0) {
645750
return MS_FAILURE;
646-
}
751+
}
647752

648753
/* Pathing the symbol. */
649754
mapserver::path_storage path;
650755
mapserver::ellipse ellipse(x/r->utfresolution,y/r->utfresolution,symbol->sizex*style->scale/2/r->utfresolution,symbol->sizey*style->scale/2/r->utfresolution);
651756
path.concat_path(ellipse);
652-
757+
653758
/* Rotation if necessary. */
654759
if( style->rotation != 0) {
655760
mapserver::trans_affine mtx;
@@ -686,7 +791,7 @@ int msPopulateRendererVTableUTFGrid( rendererVTableObj *renderer )
686791
renderer->saveImage = &utfgridSaveImage;
687792

688793
renderer->startLayer = &utfgridStartLayer;
689-
renderer->endLayer = &utfgridEndLayer;
794+
renderer->endLayer = &utfgridEndLayer;
690795

691796
renderer->startShape = &utfgridStartShape;
692797
renderer->endShape = &utfgridEndShape;

0 commit comments

Comments
 (0)