** Creates a GD image of a legend for a specific map. msDrawLegend() ** respects the current scale, and classes without a name are not ** added to the legend. ** ** scale_independent is used for WMS GetLegendGraphic. It should be set to ** MS_FALSE in most cases. If it is set to MS_TRUE then the layers' minscale ** and maxscale are ignored and layers that are currently out of scale still ** show u
| 450 | ** show up in the legend. |
| 451 | */ |
| 452 | imageObj *msDrawLegend(mapObj *map, int scale_independent) |
| 453 | { |
| 454 | int i,j; /* loop counters */ |
| 455 | pointObj pnt; |
| 456 | int size_x, size_y=0; |
| 457 | layerObj *lp; |
| 458 | rectObj rect; |
| 459 | imageObj *image = NULL; |
| 460 | outputFormatObj *format = NULL; |
| 461 | char *text; |
| 462 | |
| 463 | struct legend_struct { |
| 464 | int height; |
| 465 | char *transformedText; |
| 466 | layerObj *layer; |
| 467 | classObj *theclass; |
| 468 | struct legend_struct* pred; |
| 469 | }; |
| 470 | typedef struct legend_struct legendlabel; |
| 471 | legendlabel *head=NULL,*cur=NULL; |
| 472 | |
| 473 | if(!MS_RENDERER_PLUGIN(map->outputformat)) { |
| 474 | msSetError(MS_MISCERR,"unsupported output format","msDrawLegend()"); |
| 475 | return NULL; |
| 476 | } |
| 477 | if(msValidateContexts(map) != MS_SUCCESS) return NULL; /* make sure there are no recursive REQUIRES or LABELREQUIRES expressions */ |
| 478 | if(msLegendCalcSize(map, scale_independent, &size_x, &size_y, NULL, 0) != MS_SUCCESS) return NULL; |
| 479 | |
| 480 | /* |
| 481 | * step through all map classes, and for each one that will be displayed |
| 482 | * keep a reference to its label size and text |
| 483 | */ |
| 484 | for(i=0; i<map->numlayers; i++) { |
| 485 | lp = (GET_LAYER(map, map->layerorder[i])); |
| 486 | |
| 487 | if((lp->status == MS_OFF) || (lp->type == MS_LAYER_QUERY)) /* skip it */ |
| 488 | continue; |
| 489 | |
| 490 | if(!scale_independent && map->scaledenom > 0) { |
| 491 | if((lp->maxscaledenom > 0) && (map->scaledenom > lp->maxscaledenom)) continue; |
| 492 | if((lp->minscaledenom > 0) && (map->scaledenom <= lp->minscaledenom)) continue; |
| 493 | } |
| 494 | |
| 495 | if(!scale_independent && lp->maxscaledenom <=0 && lp->minscaledenom <=0) { |
| 496 | if((lp->maxgeowidth > 0) && ((map->extent.maxx - map->extent.minx) > lp->maxgeowidth)) continue; |
| 497 | if((lp->mingeowidth > 0) && ((map->extent.maxx - map->extent.minx) < lp->mingeowidth)) continue; |
| 498 | } |
| 499 | |
| 500 | for(j=lp->numclasses-1;j>=0;j--) { |
| 501 | text = lp->class[j]->title?lp->class[j]->title:lp->class[j]->name; /* point to the right legend text, title takes precedence */ |
| 502 | if(!text) continue; /* skip it */ |
| 503 | |
| 504 | /* skip the class if the classgroup is defined */ |
| 505 | if(lp->classgroup && (lp->class[j]->group == NULL || strcasecmp(lp->class[j]->group, lp->classgroup) != 0)) |
| 506 | continue; |
| 507 | |
| 508 | if(!scale_independent && map->scaledenom > 0) { /* verify class scale here */ |
| 509 | if((lp->class[j]->maxscaledenom > 0) && (map->scaledenom > lp->class[j]->maxscaledenom)) continue; |
no test coverage detected