struct hashObj *msInsertHashTable(hashTableObj *table, const char *key, const char *value) { struct hashObj *tp; unsigned hashval; if (!table || !key || !value) { msSetError(MS_HASHERR, "Invalid hash table or key", "msInsertHashTable"); return NULL; } for (tp=table->items[hash(key)]; tp!=NULL; tp=tp->next) if(strcasecmp(key, tp->key) == 0) break; if (tp == NULL) { /* not found */ tp = (struct hashObj *) malloc(sizeof(*tp)); MS_CHECK_ALLOC(tp, sizeof(*tp), NULL); tp->key = msStrdup(key); hashval = hash(key); tp->next = table->items[hashval]; table->items[hashval] = tp; table->numitems++; } else { free(tp->data); } if ((tp->data = msStrdup(value)) == NULL) return NULL; return tp; }
static int insertNewVTFItem(VTFactoryObj *pVTFactory, VTFactoryItemObj *pVTFI) { /* Ensure there is room for one more item in the array * (safe to use for initial alloc of the array as well) */ if (pVTFactory->first_free == pVTFactory->size) { int i; VTFactoryItemObj **vtItemPtr; vtItemPtr = (VTFactoryItemObj**)realloc(pVTFactory->vtItems, (pVTFactory->size+MS_LAYER_ALLOCSIZE)*sizeof(VTFactoryItemObj*)); MS_CHECK_ALLOC(vtItemPtr, (pVTFactory->size+MS_LAYER_ALLOCSIZE)*sizeof(VTFactoryItemObj*), MS_FAILURE); pVTFactory->size += MS_LAYER_ALLOCSIZE; pVTFactory->vtItems = vtItemPtr; for (i=pVTFactory->first_free; i<pVTFactory->size; i++) pVTFactory->vtItems[i] = NULL; } /* Insert item */ pVTFactory->vtItems[pVTFactory->first_free] = pVTFI; pVTFactory->first_free++; return MS_SUCCESS; }
int getTruetypeTextBBoxGD(rendererVTableObj *renderer, char **fonts, int numfonts, double size, char *string, rectObj *rect, double **advances, int bAdjustBaseline) { #ifdef USE_GD_FT int bbox[8]; char *error; if(advances) { #if defined (GD_HAS_FTEX_XSHOW) char *s; int k; gdFTStringExtra strex; strex.flags = gdFTEX_XSHOW; error = gdImageStringFTEx(NULL, bbox, 0, fonts[0], size, 0, 0, 0, string, &strex); if(error) { msSetError(MS_TTFERR, error, "gdImageStringFTEx()"); return(MS_FAILURE); } *advances = (double*)malloc( strlen(string) * sizeof(double) ); MS_CHECK_ALLOC(*advances, strlen(string) * sizeof(double), MS_FAILURE); s = strex.xshow; k = 0; /* TODO this smells buggy and can cause errors at a higher level. strlen NOK here*/ while ( *s && k < strlen(string) ) { (*advances)[k++] = atof(s); while ( *s && *s != ' ') s++; if ( *s == ' ' ) s++; } gdFree(strex.xshow); /* done with character advances */ rect->minx = bbox[0]; rect->miny = bbox[5]; rect->maxx = bbox[2]; rect->maxy = bbox[1]; return MS_SUCCESS; #else msSetError(MS_TTFERR, "gdImageStringFTEx support is not available or is not current enough (requires 2.0.29 or higher).", "msGetTruetypeTextBBox()"); return(MS_FAILURE); #endif } else { error = gdImageStringFT(NULL, bbox, 0, fonts[0], size, 0, 0, 0, string); if(error) { msSetError(MS_TTFERR, error, "msGetTruetypeTextBBox()"); return(MS_FAILURE); } rect->minx = bbox[0]; rect->miny = bbox[5]; rect->maxx = bbox[2]; rect->maxy = bbox[1]; return MS_SUCCESS; } #else msSetError(MS_TTFERR,"Truetype support not available", "getTruetypeTextBBoxGD()"); return(MS_FAILURE); #endif }
int initHashTable( hashTableObj *table ) { int i; table->items = (struct hashObj **) malloc(sizeof(struct hashObj *)*MS_HASHSIZE); MS_CHECK_ALLOC(table->items, sizeof(struct hashObj *)*MS_HASHSIZE, MS_FAILURE); for (i=0; i<MS_HASHSIZE; i++) table->items[i] = NULL; table->numitems = 0; return MS_SUCCESS; }
static VTFactoryItemObj * createVTFItem(const char *name) { VTFactoryItemObj *pVTFI; pVTFI = (VTFactoryItemObj *)malloc(sizeof(VTFactoryItemObj)); MS_CHECK_ALLOC(pVTFI, sizeof(VTFactoryItemObj), NULL); pVTFI->name = msStrdup(name); memset(&pVTFI->vtable, 0, sizeof(layerVTableObj)); return pVTFI; }
imageObj* msCreateImageKml(int width, int height, outputFormatObj *format, colorObj* bg) { imageObj *image = NULL; image = (imageObj*)malloc(sizeof(imageObj)); MS_CHECK_ALLOC(image, sizeof(imageObj), NULL); memset(image, 0, sizeof(imageObj)); KmlRenderer *ren = new KmlRenderer(width, height, format, bg); image->img.plugin = (void *) ren; return image; }
/********************************************************************** * msAllocWFSLayerInfo() * **********************************************************************/ static msWFSLayerInfo *msAllocWFSLayerInfo(void) { msWFSLayerInfo *psInfo; psInfo = (msWFSLayerInfo*)calloc(1,sizeof(msWFSLayerInfo)); MS_CHECK_ALLOC(psInfo, sizeof(msWFSLayerInfo), NULL); psInfo->pszGMLFilename = NULL; psInfo->rect.minx = psInfo->rect.maxx = 0; psInfo->rect.miny = psInfo->rect.maxy = 0; psInfo->pszGetUrl = NULL; psInfo->nStatus = 0; return psInfo; }
/* add a cached tile to the current image's cache */ tileCacheObj *addTileCache(imageObj *img, imageObj *tile, symbolObj *symbol, symbolStyleObj *style, int width, int height) { tileCacheObj *cachep; if(img->ntiles >= MS_IMAGECACHESIZE) { /* remove last element, size stays the same */ cachep = img->tilecache; /*go to the before last cache object*/ while(cachep->next && cachep->next->next) cachep = cachep->next; /*free the last tile's data*/ msFreeImage(cachep->next->image); /*reuse the last tile object*/ /* make the cache point to the start of the list*/ cachep->next->next = img->tilecache; /* point the global cache to the new first */ img->tilecache = cachep->next; /* the before last cache is now last, so it has no successor*/ cachep->next = NULL; } else { img->ntiles += 1; cachep = (tileCacheObj*)malloc(sizeof(tileCacheObj)); MS_CHECK_ALLOC(cachep, sizeof(tileCacheObj), NULL); cachep->next = img->tilecache; img->tilecache = cachep; } cachep = img->tilecache; cachep->image = tile; cachep->outlinewidth = style->outlinewidth; cachep->scale = style->scale; cachep->rotation = style->rotation; cachep->outlinewidth = style->outlinewidth; if(style->color) MS_COPYCOLOR(&cachep->color,style->color); if(style->outlinecolor) MS_COPYCOLOR(&cachep->outlinecolor,style->outlinecolor); if(style->backgroundcolor) MS_COPYCOLOR(&cachep->backgroundcolor,style->backgroundcolor); cachep->width = width; cachep->height = height; cachep->symbol = symbol; return(cachep); }
/* image i/o */ imageObj *agg2CreateImage(int width, int height, outputFormatObj *format, colorObj * bg) { imageObj *image = NULL; if (format->imagemode != MS_IMAGEMODE_RGB && format->imagemode != MS_IMAGEMODE_RGBA) { msSetError(MS_MISCERR, "AGG2 driver only supports RGB or RGBA pixel models.", "agg2CreateImage()"); return image; } image = (imageObj *) calloc(1, sizeof (imageObj)); MS_CHECK_ALLOC(image, sizeof (imageObj), NULL); AGG2Renderer *r = new AGG2Renderer(); r->buffer = (band_type*)malloc(width * height * 4 * sizeof(band_type)); if (r->buffer == NULL) { msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "agg2CreateImage()", __FILE__, __LINE__, (unsigned int)(width * height * 4 * sizeof(band_type))); free(image); return NULL; } r->m_rendering_buffer.attach(r->buffer, width, height, width * 4); r->m_pixel_format.attach(r->m_rendering_buffer); r->m_renderer_base.attach(r->m_pixel_format); r->m_renderer_scanline.attach(r->m_renderer_base); r->default_gamma = atof(msGetOutputFormatOption( format, "GAMMA", "0.75" )); if(r->default_gamma <= 0.0 || r->default_gamma >= 1.0) { r->default_gamma = 0.75; } r->gamma_function.set(0,r->default_gamma); r->m_rasterizer_aa_gamma.gamma(r->gamma_function); if( bg && !format->transparent ) r->m_renderer_base.clear(aggColor(bg)); else r->m_renderer_base.clear(AGG_NO_COLOR); if (!bg || format->transparent || format->imagemode == MS_IMAGEMODE_RGBA ) { r->use_alpha = true; } else { r->use_alpha = false; } image->img.plugin = (void*) r; return image; }
int *msDBFGetItemIndexes(DBFHandle dbffile, char **items, int numitems) { int *itemindexes=NULL, i; if(numitems == 0) return(NULL); itemindexes = (int *)malloc(sizeof(int)*numitems); MS_CHECK_ALLOC(itemindexes, sizeof(int)*numitems, NULL); for(i=0; i<numitems; i++) { itemindexes[i] = msDBFGetItemIndex(dbffile, items[i]); if(itemindexes[i] == -1) { free(itemindexes); return(NULL); /* item not found */ } } return(itemindexes); }
/* ** GD driver-specific image handling functions. */ imageObj *createImageGD(int width, int height, outputFormatObj *format, colorObj* bg) { imageObj *img = NULL; gdImagePtr ip; img = (imageObj *) calloc(1, sizeof (imageObj)); MS_CHECK_ALLOC(img, sizeof (imageObj), NULL); /* we're only doing PC256 for the moment */ ip = gdImageCreate(width, height); if(!format->transparent && bg && MS_VALID_COLOR(*bg)) gdImageColorAllocate(ip, bg->red, bg->green, bg->blue); /* set the background color */ else { gdImageColorAllocate(ip,117,17,91); /*random bg color (same one as picked in msResampleGDALToMap) */ gdImageColorTransparent(ip, 0); } img->img.plugin = (void *) ip; return img; }
treeObj *msReadTree(char *filename, int debug) { treeObj *tree=NULL; SHPTreeHandle disktree; disktree = msSHPDiskTreeOpen( filename, debug ); if(!disktree) { msSetError(MS_IOERR, NULL, "msReadTree()"); return(NULL); } tree = (treeObj *) malloc(sizeof(treeObj)); MS_CHECK_ALLOC(tree, sizeof(treeObj), NULL); tree->numshapes = disktree->nShapes; tree->maxdepth = disktree->nDepth; tree->root = readTreeNode( disktree ); return(tree); }
/********************************************************************** * msHTTPGetFile() * * Wrapper to call msHTTPExecuteRequests() for a single file. **********************************************************************/ int msHTTPGetFile(const char *pszGetUrl, const char *pszOutputFile, int *pnHTTPStatus, int nTimeout, int bCheckLocalCache, int bDebug) { httpRequestObj *pasReqInfo; /* Alloc httpRequestInfo structs through which status of each request * will be returned. * We need to alloc 2 instance of requestobj so that the last * object in the array can be set to NULL. */ pasReqInfo = (httpRequestObj*)calloc(2, sizeof(httpRequestObj)); MS_CHECK_ALLOC(pasReqInfo, 2*sizeof(httpRequestObj), MS_FAILURE); msHTTPInitRequestObj(pasReqInfo, 2); pasReqInfo[0].pszGetUrl = msStrdup(pszGetUrl); pasReqInfo[0].pszOutputFile = msStrdup(pszOutputFile); pasReqInfo[0].debug = (char)bDebug; if (msHTTPExecuteRequests(pasReqInfo, 1, bCheckLocalCache) != MS_SUCCESS) { *pnHTTPStatus = pasReqInfo[0].nStatus; if (pasReqInfo[0].debug) msDebug("HTTP request failed for %s.\n", pszGetUrl); msHTTPFreeRequestObj(pasReqInfo, 2); free(pasReqInfo); return MS_FAILURE; } *pnHTTPStatus = pasReqInfo[0].nStatus; msHTTPFreeRequestObj(pasReqInfo, 2); free(pasReqInfo); return MS_SUCCESS; }
DBFHandle msDBFOpen( const char * pszFilename, const char * pszAccess ) { DBFHandle psDBF; uchar *pabyBuf; int nFields, nRecords, nHeadLen, nRecLen, iField; char *pszDBFFilename; /* -------------------------------------------------------------------- */ /* We only allow the access strings "rb" and "r+". */ /* -------------------------------------------------------------------- */ if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0 && strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"r+b") != 0 ) return( NULL ); /* -------------------------------------------------------------------- */ /* Ensure the extension is converted to dbf or DBF if it is */ /* currently .shp or .shx. */ /* -------------------------------------------------------------------- */ pszDBFFilename = (char *) msSmallMalloc(strlen(pszFilename)+1); strcpy( pszDBFFilename, pszFilename ); if( strcmp(pszFilename+strlen(pszFilename)-4,".shp") || strcmp(pszFilename+strlen(pszFilename)-4,".shx") ) { strcpy( pszDBFFilename+strlen(pszDBFFilename)-4, ".dbf"); } else if( strcmp(pszFilename+strlen(pszFilename)-4,".SHP") || strcmp(pszFilename+strlen(pszFilename)-4,".SHX") ) { strcpy( pszDBFFilename+strlen(pszDBFFilename)-4, ".DBF"); } /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) ); MS_CHECK_ALLOC(psDBF, sizeof(DBFInfo), NULL); psDBF->fp = fopen( pszDBFFilename, pszAccess ); if( psDBF->fp == NULL ) return( NULL ); psDBF->bNoHeader = MS_FALSE; psDBF->nCurrentRecord = -1; psDBF->bCurrentRecordModified = MS_FALSE; psDBF->pszStringField = NULL; psDBF->nStringFieldLen = 0; free( pszDBFFilename ); /* -------------------------------------------------------------------- */ /* Read Table Header info */ /* -------------------------------------------------------------------- */ pabyBuf = (uchar *) msSmallMalloc(500); fread( pabyBuf, 32, 1, psDBF->fp ); psDBF->nRecords = nRecords = pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256; psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256; psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256; psDBF->nFields = nFields = (nHeadLen - 32) / 32; psDBF->pszCurrentRecord = (char *) msSmallMalloc(nRecLen); /* -------------------------------------------------------------------- */ /* Read in Field Definitions */ /* -------------------------------------------------------------------- */ pabyBuf = (uchar *) SfRealloc(pabyBuf,nHeadLen); psDBF->pszHeader = (char *) pabyBuf; fseek( psDBF->fp, 32, 0 ); fread( pabyBuf, nHeadLen, 1, psDBF->fp ); psDBF->panFieldOffset = (int *) msSmallMalloc(sizeof(int) * nFields); psDBF->panFieldSize = (int *) msSmallMalloc(sizeof(int) * nFields); psDBF->panFieldDecimals = (int *) msSmallMalloc(sizeof(int) * nFields); psDBF->pachFieldType = (char *) msSmallMalloc(sizeof(char) * nFields); for( iField = 0; iField < nFields; iField++ ) { uchar *pabyFInfo; pabyFInfo = pabyBuf+iField*32; if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' ) { psDBF->panFieldSize[iField] = pabyFInfo[16]; psDBF->panFieldDecimals[iField] = pabyFInfo[17]; } else { psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256; psDBF->panFieldDecimals[iField] = 0; } psDBF->pachFieldType[iField] = (char) pabyFInfo[11]; if( iField == 0 ) psDBF->panFieldOffset[iField] = 1; else psDBF->panFieldOffset[iField] = psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1]; } return( psDBF ); }
int msDrawBarChartLayer(mapObj *map, layerObj *layer, imageObj *image) { shapeObj shape; int status=MS_SUCCESS; const char *chartSizeProcessingKey=msLayerGetProcessingKey( layer,"CHART_SIZE" ); const char *barMax=msLayerGetProcessingKey( layer,"CHART_BAR_MAXVAL" ); const char *barMin=msLayerGetProcessingKey( layer,"CHART_BAR_MINVAL" ); float width,height; float barWidth; float *values; styleObj **styles; pointObj center; float barMaxVal,barMinVal; int numvalues = layer->numclasses; if(chartSizeProcessingKey==NULL) { width=height=20; } else { switch(sscanf(chartSizeProcessingKey ,"%f %f",&width,&height)) { case 2: break; case 1: height = width; break; default: msSetError(MS_MISCERR, "msDrawChart format error for processing key \"CHART_SIZE\"", "msDrawBarChartLayer()"); return MS_FAILURE; } } if(barMax) { if(sscanf(barMax,"%f",&barMaxVal)!=1) { msSetError(MS_MISCERR, "Error reading value for processing key \"CHART_BAR_MAXVAL\"", "msDrawBarChartLayer()"); return MS_FAILURE; } } if(barMin) { if(sscanf(barMin,"%f",&barMinVal)!=1) { msSetError(MS_MISCERR, "Error reading value for processing key \"CHART_BAR_MINVAL\"", "msDrawBarChartLayer()"); return MS_FAILURE; } } if(barMin && barMax && barMinVal>=barMaxVal) { msSetError(MS_MISCERR, "\"CHART_BAR_MINVAL\" must be less than \"CHART_BAR_MAXVAL\"", "msDrawBarChartLayer()"); return MS_FAILURE; } barWidth=(float)width/(float)layer->numclasses; if(!barWidth) { msSetError(MS_MISCERR, "Specified width of chart too small to fit given number of classes", "msDrawBarChartLayer()"); return MS_FAILURE; } msInitShape(&shape); values=(float*)calloc(numvalues,sizeof(float)); MS_CHECK_ALLOC(values, numvalues*sizeof(float), MS_FAILURE); styles = (styleObj**)malloc(numvalues*sizeof(styleObj*)); if (styles == NULL) { msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msDrawBarChartLayer()", __FILE__, __LINE__, numvalues*sizeof(styleObj*)); free(values); return MS_FAILURE; } while(MS_SUCCESS == getNextShape(map,layer,values,styles,&shape)) { msDrawStartShape(map, layer, image, &shape); if(findChartPoint(map, &shape, width,height, ¢er)==MS_SUCCESS) { status = msDrawBarChart(map,image, ¢er, values, styles, numvalues, width,height, (barMax!=NULL)?&barMaxVal:NULL, (barMin!=NULL)?&barMinVal:NULL, barWidth); } msDrawEndShape(map,layer,image,&shape); msFreeShape(&shape); } free(values); free(styles); return status; }
/* helper functions */ int agg2GetTruetypeTextBBox(rendererVTableObj *renderer, char **fonts, int numfonts, double size, char *string, rectObj *rect, double **advances,int bAdjustBaseline) { aggRendererCache *cache = (aggRendererCache*)MS_RENDERER_CACHE(renderer); if(aggLoadFont(cache,fonts[0],size) == MS_FAILURE) return MS_FAILURE; int curfontidx = 0; int unicode, curGlyph = 1, numglyphs = 0; if (advances) { numglyphs = msGetNumGlyphs(string); } const mapserver::glyph_cache* glyph; string += msUTF8ToUniChar(string, &unicode); if(curfontidx != 0) { if(aggLoadFont(cache,fonts[0],size) == MS_FAILURE) return MS_FAILURE; curfontidx = 0; } glyph = cache->m_fman.glyph(unicode); if(!glyph || glyph->glyph_index == 0) { int i; for(i=1; i<numfonts; i++) { if(aggLoadFont(cache,fonts[i],size) == MS_FAILURE) return MS_FAILURE; curfontidx = i; glyph = cache->m_fman.glyph(unicode); if(glyph && glyph->glyph_index != 0) { break; } } } if (glyph) { rect->minx = glyph->bounds.x1; rect->maxx = glyph->bounds.x2; rect->miny = glyph->bounds.y1; rect->maxy = bAdjustBaseline?1:glyph->bounds.y2; } else return MS_FAILURE; if (advances) { *advances = (double*) malloc(numglyphs * sizeof (double)); MS_CHECK_ALLOC(*advances, numglyphs * sizeof (double), MS_FAILURE); (*advances)[0] = glyph->advance_x; } double fx = glyph->advance_x, fy = glyph->advance_y; while (*string) { if (advances) { if (*string == '\r' || *string == '\n') (*advances)[curGlyph++] = -fx; } if (*string == '\r') { fx = 0; string++; continue; } if (*string == '\n') { fx = 0; fy += ceil(size * AGG_LINESPACE); string++; continue; } string += msUTF8ToUniChar(string, &unicode); if(curfontidx != 0) { if(aggLoadFont(cache,fonts[0],size) == MS_FAILURE) return MS_FAILURE; curfontidx = 0; } glyph = cache->m_fman.glyph(unicode); if(!glyph || glyph->glyph_index == 0) { int i; for(i=1; i<numfonts; i++) { if(aggLoadFont(cache,fonts[i],size) == MS_FAILURE) return MS_FAILURE; curfontidx = i; glyph = cache->m_fman.glyph(unicode); if(glyph && glyph->glyph_index != 0) { break; } } } if (glyph) { rect->minx = MS_MIN(rect->minx, fx+glyph->bounds.x1); rect->miny = MS_MIN(rect->miny, fy+glyph->bounds.y1); rect->maxx = MS_MAX(rect->maxx, fx+glyph->bounds.x2); rect->maxy = MS_MAX(rect->maxy, fy+(bAdjustBaseline?1:glyph->bounds.y2)); fx += glyph->advance_x; fy += glyph->advance_y; if (advances) { (*advances)[curGlyph++] = glyph->advance_x; } } } return MS_SUCCESS; }
int msAddLabel(mapObj *map, labelObj *label, int layerindex, int classindex, shapeObj *shape, pointObj *point, labelPathObj *labelpath, double featuresize) { int i; labelCacheSlotObj *cacheslot; labelCacheMemberObj *cachePtr=NULL; layerObj *layerPtr=NULL; classObj *classPtr=NULL; if(!label) return(MS_FAILURE); // RFC 77 TODO: set a proper message if(label->status == MS_OFF) return(MS_SUCCESS); /* not an error */ if(!label->annotext) { /* check if we have a labelpnt style */ for(i=0; i<label->numstyles; i++) { if(label->styles[i]->_geomtransform.type == MS_GEOMTRANSFORM_LABELPOINT) break; } if(i==label->numstyles) { /* label has no text or marker symbols */ return MS_SUCCESS; } } layerPtr = (GET_LAYER(map, layerindex)); /* set up a few pointers for clarity */ classPtr = GET_LAYER(map, layerindex)->class[classindex]; if(classPtr->leader.maxdistance) { if (layerPtr->type == MS_LAYER_ANNOTATION) { msSetError(MS_MISCERR, "LEADERs are not supported on annotation layers", "msAddLabel()"); return MS_FAILURE; } if(labelpath) { msSetError(MS_MISCERR, "LEADERs are not supported on ANGLE FOLLOW labels", "msAddLabel()"); return MS_FAILURE; } } /* check that the label intersects the layer mask */ if (layerPtr->mask) { int maskLayerIdx = msGetLayerIndex(map, layerPtr->mask); layerObj *maskLayer = GET_LAYER(map, maskLayerIdx); unsigned char *alphapixptr; if (maskLayer->maskimage && MS_IMAGE_RENDERER(maskLayer->maskimage)->supports_pixel_buffer) { rasterBufferObj rb; memset(&rb, 0, sizeof (rasterBufferObj)); MS_IMAGE_RENDERER(maskLayer->maskimage)->getRasterBufferHandle(maskLayer->maskimage, &rb); if (point) { int x = MS_NINT(point->x); int y = MS_NINT(point->y); /* Using label repeatdistance, we might have a point with x/y below 0. See #4764 */ if (x >= 0 && x < rb.width && y >= 0 && y < rb.height) { #ifdef USE_GD if(rb.type == MS_BUFFER_BYTE_RGBA) { alphapixptr = rb.data.rgba.a+rb.data.rgba.row_step*y + rb.data.rgba.pixel_step*x; if(!*alphapixptr) { /* label point does not intersect mask */ return MS_SUCCESS; } } else { if(!gdImageGetPixel(rb.data.gd_img,x,y)) { return MS_SUCCESS; } } #else assert(rb.type == MS_BUFFER_BYTE_RGBA); alphapixptr = rb.data.rgba.a+rb.data.rgba.row_step*y + rb.data.rgba.pixel_step*x; if(!*alphapixptr) { /* label point does not intersect mask */ return MS_SUCCESS; } #endif } } else if (labelpath) { int i = 0; for (i = 0; i < labelpath->path.numpoints; i++) { int x = MS_NINT(labelpath->path.point[i].x); int y = MS_NINT(labelpath->path.point[i].y); /* Using label repeatdistance, we might have a point with x/y below 0. See #4764 */ if (x >= 0 && x < rb.width && y >= 0 && y < rb.height) { #ifdef USE_GD if (rb.type == MS_BUFFER_BYTE_RGBA) { alphapixptr = rb.data.rgba.a + rb.data.rgba.row_step * y + rb.data.rgba.pixel_step*x; if (!*alphapixptr) { /* label point does not intersect mask */ msFreeLabelPathObj(labelpath); return MS_SUCCESS; } } else { if (!gdImageGetPixel(rb.data.gd_img, x, y)) { msFreeLabelPathObj(labelpath); return MS_SUCCESS; } } #else assert(rb.type == MS_BUFFER_BYTE_RGBA); alphapixptr = rb.data.rgba.a + rb.data.rgba.row_step * y + rb.data.rgba.pixel_step*x; if (!*alphapixptr) { /* label point does not intersect mask */ msFreeLabelPathObj(labelpath); return MS_SUCCESS; } #endif } } } } else { msSetError(MS_MISCERR, "Layer (%s) references references a mask layer, but the selected renderer does not support them", "msAddLabel()", layerPtr->name); return (MS_FAILURE); } } /* Validate label priority value and get ref on label cache for it */ if (label->priority < 1) label->priority = 1; else if (label->priority > MS_MAX_LABEL_PRIORITY) label->priority = MS_MAX_LABEL_PRIORITY; cacheslot = &(map->labelcache.slots[label->priority-1]); if(cacheslot->numlabels == cacheslot->cachesize) { /* just add it to the end */ cacheslot->labels = (labelCacheMemberObj *) realloc(cacheslot->labels, sizeof(labelCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT)); MS_CHECK_ALLOC(cacheslot->labels, sizeof(labelCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT), MS_FAILURE); cacheslot->cachesize += MS_LABELCACHEINCREMENT; } cachePtr = &(cacheslot->labels[cacheslot->numlabels]); cachePtr->layerindex = layerindex; /* so we can get back to this *raw* data if necessary */ cachePtr->classindex = classindex; if(shape) { cachePtr->shapetype = shape->type; } else { cachePtr->shapetype = MS_SHAPE_POINT; } cachePtr->leaderline = NULL; cachePtr->leaderbbox = NULL; /* Store the label point or the label path (Bug #1620) */ if ( point ) { cachePtr->point = *point; /* the actual label point */ cachePtr->labelpath = NULL; } else { assert(labelpath); cachePtr->labelpath = labelpath; /* Use the middle point of the labelpath for mindistance calculations */ cachePtr->point = labelpath->path.point[labelpath->path.numpoints / 2]; } /* TODO: perhaps we can get rid of this next section and just store a marker size? Why do we cache the styles for a point layer? */ /* copy the styles (only if there is an accompanying marker) * We cannot simply keeep refs because the rendering code alters some members of the style objects */ cachePtr->styles = NULL; cachePtr->numstyles = 0; if(layerPtr->type == MS_LAYER_ANNOTATION && classPtr->numstyles > 0) { cachePtr->numstyles = classPtr->numstyles; cachePtr->styles = (styleObj *) msSmallMalloc(sizeof(styleObj)*classPtr->numstyles); if (classPtr->numstyles > 0) { for(i=0; i<classPtr->numstyles; i++) { initStyle(&(cachePtr->styles[i])); msCopyStyle(&(cachePtr->styles[i]), classPtr->styles[i]); } } } /* copy the label */ cachePtr->numlabels = 1; cachePtr->labels = (labelObj *) msSmallMalloc(sizeof(labelObj)); initLabel(cachePtr->labels); msCopyLabel(cachePtr->labels, label); cachePtr->markerid = -1; cachePtr->featuresize = featuresize; //cachePtr->poly = (shapeObj *) msSmallMalloc(sizeof(shapeObj)); //msInitShape(cachePtr->poly); cachePtr->poly = NULL; cachePtr->status = MS_FALSE; if(layerPtr->type == MS_LAYER_POINT && classPtr->numstyles > 0) { /* cache the marker placement, it's already on the map */ rectObj rect; double w, h; if(cacheslot->nummarkers == cacheslot->markercachesize) { /* just add it to the end */ cacheslot->markers = (markerCacheMemberObj *) realloc(cacheslot->markers, sizeof(markerCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT)); MS_CHECK_ALLOC(cacheslot->markers, sizeof(markerCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT), MS_FAILURE); cacheslot->markercachesize+=MS_LABELCACHEINCREMENT; } i = cacheslot->nummarkers; cacheslot->markers[i].poly = (shapeObj *) msSmallMalloc(sizeof(shapeObj)); msInitShape(cacheslot->markers[i].poly); /* TO DO: at the moment only checks the bottom style, perhaps should check all of them */ /* #2347: after RFC-24 classPtr->styles could be NULL so we check it */ if(classPtr->styles != NULL) { if(msGetMarkerSize(&map->symbolset, classPtr->styles[0], &w, &h, layerPtr->scalefactor) != MS_SUCCESS) return(MS_FAILURE); rect.minx = point->x - .5 * w; rect.miny = point->y - .5 * h; rect.maxx = rect.minx + (w-1); rect.maxy = rect.miny + (h-1); msRectToPolygon(rect, cacheslot->markers[i].poly); cacheslot->markers[i].id = cacheslot->numlabels; cachePtr->markerid = i; cacheslot->nummarkers++; } } cacheslot->numlabels++; /* Maintain main labelCacheObj.numlabels only for backwards compatibility */ map->labelcache.numlabels++; return(MS_SUCCESS); }
int msAddLabelGroup(mapObj *map, int layerindex, int classindex, shapeObj *shape, pointObj *point, double featuresize) { int i, priority, numactivelabels=0; labelCacheSlotObj *cacheslot; labelCacheMemberObj *cachePtr=NULL; layerObj *layerPtr=NULL; classObj *classPtr=NULL; layerPtr = (GET_LAYER(map, layerindex)); /* set up a few pointers for clarity */ classPtr = GET_LAYER(map, layerindex)->class[classindex]; if(classPtr->numlabels == 0) return MS_SUCCESS; /* not an error just nothing to do */ for(i=0; i<classPtr->numlabels; i++) { if(classPtr->labels[i]->status == MS_ON) { numactivelabels++; } } if(numactivelabels == 0) return MS_SUCCESS; /* if the number of labels is 1 then call msAddLabel() accordingly */ if(numactivelabels == 1) { for(i=0; i<classPtr->numlabels; i++) { if(classPtr->labels[i]->status == MS_ON) return msAddLabel(map, classPtr->labels[i], layerindex, classindex, shape, point, NULL, featuresize); } } if (layerPtr->type == MS_LAYER_ANNOTATION && (classPtr->numlabels > 1 || classPtr->leader.maxdistance)) { msSetError(MS_MISCERR, "Multiple Labels and/or LEADERs are not supported with annotation layers", "msAddLabelGroup()"); return MS_FAILURE; } /* check that the label intersects the layer mask */ if(layerPtr->mask) { int maskLayerIdx = msGetLayerIndex(map,layerPtr->mask); layerObj *maskLayer = GET_LAYER(map,maskLayerIdx); unsigned char *alphapixptr; if(maskLayer->maskimage && MS_IMAGE_RENDERER(maskLayer->maskimage)->supports_pixel_buffer) { rasterBufferObj rb; int x,y; memset(&rb,0,sizeof(rasterBufferObj)); MS_IMAGE_RENDERER(maskLayer->maskimage)->getRasterBufferHandle(maskLayer->maskimage,&rb); x = MS_NINT(point->x); y = MS_NINT(point->y); /* Using label repeatdistance, we might have a point with x/y below 0. See #4764 */ if (x >= 0 && x < rb.width && y >= 0 && y < rb.height) { #ifdef USE_GD if(rb.type == MS_BUFFER_BYTE_RGBA) { alphapixptr = rb.data.rgba.a+rb.data.rgba.row_step*y + rb.data.rgba.pixel_step*x; if(!*alphapixptr) { /* label point does not intersect mask */ return MS_SUCCESS; } } else { if(!gdImageGetPixel(rb.data.gd_img,x,y)) return MS_SUCCESS; } #else assert(rb.type == MS_BUFFER_BYTE_RGBA); alphapixptr = rb.data.rgba.a+rb.data.rgba.row_step*y + rb.data.rgba.pixel_step*x; if(!*alphapixptr) { /* label point does not intersect mask */ return MS_SUCCESS; } #endif } } else { msSetError(MS_MISCERR, "Layer (%s) references references a mask layer, but the selected renderer does not support them", "msAddLabelGroup()", layerPtr->name); return (MS_FAILURE); } } /* Validate label priority value and get ref on label cache for it */ priority = classPtr->labels[0]->priority; /* take priority from the first label */ if (priority < 1) priority = 1; else if (priority > MS_MAX_LABEL_PRIORITY) priority = MS_MAX_LABEL_PRIORITY; cacheslot = &(map->labelcache.slots[priority-1]); if(cacheslot->numlabels == cacheslot->cachesize) { /* just add it to the end */ cacheslot->labels = (labelCacheMemberObj *) realloc(cacheslot->labels, sizeof(labelCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT)); MS_CHECK_ALLOC(cacheslot->labels, sizeof(labelCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT), MS_FAILURE); cacheslot->cachesize += MS_LABELCACHEINCREMENT; } cachePtr = &(cacheslot->labels[cacheslot->numlabels]); cachePtr->layerindex = layerindex; /* so we can get back to this *raw* data if necessary */ cachePtr->classindex = classindex; if(shape) { cachePtr->shapetype = shape->type; } else { cachePtr->shapetype = MS_SHAPE_POINT; } cachePtr->point = *point; /* the actual label point */ cachePtr->labelpath = NULL; cachePtr->leaderline = NULL; cachePtr->leaderbbox = NULL; // cachePtr->text = msStrdup(string); /* the actual text */ /* TODO: perhaps we can get rid of this next section and just store a marker size? Why do we cache the styles for a point layer? */ /* copy the styles (only if there is an accompanying marker) * We cannot simply keep refs because the rendering code might alters some members of the style objects */ cachePtr->styles = NULL; cachePtr->numstyles = 0; if(layerPtr->type == MS_LAYER_ANNOTATION && classPtr->numstyles > 0) { cachePtr->numstyles = classPtr->numstyles; cachePtr->styles = (styleObj *) msSmallMalloc(sizeof(styleObj)*classPtr->numstyles); if (classPtr->numstyles > 0) { for(i=0; i<classPtr->numstyles; i++) { initStyle(&(cachePtr->styles[i])); msCopyStyle(&(cachePtr->styles[i]), classPtr->styles[i]); } } } /* ** copy the labels (we are guaranteed to have more than one): ** we cannot simply keep refs because the rendering code alters some members of the style objects */ cachePtr->numlabels = 0; cachePtr->labels = (labelObj *) msSmallMalloc(sizeof(labelObj)*numactivelabels); for(i=0; i<classPtr->numlabels; i++) { if(classPtr->labels[i]->status == MS_OFF) continue; initLabel(&(cachePtr->labels[cachePtr->numlabels])); msCopyLabel(&(cachePtr->labels[cachePtr->numlabels]), classPtr->labels[i]); cachePtr->numlabels++; } assert(cachePtr->numlabels == numactivelabels); cachePtr->markerid = -1; cachePtr->featuresize = featuresize; //cachePtr->poly = (shapeObj *) msSmallMalloc(sizeof(shapeObj)); //msInitShape(cachePtr->poly); cachePtr->poly = NULL; cachePtr->status = MS_FALSE; if(layerPtr->type == MS_LAYER_POINT && classPtr->numstyles > 0) { /* cache the marker placement, it's already on the map */ /* TO DO: at the moment only checks the bottom style, perhaps should check all of them */ /* #2347: after RFC-24 classPtr->styles could be NULL so we check it */ rectObj rect; double w, h; if(msGetMarkerSize(&map->symbolset, classPtr->styles[0], &w, &h, layerPtr->scalefactor) != MS_SUCCESS) return(MS_FAILURE); if(cacheslot->nummarkers == cacheslot->markercachesize) { /* just add it to the end */ cacheslot->markers = (markerCacheMemberObj *) realloc(cacheslot->markers, sizeof(markerCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT)); MS_CHECK_ALLOC(cacheslot->markers, sizeof(markerCacheMemberObj)*(cacheslot->cachesize+MS_LABELCACHEINCREMENT), MS_FAILURE); cacheslot->markercachesize+=MS_LABELCACHEINCREMENT; } i = cacheslot->nummarkers; cacheslot->markers[i].poly = (shapeObj *) msSmallMalloc(sizeof(shapeObj)); msInitShape(cacheslot->markers[i].poly); rect.minx = (point->x - .5 * w); rect.miny = (point->y - .5 * h); rect.maxx = rect.minx + (w-1); rect.maxy = rect.miny + (h-1); msRectToPolygon(rect, cacheslot->markers[i].poly); cacheslot->markers[i].id = cacheslot->numlabels; cachePtr->markerid = i; cacheslot->nummarkers++; } cacheslot->numlabels++; /* Maintain main labelCacheObj.numlabels only for backwards compatibility */ map->labelcache.numlabels++; return(MS_SUCCESS); }
/********************************************************************** * msBuildWFSLayerGetURL() * * Build a WFS GetFeature URL for a Get Request. * * Returns a reference to a newly allocated string that should be freed * by the caller. **********************************************************************/ static char *msBuildWFSLayerGetURL(mapObj *map, layerObj *lp, rectObj *bbox, wfsParamsObj *psParams) { char *pszURL = NULL, *pszOnlineResource=NULL; const char *pszTmp; char *pszVersion, *pszService, *pszTypename = NULL; int bVersionInConnection = 0, bServiceInConnection = 0; int bTypenameInConnection = 0; size_t bufferSize = 0; if (lp->connectiontype != MS_WFS || lp->connection == NULL) { msSetError(MS_WFSCONNERR, "Call supported only for CONNECTIONTYPE WFS", "msBuildWFSLayerGetURL()"); return NULL; } /* -------------------------------------------------------------------- */ /* Find out request version. Look first for the wfs_version */ /* metedata. If not available try to find out if the CONNECTION */ /* string contains the version. This last test is done for */ /* backward compatiblity but is depericated. */ /* -------------------------------------------------------------------- */ pszVersion = psParams->pszVersion; if (!pszVersion) { if ((pszTmp = strstr(lp->connection, "VERSION=")) == NULL && (pszTmp = strstr(lp->connection, "version=")) == NULL ) { msSetError(MS_WFSCONNERR, "Metadata wfs_version must be set in the layer", "msBuildWFSLayerGetURL()"); return NULL; } pszVersion = strchr(pszTmp, '=')+1; bVersionInConnection = 1; } if (strncmp(pszVersion, "0.0.14", 6) != 0 && strncmp(pszVersion, "1.0.0", 5) != 0 && strncmp(pszVersion, "1.1", 3) != 0) { msSetError(MS_WFSCONNERR, "MapServer supports only WFS 1.0.0 or 0.0.14 (please verify the version metadata wfs_version).", "msBuildWFSLayerGetURL()"); return NULL; } /* -------------------------------------------------------------------- */ /* Find out the service. It is always set to WFS in function */ /* msBuildRequestParms (check Bug 1302 for details). */ /* -------------------------------------------------------------------- */ pszService = psParams->pszService; /* -------------------------------------------------------------------- */ /* Find out the typename. Look first for the wfs_tyename */ /* metadata. If not available try to find out if the CONNECTION */ /* string contains it. This last test is done for */ /* backward compatiblity but is depericated. */ /* -------------------------------------------------------------------- */ pszTypename = psParams->pszTypeName; if (!pszTypename) { if ((pszTmp = strstr(lp->connection, "TYPENAME=")) == NULL && (pszTmp = strstr(lp->connection, "typename=")) == NULL ) { msSetError(MS_WFSCONNERR, "Metadata wfs_typename must be set in the layer", "msBuildWFSLayerGetURL()"); return NULL; } bTypenameInConnection = 1; } /* -------------------------------------------------------------------- * Build the request URL. * At this point we set only the following parameters for GetFeature: * REQUEST * BBOX * VERSION * SERVICE * TYPENAME * FILTER * MAXFEATURES * * For backward compatiblity the user could also have in the connection * string the following parameters (but it is depricated): * VERSION * SERVICE * TYPENAME * -------------------------------------------------------------------- */ /* Make sure we have a big enough buffer for the URL */ bufferSize = strlen(lp->connection)+1024; pszURL = (char *)malloc(bufferSize); MS_CHECK_ALLOC(pszURL, bufferSize, NULL); /* __TODO__ We have to urlencode each value... especially the BBOX values */ /* because if they end up in exponent format (123e+06) the + will be seen */ /* as a space by the remote server. */ /* -------------------------------------------------------------------- */ /* build the URL, */ /* -------------------------------------------------------------------- */ /* make sure connection ends with "&" or "?" */ pszOnlineResource = msOWSTerminateOnlineResource(lp->connection); snprintf(pszURL, bufferSize, "%s", pszOnlineResource); msFree(pszOnlineResource); /* REQUEST */ snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&REQUEST=GetFeature"); /* VERSION */ if (!bVersionInConnection) snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&VERSION=%s", pszVersion); /* SERVICE */ if (!bServiceInConnection) snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&SERVICE=%s", pszService); /* TYPENAME */ if (!bTypenameInConnection) snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&TYPENAME=%s", pszTypename); /* -------------------------------------------------------------------- */ /* If the filter parameter is given in the wfs_filter metadata, */ /* we use it and do not send the BBOX paramter as they are */ /* mutually exclusive. */ /* -------------------------------------------------------------------- */ if (psParams->pszFilter) { char *encoded_filter = msEncodeUrl(psParams->pszFilter); snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&FILTER=%s",encoded_filter); free(encoded_filter); } else { /* * take care about the axis order for WFS 1.1 */ char *projUrn; char *projEpsg; projUrn = msOWSGetProjURN(&(lp->projection), &(lp->metadata), "FO", 1); msOWSGetEPSGProj(&(lp->projection), &(lp->metadata), "FO", 1, &projEpsg); /* * WFS 1.1 supports including the SRS in the BBOX parameter, should * respect axis order in the BBOX and has a separate SRSNAME parameter for * the desired result SRS. * WFS 1.0 is always easting, northing, doesn't include the SRS as part of * the BBOX parameter and has no SRSNAME parameter: if we don't have a * URN then fallback to WFS 1.0 style */ if ((strncmp(pszVersion, "1.1", 3) == 0) && projUrn) { if (projEpsg && (strncmp(projEpsg, "EPSG:", 5) == 0) && msIsAxisInverted(atoi(projEpsg + 5))) { snprintf(pszURL + strlen(pszURL), bufferSize - strlen(pszURL), "&BBOX=%.15g,%.15g,%.15g,%.15g,%s&SRSNAME=%s", bbox->miny, bbox->minx, bbox->maxy, bbox->maxx, projUrn, projUrn); } else { snprintf(pszURL + strlen(pszURL), bufferSize - strlen(pszURL), "&BBOX=%.15g,%.15g,%.15g,%.15g,%s&SRSNAME=%s", bbox->minx, bbox->miny, bbox->maxy, bbox->maxy, projUrn, projUrn); } } else { snprintf(pszURL + strlen(pszURL), bufferSize - strlen(pszURL), "&BBOX=%.15g,%.15g,%.15g,%.15g", bbox->minx, bbox->miny, bbox->maxx, bbox->maxy); } msFree(projUrn); msFree(projEpsg); } if (psParams->nMaxFeatures > 0) snprintf(pszURL + strlen(pszURL), bufferSize-strlen(pszURL), "&MAXFEATURES=%d", psParams->nMaxFeatures); return pszURL; }
shapeObj *msRasterizeArc(double x0, double y0, double radius, double startAngle, double endAngle, int isSlice) { static int allocated_size=100; shapeObj *shape = (shapeObj*)calloc(1,sizeof(shapeObj)); MS_CHECK_ALLOC(shape, sizeof(shapeObj), NULL); mapserver::arc arc ( x0, y0,radius,radius, startAngle*MS_DEG_TO_RAD, endAngle*MS_DEG_TO_RAD,true ); arc.approximation_scale ( 1 ); arc.rewind(1); msInitShape(shape); lineObj *line = (lineObj*)calloc(1,sizeof(lineObj)); if (!line) { msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msRasterizeArc()" , __FILE__, __LINE__, sizeof(lineObj)); free(shape); return NULL; } shape->line = line; shape->numlines = 1; line->point = (pointObj*)calloc(allocated_size,sizeof(pointObj)); if (!line->point) { msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msRasterizeArc()" , __FILE__, __LINE__, allocated_size*sizeof(pointObj)); free(line); free(shape); return NULL; } line->numpoints = 0; double x,y; //first segment from center to first point of arc if(isSlice) { line->point[0].x = x0; line->point[0].y = y0; line->numpoints = 1; } while(arc.vertex(&x,&y) != mapserver::path_cmd_stop) { if(line->numpoints == allocated_size) { allocated_size *= 2; line->point = (pointObj*)realloc(line->point, allocated_size * sizeof(pointObj)); if (!line->point) { msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msRasterizeArc()" , __FILE__, __LINE__, allocated_size * sizeof(pointObj)); free(line); free(shape); return NULL; } } line->point[line->numpoints].x = x; line->point[line->numpoints].y = y; line->numpoints++; } //make sure the shape is closed if we're doing a full circle if(!isSlice && !(endAngle-startAngle)%360) { if(line->point[line->numpoints-1].x != line->point[0].x || line->point[line->numpoints-1].y != line->point[0].y) { if(line->numpoints == allocated_size) { allocated_size *= 2; line->point = (pointObj*)realloc(line->point, allocated_size * sizeof(pointObj)); if (!line->point) { msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msRasterizeArc()" , __FILE__, __LINE__, allocated_size * sizeof(pointObj)); free(line); free(shape); return NULL; } } line->point[line->numpoints].x = line->point[0].x; line->point[line->numpoints].y = line->point[0].y; line->numpoints++; } } if(isSlice) { if(line->numpoints == allocated_size) { allocated_size *= 2; line->point = (pointObj*)realloc(line->point, allocated_size * sizeof(pointObj)); if (!line->point) { msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msRasterizeArc()" , __FILE__, __LINE__, allocated_size * sizeof(pointObj)); free(line); free(shape); return NULL; } } line->point[line->numpoints].x = x0; line->point[line->numpoints].y = y0; line->numpoints++; } return shape; }
int msEmbedScalebar(mapObj *map, imageObj *img) { int l,index,s; pointObj point; imageObj *image = NULL; rendererVTableObj *renderer = MS_MAP_RENDERER(map); symbolObj *embededSymbol; if( ! renderer ) { msSetError(MS_MISCERR,"unsupported outputformat","msEmbedScalebar()"); return MS_FAILURE; } index = msGetSymbolIndex(&(map->symbolset), "scalebar", MS_FALSE); if(index != -1) msRemoveSymbol(&(map->symbolset), index); /* remove cached symbol in case the function is called multiple times with different zoom levels */ if((embededSymbol=msGrowSymbolSet(&map->symbolset)) == NULL) return MS_FAILURE; s = map->symbolset.numsymbols; map->symbolset.numsymbols++; image = msDrawScalebar(map); if(!image) { return MS_FAILURE; } embededSymbol->pixmap_buffer = calloc(1,sizeof(rasterBufferObj)); MS_CHECK_ALLOC(embededSymbol->pixmap_buffer, sizeof(rasterBufferObj), MS_FAILURE); if(MS_SUCCESS != renderer->getRasterBufferCopy(image,embededSymbol->pixmap_buffer)) { return MS_FAILURE; } embededSymbol->type = MS_SYMBOL_PIXMAP; /* intialize a few things */ embededSymbol->name = msStrdup("scalebar"); embededSymbol->sizex = embededSymbol->pixmap_buffer->width; embededSymbol->sizey = embededSymbol->pixmap_buffer->height; if(map->scalebar.transparent) { embededSymbol->transparent = MS_TRUE; embededSymbol->transparentcolor = 0; } switch(map->scalebar.position) { case(MS_LL): point.x = MS_NINT(embededSymbol->pixmap_buffer->width/2.0); point.y = map->height - MS_NINT(embededSymbol->pixmap_buffer->height/2.0); break; case(MS_LR): point.x = map->width - MS_NINT(embededSymbol->pixmap_buffer->width/2.0); point.y = map->height - MS_NINT(embededSymbol->pixmap_buffer->height/2.0); break; case(MS_LC): point.x = MS_NINT(map->width/2.0); point.y = map->height - MS_NINT(embededSymbol->pixmap_buffer->height/2.0); break; case(MS_UR): point.x = map->width - MS_NINT(embededSymbol->pixmap_buffer->width/2.0); point.y = MS_NINT(embededSymbol->pixmap_buffer->height/2.0); break; case(MS_UL): point.x = MS_NINT(embededSymbol->pixmap_buffer->width/2.0); point.y = MS_NINT(embededSymbol->pixmap_buffer->height/2.0); break; case(MS_UC): point.x = MS_NINT(map->width/2.0); point.y = MS_NINT(embededSymbol->pixmap_buffer->height/2.0); break; } l = msGetLayerIndex(map, "__embed__scalebar"); if(l == -1) { if (msGrowMapLayers(map) == NULL) return(-1); l = map->numlayers; map->numlayers++; if(initLayer((GET_LAYER(map, l)), map) == -1) return(-1); GET_LAYER(map, l)->name = msStrdup("__embed__scalebar"); GET_LAYER(map, l)->type = MS_LAYER_POINT; if (msGrowLayerClasses( GET_LAYER(map, l) ) == NULL) return(-1); if(initClass(GET_LAYER(map, l)->class[0]) == -1) return(-1); GET_LAYER(map, l)->numclasses = 1; /* so we make sure to free it */ /* update the layer order list with the layer's index. */ map->layerorder[l] = l; } GET_LAYER(map, l)->status = MS_ON; if(map->scalebar.postlabelcache) { /* add it directly to the image */ if(msMaybeAllocateClassStyle(GET_LAYER(map, l)->class[0], 0)==MS_FAILURE) return MS_FAILURE; GET_LAYER(map, l)->class[0]->styles[0]->symbol = s; msDrawMarkerSymbol(&map->symbolset, img, &point, GET_LAYER(map, l)->class[0]->styles[0], 1.0); } else { if(!GET_LAYER(map, l)->class[0]->labels) {
int msUVRASTERLayerGetExtent(layerObj *layer, rectObj *extent) { char szPath[MS_MAXPATHLEN]; mapObj *map = layer->map; double adfGeoTransform[6]; int nXSize, nYSize; GDALDatasetH hDS; shapefileObj *tileshpfile; int tilelayerindex = -1; CPLErr eErr = CE_Failure; char *decrypted_path; if( (!layer->data || strlen(layer->data) == 0) && layer->tileindex == NULL) { /* should we be issuing a specific error about not supporting extents for tileindexed raster layers? */ return MS_FAILURE; } if( map == NULL ) return MS_FAILURE; /* If the layer use a tileindex, return the extent of the tileindex shapefile/referenced layer */ if (layer->tileindex) { tilelayerindex = msGetLayerIndex(map, layer->tileindex); if(tilelayerindex != -1) /* does the tileindex reference another layer */ return msLayerGetExtent(GET_LAYER(map, tilelayerindex), extent); else { tileshpfile = (shapefileObj *) malloc(sizeof(shapefileObj)); MS_CHECK_ALLOC(tileshpfile, sizeof(shapefileObj), MS_FAILURE); if(msShapefileOpen(tileshpfile, "rb", msBuildPath3(szPath, map->mappath, map->shapepath, layer->tileindex), MS_TRUE) == -1) if(msShapefileOpen(tileshpfile, "rb", msBuildPath(szPath, map->mappath, layer->tileindex), MS_TRUE) == -1) return MS_FAILURE; *extent = tileshpfile->bounds; msShapefileClose(tileshpfile); free(tileshpfile); return MS_SUCCESS; } } msTryBuildPath3(szPath, map->mappath, map->shapepath, layer->data); decrypted_path = msDecryptStringTokens( map, szPath ); msAcquireLock( TLOCK_GDAL ); if( decrypted_path ) { hDS = GDALOpen(decrypted_path, GA_ReadOnly ); msFree( decrypted_path ); } else hDS = NULL; if( hDS != NULL ) { nXSize = GDALGetRasterXSize( hDS ); nYSize = GDALGetRasterYSize( hDS ); eErr = GDALGetGeoTransform( hDS, adfGeoTransform ); GDALClose( hDS ); } msReleaseLock( TLOCK_GDAL ); if( hDS == NULL || eErr != CE_None ) { return MS_FAILURE; } /* If this appears to be an ungeoreferenced raster than flip it for mapservers purposes. */ if( adfGeoTransform[5] == 1.0 && adfGeoTransform[3] == 0.0 ) { adfGeoTransform[5] = -1.0; adfGeoTransform[3] = nYSize; } extent->minx = adfGeoTransform[0]; extent->maxy = adfGeoTransform[3]; extent->maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1]; extent->miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5]; return MS_SUCCESS; }
int msWriteTree(treeObj *tree, char *filename, int B_order) { char signature[3] = "SQT"; char version = 1; char reserved[3] = {0,0,0}; SHPTreeHandle disktree; int i; char mtBigEndian; char pabyBuf[32]; char *pszBasename, *pszFullname; disktree = (SHPTreeHandle) malloc(sizeof(SHPTreeInfo)); MS_CHECK_ALLOC(disktree, sizeof(SHPTreeInfo), MS_FALSE); /* -------------------------------------------------------------------- */ /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ pszBasename = (char *) msSmallMalloc(strlen(filename)+5); strcpy( pszBasename, filename ); for( i = strlen(pszBasename)-1; i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' && pszBasename[i] != '\\'; i-- ) {} if( pszBasename[i] == '.' ) pszBasename[i] = '\0'; /* -------------------------------------------------------------------- */ /* Open the .shp and .shx files. Note that files pulled from */ /* a PC to Unix with upper case filenames won't work! */ /* -------------------------------------------------------------------- */ pszFullname = (char *) msSmallMalloc(strlen(pszBasename) + 5); sprintf( pszFullname, "%s%s", pszBasename, MS_INDEX_EXTENSION); disktree->fp = fopen(pszFullname, "wb"); msFree(pszBasename); /* not needed */ msFree(pszFullname); if(!disktree->fp) { msFree(disktree); msSetError(MS_IOERR, NULL, "msWriteTree()"); return(MS_FALSE); } /* for efficiency, trim the tree */ msTreeTrim(tree); /* -------------------------------------------------------------------- */ /* Establish the byte order on this machine. */ /* -------------------------------------------------------------------- */ i = 1; if( *((uchar *) &i) == 1 ) mtBigEndian = MS_FALSE; else mtBigEndian = MS_TRUE; if( !(mtBigEndian ^ ( B_order == MS_LSB_ORDER || B_order == MS_NEW_LSB_ORDER )) ) disktree->needswap = 1; else disktree->needswap = 0; if( B_order == MS_NATIVE_ORDER ) disktree->needswap = 0; /* write the header */ if ( B_order > 0 ) { memcpy( pabyBuf, &signature, 3 ); memcpy (&disktree->signature, &signature, 3); pabyBuf[3] = B_order; memcpy( pabyBuf+4, &version, 1); memcpy( pabyBuf+5, &reserved, 3); memcpy( &disktree->version, &version, 1); memcpy( &disktree->flags, &reserved, 3); fwrite( pabyBuf, 8, 1, disktree->fp ); } memcpy( pabyBuf, &tree->numshapes, 4 ); if( disktree->needswap ) SwapWord( 4, pabyBuf ); memcpy( pabyBuf+4, &tree->maxdepth, 4 ); if( disktree->needswap ) SwapWord( 4, pabyBuf+4 ); i = fwrite( pabyBuf, 8, 1, disktree->fp ); if( !i ) { fprintf (stderr, "unable to write to index file ... exiting \n"); msSHPDiskTreeClose( disktree ); return (MS_FALSE); } writeTreeNode(disktree, tree->root); msSHPDiskTreeClose( disktree ); return(MS_TRUE); }
int msDrawVBarChartLayer(mapObj *map, layerObj *layer, imageObj *image) { shapeObj shape; int status=MS_SUCCESS; const char *chartSizeProcessingKey=msLayerGetProcessingKey( layer,"CHART_SIZE" ); const char *chartScaleProcessingKey=msLayerGetProcessingKey( layer,"CHART_SCALE" ); float barWidth,scale=1.0; float *values; styleObj **styles; pointObj center; int numvalues = layer->numclasses; if(chartSizeProcessingKey==NULL) { barWidth=20; } else { if(sscanf(chartSizeProcessingKey ,"%f",&barWidth) != 1) { msSetError(MS_MISCERR, "msDrawChart format error for processing key \"CHART_SIZE\"", "msDrawVBarChartLayer()"); return MS_FAILURE; } } if(chartScaleProcessingKey) { if(sscanf(chartScaleProcessingKey,"%f",&scale)!=1) { msSetError(MS_MISCERR, "Error reading value for processing key \"CHART_SCALE\"", "msDrawVBarChartLayer()"); return MS_FAILURE; } } msInitShape(&shape); values=(float*)calloc(numvalues,sizeof(float)); MS_CHECK_ALLOC(values, numvalues*sizeof(float), MS_FAILURE); styles = (styleObj**)malloc(numvalues*sizeof(styleObj*)); if (styles == NULL) { msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msDrawVBarChartLayer()", __FILE__, __LINE__, numvalues*sizeof(styleObj*)); free(values); return MS_FAILURE; } while(MS_SUCCESS == getNextShape(map,layer,values,styles,&shape)) { int i; double h=0; for(i=0; i<numvalues; i++) { values[i]*=scale; h += values[i]; } msDrawStartShape(map, layer, image, &shape); if(findChartPoint(map, &shape, barWidth,h, ¢er)==MS_SUCCESS) { status = msDrawVBarChart(map,image, ¢er, values, styles, numvalues, barWidth); } msDrawEndShape(map,layer,image,&shape); msFreeShape(&shape); } free(values); free(styles); return status; }
int msRenderSVGToPixmap(symbolObj *symbol, symbolStyleObj *style) { #ifdef USE_SVG_CAIRO unsigned int svg_width, svg_height; svg_cairo_status_t status; cairo_t *cr; svg_cairo_t *svgc; cairo_surface_t *surface; unsigned char *pb; rasterBufferObj *rb; //rendering_buffer *rc; int width, height, surface_w, surface_h,row; double scale; //already rendered at the right size and scale? return if (symbol->pixmap_buffer) { if (style->scale == symbol->pixmap_buffer->scale && style->rotation == symbol->pixmap_buffer->rotation) { return MS_SUCCESS; } else { if(symbol->renderer!=NULL) symbol->renderer->freeSymbol(symbol); msFreeRasterBuffer(symbol->pixmap_buffer); } } if (!symbol->svg_cairo_surface ) msPreloadSVGSymbol(symbol); if (!symbol->svg_cairo_surface) return MS_FAILURE; //set up raster svgc =symbol->svg_cairo_surface; svg_cairo_get_size (svgc, &svg_width, &svg_height); width = surface_w = svg_width; height = surface_h = svg_height; //scale such that the SVG is rendered at the desired size in pixels scale = style->scale; /*MS_MIN(style->scale / (double) svg_width, style->scale / (double) svg_height);*/ //increase pixmap size to accomodate scaling/rotation if (scale != 1.0 && style->scale != 1.0) { width = surface_w = (svg_width * scale + 0.5); height = surface_h = (svg_height * scale + 0.5); } if (style->rotation != 0) { surface_w = MS_NINT(width * 1.415); surface_h = MS_NINT(height * 1.415); } surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, surface_w, surface_h); cr = cairo_create(surface); if (style->rotation != 0) { cairo_translate (cr, surface_w/2, surface_h/2); cairo_rotate(cr, -style->rotation); cairo_translate (cr, -width/2, -height/2); } if (style->scale != 1.0) { cairo_scale(cr,scale,scale); } status = svg_cairo_render(svgc, cr); pb = cairo_image_surface_get_data(surface); //set up raster symbol->pixmap_buffer = (rasterBufferObj*)calloc(1,sizeof(rasterBufferObj)); MS_CHECK_ALLOC(symbol->pixmap_buffer, sizeof(rasterBufferObj), MS_FAILURE); initializeRasterBufferCairo(symbol->pixmap_buffer, surface_w, surface_h, 0); rb = symbol->pixmap_buffer; memcpy(rb->data.rgba.pixels, pb, surface_w * surface_h * 4 * sizeof(unsigned char)); /* unpremultiply the data */ for(row=0; row<rb->height; row++) { int col; unsigned char *a,*r,*g,*b; r=rb->data.rgba.r+row*rb->data.rgba.row_step; g=rb->data.rgba.g+row*rb->data.rgba.row_step; b=rb->data.rgba.b+row*rb->data.rgba.row_step; a=rb->data.rgba.a+row*rb->data.rgba.row_step; for(col=0; col<rb->width; col++) { if(*a && *a < 255) { double da = *a/255.0; *r/=da; *g/=da; *b/=da; } a+=rb->data.rgba.pixel_step; r+=rb->data.rgba.pixel_step; g+=rb->data.rgba.pixel_step; b+=rb->data.rgba.pixel_step; } } rb->scale = style->scale; rb->rotation = style->rotation; cairo_destroy(cr); cairo_surface_destroy(surface); return MS_SUCCESS; #else msSetError(MS_MISCERR, "SVG Symbols requested but MapServer is not built with libsvgcairo", "renderSVGSymbolCairo()"); return MS_FAILURE; #endif }
int msDrawPieChartLayer(mapObj *map, layerObj *layer, imageObj *image) { shapeObj shape; int status=MS_SUCCESS; const char *chartRangeProcessingKey=NULL; const char *chartSizeProcessingKey=msLayerGetProcessingKey( layer,"CHART_SIZE" ); float diameter, mindiameter=-1, maxdiameter, minvalue, maxvalue; float *values; styleObj **styles; pointObj center; int numvalues = layer->numclasses; /* the number of classes to represent in the graph */ if(chartSizeProcessingKey==NULL) { chartRangeProcessingKey=msLayerGetProcessingKey( layer,"CHART_SIZE_RANGE" ); if(chartRangeProcessingKey==NULL) diameter=20; else { sscanf(chartRangeProcessingKey,"%*s %f %f %f %f", &mindiameter,&maxdiameter,&minvalue,&maxvalue); } } else { if(sscanf(chartSizeProcessingKey ,"%f",&diameter)!=1) { msSetError(MS_MISCERR, "msDrawChart format error for processing key \"CHART_SIZE\"", "msDrawPieChartLayer()"); return MS_FAILURE; } } /* step through the target shapes */ msInitShape(&shape); values=(float*)calloc(numvalues,sizeof(float)); MS_CHECK_ALLOC(values, numvalues*sizeof(float), MS_FAILURE); styles = (styleObj**)malloc((numvalues)*sizeof(styleObj*)); if (styles == NULL) { msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "msDrawPieChartLayer()", __FILE__, __LINE__, numvalues*sizeof(styleObj*)); free(values); return MS_FAILURE; } if(chartRangeProcessingKey!=NULL) numvalues--; while(MS_SUCCESS == getNextShape(map,layer,values,styles,&shape)) { msDrawStartShape(map, layer, image, &shape); if(chartRangeProcessingKey!=NULL) { diameter = values[numvalues]; if(mindiameter>=0) { if(diameter<=minvalue) diameter=mindiameter; else if(diameter>=maxvalue) diameter=maxdiameter; else { diameter=MS_NINT( mindiameter+ ((diameter-minvalue)/(maxvalue-minvalue))* (maxdiameter-mindiameter) ); } } } if(findChartPoint(map, &shape, diameter, diameter, ¢er) == MS_SUCCESS) { status = msDrawPieChart(map,image, ¢er, diameter, values,styles,numvalues); } msDrawEndShape(map,layer,image,&shape); msFreeShape(&shape); } free(values); free(styles); return status; }
int renderLineGD(imageObj *img, shapeObj *p, strokeStyleObj *stroke) { gdImagePtr ip; int c; gdImagePtr brush=NULL; if(!img || !p || !stroke) return MS_FAILURE; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; SETPEN(ip, stroke->color); c = stroke->color->pen; if(stroke->patternlength > 0) { int *style; int i, j, k=0; int sc; for(i=0; i<stroke->patternlength; i++) k += MS_NINT(stroke->pattern[i]); style = (int *) malloc (k * sizeof(int)); MS_CHECK_ALLOC(style, k * sizeof(int), MS_FAILURE); sc = c; /* start with the color */ k=0; for(i=0; i<stroke->patternlength; i++) { for(j=0; j<MS_NINT(stroke->pattern[i]); j++, k++) { style[k] = sc; } sc = ((sc==c)?gdTransparent:c); } gdImageSetStyle(ip, style, k); free(style); c = gdStyled; } if(stroke->width > 1) { int brush_fc; brush = gdImageCreate(ceil(stroke->width), ceil(stroke->width)); gdImageColorAllocate(brush, gdImageRed(ip,0), gdImageGreen(ip, 0), gdImageBlue(ip, 0)); gdImageColorTransparent(brush,0); brush_fc = gdImageColorAllocate(brush, gdImageRed(ip,stroke->color->pen), gdImageGreen(ip,stroke->color->pen), gdImageBlue(ip,stroke->color->pen)); gdImageFilledEllipse(brush,MS_NINT(brush->sx/2),MS_NINT(brush->sy/2), MS_NINT(stroke->width),MS_NINT(stroke->width), brush_fc); gdImageSetBrush(ip, brush); if(stroke->patternlength > 0) { c = gdStyledBrushed; } else { c = gdBrushed; } } /* finally draw something */ imagePolyline(ip, p, c); /* clean up */ if(stroke->width>1) { gdImageDestroy(brush); } return MS_SUCCESS; }
/* * Utility function to create a IM image. Returns * a pointer to an imageObj structure. */ imageObj *msImageCreateIM(int width, int height, outputFormatObj *format, char *imagepath, char *imageurl, double resolution, double defresolution) { imageObj *image=NULL; if (setvbuf(stdout, NULL, _IONBF , 0)){ printf("Whoops..."); }; DEBUG_IF printf("msImageCreateIM<BR>\n"); if (width > 0 && height > 0) { image = (imageObj *)calloc(1,sizeof(imageObj)); MS_CHECK_ALLOC(image, sizeof(imageObj), NULL); if (image) { imgStr.string = &(image->img.imagemap); imgStr.alloc_size = &(image->size); image->format = format; format->refcount++; image->width = width; image->height = height; image->imagepath = NULL; image->imageurl = NULL; image->resolution = resolution; image->resolutionfactor = resolution/defresolution; if( strcasecmp("ON",msGetOutputFormatOption( format, "DXF", "OFF" )) == 0){ dxf = 1; im_iprintf(&layerStr, " 2\nLAYER\n 70\n 10\n"); } else dxf = 0; if( strcasecmp("ON",msGetOutputFormatOption( format, "SCRIPT", "OFF" )) == 0){ dxf = 2; im_iprintf(&layerStr, ""); } /* get href formation string options */ polyHrefFmt = makeFmtSafe(msGetOutputFormatOption ( format, "POLYHREF", "javascript:Clicked('%s');"), 1); polyMOverFmt = makeFmtSafe(msGetOutputFormatOption ( format, "POLYMOUSEOVER", ""), 1); polyMOutFmt = makeFmtSafe(msGetOutputFormatOption ( format, "POLYMOUSEOUT", ""), 1); symbolHrefFmt = makeFmtSafe(msGetOutputFormatOption ( format, "SYMBOLHREF", "javascript:SymbolClicked();"), 1); symbolMOverFmt = makeFmtSafe(msGetOutputFormatOption ( format, "SYMBOLMOUSEOVER", ""), 1); symbolMOutFmt = makeFmtSafe(msGetOutputFormatOption ( format, "SYMBOLMOUSEOUT", ""), 1); /* get name of client-side image map */ mapName = msGetOutputFormatOption ( format, "MAPNAME", "map1" ); /* should we suppress area declarations with no title? */ if( strcasecmp("YES",msGetOutputFormatOption( format, "SUPPRESS", "NO" )) == 0){ suppressEmpty=1; } lname = msStrdup("NONE"); *(imgStr.string) = msStrdup(""); if (*(imgStr.string)){ *(imgStr.alloc_size) = imgStr.string_len = strlen(*(imgStr.string)); } else { *(imgStr.alloc_size) = imgStr.string_len = 0; } if (imagepath) { image->imagepath = msStrdup(imagepath); } if (imageurl) { image->imageurl = msStrdup(imageurl); } return image; } else free( image ); } else { msSetError(MS_IMGERR, "Cannot create IM image of size %d x %d.", "msImageCreateIM()", width, height ); } return image; }